Skip to content

Commit

Permalink
fix(crud-typeorm): prevent sql injection in order by
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelyali committed Apr 18, 2020
1 parent 4bc9673 commit cffac90
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 3 deletions.
5 changes: 4 additions & 1 deletion integration/crud-typeorm/orm.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { join } from 'path';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { isNil } from '@nestjsx/util';

export const withCache: TypeOrmModuleOptions = {
type: 'postgres',
Expand All @@ -9,7 +10,9 @@ export const withCache: TypeOrmModuleOptions = {
password: 'root',
database: 'nestjsx_crud',
synchronize: false,
logging: true,
logging: !isNil(process.env.TYPEORM_LOGGING)
? !!parseInt(process.env.TYPEORM_LOGGING, 10)
: true,
cache: {
type: 'redis',
options: {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"test": "yarn s test",
"pretest:coveralls": "yarn pretest",
"test:coveralls": "yarn s test.coveralls",
"start:typeorm": "npx nodemon -w ./integration/crud-typeorm -e ts node_modules/.bin/ts-node integration/crud-typeorm/main.ts",
"start:typeorm": "npx nodemon -w ./integration/crud-typeorm -e ts node_modules/ts-node/dist/bin.js integration/crud-typeorm/main.ts",
"db:sync:typeorm": "cd ./integration/crud-typeorm && npx ts-node -r tsconfig-paths/register ../../node_modules/typeorm/cli.js schema:sync -f=orm",
"db:drop:typeorm": "cd ./integration/crud-typeorm && npx ts-node -r tsconfig-paths/register ../../node_modules/typeorm/cli.js schema:drop -f=orm",
"db:seeds:typeorm": "cd ./integration/crud-typeorm && npx ts-node -r tsconfig-paths/register ../../node_modules/typeorm/cli.js migration:run -f=orm",
Expand Down
24 changes: 23 additions & 1 deletion packages/crud-typeorm/src/typeorm-crud.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ export class TypeOrmCrudService<T> extends CrudService<T> {
protected entityPrimaryColumns: string[];
protected entityColumnsHash: ObjectLiteral = {};
protected entityRelationsHash: ObjectLiteral = {};
protected sqlInjectionRegEx: RegExp[] = [
/(%27)|(\')|(--)|(%23)|(#)/gi,
/((%3D)|(=))[^\n]*((%27)|(\')|(--)|(%3B)|(;))/gi,
/w*((%27)|(\'))((%6F)|o|(%4F))((%72)|r|(%52))/gi,
/((%27)|(\'))union/gi,
];

constructor(protected repo: Repository<T>) {
super();
Expand Down Expand Up @@ -791,7 +797,9 @@ export class TypeOrmCrudService<T> extends CrudService<T> {
const params: ObjectLiteral = {};

for (let i = 0; i < sort.length; i++) {
params[this.getFieldWithAlias(sort[i].field)] = sort[i].order;
const field = this.getFieldWithAlias(sort[i].field);
const checkedFiled = this.checkSqlInjection(field);
params[checkedFiled] = sort[i].order;
}

return params;
Expand Down Expand Up @@ -947,4 +955,18 @@ export class TypeOrmCrudService<T> extends CrudService<T> {
this.throwBadRequestException(`Invalid column '${cond.field}' value`);
}
}

private checkSqlInjection(field: string): string {
/* istanbul ignore else */
if (this.sqlInjectionRegEx.length) {
for (let i = 0; i < this.sqlInjectionRegEx.length; i++) {
/* istanbul ignore else */
if (this.sqlInjectionRegEx[0].test(field)) {
this.throwBadRequestException(`SQL injection detected: "${field}"`);
}
}
}

return field;
}
}
17 changes: 17 additions & 0 deletions packages/crud-typeorm/test/b.query-params.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,23 @@ describe('#crud-typeorm', () => {
res.body[0].company.projects[0].id,
);
});

it('should throw 400 if SQL injection has been detected', (done) => {
const query = qb
.sortBy({
field: ' ASC; SELECT CAST( version() AS INTEGER); --',
order: 'DESC',
})
.query();

return request(server)
.get('/companies')
.query(query)
.end((_, res) => {
expect(res.status).toBe(400);
done();
});
});
});

describe('#search', () => {
Expand Down

0 comments on commit cffac90

Please sign in to comment.