-
Notifications
You must be signed in to change notification settings - Fork 309
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
175 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 14 additions & 1 deletion
15
packages/dd-trace/src/appsec/iast/analyzers/injection-analyzer.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,32 @@ | ||
'use strict' | ||
const Analyzer = require('./vulnerability-analyzer') | ||
const { isTainted, getRanges } = require('../taint-tracking/operations') | ||
const { SQL_ROW_VALUE } = require('../taint-tracking/source-types') | ||
|
||
class InjectionAnalyzer extends Analyzer { | ||
_isVulnerable (value, iastContext) { | ||
if (value) { | ||
return isTainted(iastContext, value) | ||
if (!isTainted(iastContext, value)) { | ||
return false | ||
} | ||
|
||
return this._rangesAreExpected(getRanges(iastContext, value)) | ||
} | ||
|
||
return false | ||
} | ||
|
||
_getEvidence (value, iastContext) { | ||
const ranges = getRanges(iastContext, value) | ||
return { value, ranges } | ||
} | ||
|
||
_rangesAreExpected (ranges) { | ||
if (!ranges) return false | ||
|
||
const nonRowRanges = ranges.filter(range => range.iinfo.type !== SQL_ROW_VALUE) | ||
return nonRowRanges.length > 0 | ||
} | ||
} | ||
|
||
module.exports = InjectionAnalyzer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
packages/dd-trace/test/appsec/iast/taint-tracking/sources/sql_row.pg.plugin.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
'use strict' |
105 changes: 105 additions & 0 deletions
105
packages/dd-trace/test/appsec/iast/taint-tracking/sources/sql_row.sequelize.plugin.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
'use strict' | ||
|
||
const { prepareTestServerForIast } = require('../../utils') | ||
|
||
describe('db sources with sequelize', () => { | ||
withVersions('sequelize', 'sequelize', sequelizeVersion => { | ||
prepareTestServerForIast('sequelize', (testThatRequestHasVulnerability, testThatRequestHasNoVulnerability) => { | ||
let Sequelize, sequelize | ||
|
||
beforeEach(async () => { | ||
Sequelize = require(`../../../../../../../versions/sequelize@${sequelizeVersion}`).get() | ||
sequelize = new Sequelize('database', 'username', 'password', { | ||
dialect: 'sqlite', | ||
logging: false | ||
}) | ||
await sequelize.query(`CREATE TABLE examples ( | ||
id INT, | ||
name VARCHAR(50), | ||
query VARCHAR(100), | ||
command VARCHAR(50), | ||
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP, | ||
updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP )`) | ||
|
||
await sequelize.query(`INSERT INTO examples (id, name, query, command) | ||
VALUES (1, 'Item1', 'SELECT 1', 'ls'), | ||
(2, 'Item2', 'SELECT 1', 'ls'), | ||
(3, 'Item3', 'SELECT 1', 'ls')`) | ||
}) | ||
|
||
afterEach(() => { | ||
return sequelize.close() | ||
}) | ||
|
||
describe('using query method', () => { | ||
testThatRequestHasVulnerability(async (req, res) => { | ||
const result = await sequelize.query('SELECT * from examples') | ||
|
||
await sequelize.query(result[0][0].query) | ||
|
||
res.end('OK') | ||
}, 'SQL_INJECTION', { occurrences: 1 }, null, null, | ||
'Should have SQL_INJECTION using the first row of the result') | ||
|
||
testThatRequestHasNoVulnerability(async (req, res) => { | ||
const result = await sequelize.query('SELECT * from examples') | ||
|
||
await sequelize.query(result[0][1].query) | ||
|
||
res.end('OK') | ||
}, 'SQL_INJECTION', null, 'Should not taint the second row of a query with default configuration') | ||
|
||
testThatRequestHasNoVulnerability(async (req, res) => { | ||
const result = await sequelize.query('SELECT * from examples') | ||
|
||
const childProcess = require('child_process') | ||
childProcess.execSync(result[0][0].command) | ||
|
||
res.end('OK') | ||
}, 'COMMAND_INJECTION', null, 'Should not detect COMMAND_INJECTION with database source') | ||
}) | ||
|
||
describe('using Model', () => { | ||
// let Model | ||
let Example | ||
|
||
beforeEach(() => { | ||
Example = sequelize.define('example', { | ||
id: { | ||
type: Sequelize.DataTypes.INTEGER, | ||
primaryKey: true | ||
}, | ||
name: Sequelize.DataTypes.STRING, | ||
query: Sequelize.DataTypes.STRING, | ||
command: Sequelize.DataTypes.STRING | ||
}) | ||
}) | ||
|
||
testThatRequestHasVulnerability(async (req, res) => { | ||
const examples = await Example.findAll() | ||
|
||
await sequelize.query(examples[0].query) | ||
|
||
res.end('OK') | ||
}, 'SQL_INJECTION', { occurrences: 1 }, null, null, | ||
'Should have SQL_INJECTION using the first row of the result') | ||
|
||
testThatRequestHasNoVulnerability(async (req, res) => { | ||
const examples = await Example.findAll() | ||
|
||
await sequelize.query(examples[1].query) | ||
|
||
res.end('OK') | ||
}, 'SQL_INJECTION', null, 'Should not taint the second row of a query with default configuration') | ||
|
||
testThatRequestHasNoVulnerability(async (req, res) => { | ||
const examples = await Example.findAll() | ||
|
||
childProcess.execSync(examples[0].command) | ||
|
||
res.end('OK') | ||
}, 'COMMAND_INJECTION', null, 'Should not detect COMMAND_INJECTION with database source') | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -410,6 +410,10 @@ | |
{ | ||
"name": "express", | ||
"versions": [">=4"] | ||
}, | ||
{ | ||
"name": "sqlite3", | ||
"versions": ["^5.0.8"] | ||
} | ||
] | ||
} |