-
Notifications
You must be signed in to change notification settings - Fork 309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exploit prevention SQLi in pg #4566
Merged
+1,527
−410
Merged
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
daefc81
pg query with abortcontroller
uurien d46be5e
Adding instrumentation tests
uurien 4dd4685
Changing instrumentation for query object and adding tests
uurien 15ede9b
Add tests for pg.pool
uurien a8906cf
Implement abortController for pg.pool
uurien 6145de2
Call to waf with pg query
uurien 56014d6
Add pg.Pool blocking tests
uurien 3570cec
Analyze also in pg.Pool and ignore pg.Client when it is already analyzed
uurien dc1cbd6
Refactor - split rasp.js and move it to rasp directory
uurien c7b82f9
Add integration tests for pg and unhandled promise
uurien 3c48698
Cleaning code
uurien ff05f99
Add timeout to integration tests
uurien 48b39ff
Small fix in test
uurien 0d8920c
Add new integration test
uurien a9c48b3
Merge branch 'master' into ugaitz/rasp-sql-pg
uurien d77f60a
Apply some PR suggestions
uurien a3ea4fc
Change approach to prevent double calls
uurien 4da334c
Merge branch 'master' into ugaitz/rasp-sql-pg
uurien 35763ec
Do not prevent double calls if an input address is updated between calls
uurien 03a9435
Small fixes
uurien a8902c5
Merge branch 'master' into ugaitz/rasp-sql-pg
uurien 636b3ed
Do not use Array.concat
uurien 3b111f5
Use assert instead of checking error message manually
uurien 70f195d
require missing assert
uurien efa203a
Apply comments in the PR
uurien 38c56cf
Update packages/dd-trace/test/appsec/waf/waf_context_wrapper.spec.js
uurien 698e1b8
Merge branch 'master' into ugaitz/rasp-sql-pg
uurien d93eabe
Update packages/dd-trace/test/appsec/rasp/sql_injection.spec.js
uurien File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,244 @@ | ||
'use strict' | ||
|
||
const agent = require('../../dd-trace/test/plugins/agent') | ||
const dc = require('dc-polyfill') | ||
const { assert } = require('chai') | ||
|
||
const clients = { | ||
pg: pg => pg.Client | ||
} | ||
|
||
if (process.env.PG_TEST_NATIVE === 'true') { | ||
clients['pg.native'] = pg => pg.native.Client | ||
} | ||
|
||
describe('pg instrumentation', () => { | ||
withVersions('pg', 'pg', version => { | ||
const queryClientStartChannel = dc.channel('apm:pg:query:start') | ||
const queryPoolStartChannel = dc.channel('datadog:pg:pool:query:start') | ||
|
||
let pg | ||
let Query | ||
|
||
function abortQuery ({ abortController }) { | ||
const error = new Error('Test') | ||
abortController.abort(error) | ||
|
||
if (!abortController.signal.reason) { | ||
abortController.signal.reason = error | ||
} | ||
} | ||
|
||
before(() => { | ||
return agent.load(['pg']) | ||
}) | ||
|
||
describe('pg.Client', () => { | ||
Object.keys(clients).forEach(implementation => { | ||
describe(implementation, () => { | ||
let client | ||
|
||
beforeEach(done => { | ||
pg = require(`../../../versions/pg@${version}`).get() | ||
const Client = clients[implementation](pg) | ||
Query = Client.Query | ||
|
||
client = new Client({ | ||
host: '127.0.0.1', | ||
user: 'postgres', | ||
password: 'postgres', | ||
database: 'postgres', | ||
application_name: 'test' | ||
}) | ||
|
||
client.connect(err => done(err)) | ||
}) | ||
|
||
afterEach(() => { | ||
client.end() | ||
}) | ||
|
||
describe('abortController', () => { | ||
afterEach(() => { | ||
if (queryClientStartChannel.hasSubscribers) { | ||
queryClientStartChannel.unsubscribe(abortQuery) | ||
} | ||
}) | ||
|
||
describe('using callback', () => { | ||
it('Should not fail if it is not aborted', (done) => { | ||
client.query('SELECT 1', (err) => { | ||
done(err) | ||
}) | ||
}) | ||
|
||
it('Should abort query', (done) => { | ||
queryClientStartChannel.subscribe(abortQuery) | ||
|
||
client.query('SELECT 1', (err) => { | ||
assert.propertyVal(err, 'message', 'Test') | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
describe('using promise', () => { | ||
it('Should not fail if it is not aborted', async () => { | ||
await client.query('SELECT 1') | ||
}) | ||
|
||
it('Should abort query', async () => { | ||
queryClientStartChannel.subscribe(abortQuery) | ||
|
||
try { | ||
await client.query('SELECT 1') | ||
} catch (err) { | ||
assert.propertyVal(err, 'message', 'Test') | ||
|
||
return | ||
} | ||
|
||
throw new Error('Query was not aborted') | ||
}) | ||
}) | ||
|
||
describe('using query object', () => { | ||
describe('without callback', () => { | ||
it('Should not fail if it is not aborted', (done) => { | ||
const query = new Query('SELECT 1') | ||
|
||
client.query(query) | ||
|
||
query.on('end', () => { | ||
done() | ||
}) | ||
}) | ||
|
||
it('Should abort query', (done) => { | ||
queryClientStartChannel.subscribe(abortQuery) | ||
|
||
const query = new Query('SELECT 1') | ||
|
||
client.query(query) | ||
|
||
query.on('error', err => { | ||
assert.propertyVal(err, 'message', 'Test') | ||
done() | ||
}) | ||
|
||
query.on('end', () => { | ||
done(new Error('Query was not aborted')) | ||
}) | ||
}) | ||
}) | ||
|
||
describe('with callback in query object', () => { | ||
it('Should not fail if it is not aborted', (done) => { | ||
const query = new Query('SELECT 1') | ||
query.callback = (err) => { | ||
done(err) | ||
} | ||
|
||
client.query(query) | ||
}) | ||
|
||
it('Should abort query', (done) => { | ||
queryClientStartChannel.subscribe(abortQuery) | ||
|
||
const query = new Query('SELECT 1') | ||
query.callback = err => { | ||
assert.propertyVal(err, 'message', 'Test') | ||
done() | ||
} | ||
|
||
client.query(query) | ||
}) | ||
}) | ||
|
||
describe('with callback in query parameter', () => { | ||
it('Should not fail if it is not aborted', (done) => { | ||
const query = new Query('SELECT 1') | ||
|
||
client.query(query, (err) => { | ||
done(err) | ||
}) | ||
}) | ||
|
||
it('Should abort query', (done) => { | ||
queryClientStartChannel.subscribe(abortQuery) | ||
|
||
const query = new Query('SELECT 1') | ||
|
||
client.query(query, err => { | ||
assert.propertyVal(err, 'message', 'Test') | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
|
||
describe('pg.Pool', () => { | ||
let pool | ||
|
||
beforeEach(() => { | ||
const { Pool } = require(`../../../versions/pg@${version}`).get() | ||
|
||
pool = new Pool({ | ||
host: '127.0.0.1', | ||
user: 'postgres', | ||
password: 'postgres', | ||
database: 'postgres', | ||
application_name: 'test' | ||
}) | ||
}) | ||
|
||
describe('abortController', () => { | ||
afterEach(() => { | ||
if (queryPoolStartChannel.hasSubscribers) { | ||
queryPoolStartChannel.unsubscribe(abortQuery) | ||
} | ||
}) | ||
|
||
describe('using callback', () => { | ||
it('Should not fail if it is not aborted', (done) => { | ||
pool.query('SELECT 1', (err) => { | ||
done(err) | ||
}) | ||
}) | ||
|
||
it('Should abort query', (done) => { | ||
queryPoolStartChannel.subscribe(abortQuery) | ||
|
||
pool.query('SELECT 1', (err) => { | ||
assert.propertyVal(err, 'message', 'Test') | ||
done() | ||
}) | ||
}) | ||
}) | ||
|
||
describe('using promise', () => { | ||
it('Should not fail if it is not aborted', async () => { | ||
await pool.query('SELECT 1') | ||
}) | ||
|
||
it('Should abort query', async () => { | ||
queryPoolStartChannel.subscribe(abortQuery) | ||
|
||
try { | ||
await pool.query('SELECT 1') | ||
} catch (err) { | ||
assert.propertyVal(err, 'message', 'Test') | ||
return | ||
} | ||
|
||
throw new Error('Query was not aborted') | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |
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
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on:
https://github.com/brianc/node-postgres/blob/54eb0fa216aaccd727765641e7d1cf5da2bc483d/packages/pg/lib/client.js#L510
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worth putting this comment directly in the code