Skip to content
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

Detect SQL injection with sequelize #3154

Merged
merged 11 commits into from
May 25, 2023
Merged

Conversation

uurien
Copy link
Collaborator

@uurien uurien commented May 15, 2023

What does this PR do?

With sequelize is used as sequelize.query(sql) if the sql comes from the request, the point will be reported as vulnerable.

Motivation

we are already supporting frameworks like pg or mysql, but supporting sequelize we can support all the databases that it supports (oracle, sqlite...) and calculate an accurate vulnerability file and line.

Plugin Checklist

  • Unit tests.

Additional Notes

For APM ownership changes:
This PR just adds hooks for sequelize library, to be able to analyze the query method.

@github-actions
Copy link

github-actions bot commented May 15, 2023

Overall package size

Self size: 4.19 MB
Deduped: 58.32 MB
No deduping: 58.36 MB

Dependency sizes

name version self size total size
@datadog/pprof 2.2.1 14.24 MB 15.12 MB
@datadog/native-iast-taint-tracking 1.4.1 14.85 MB 14.86 MB
@datadog/native-appsec 3.1.0 13.31 MB 13.32 MB
protobufjs 7.1.2 2.76 MB 6.55 MB
@datadog/native-iast-rewriter 2.0.1 2.09 MB 2.1 MB
@datadog/native-metrics 2.0.0 898.77 kB 1.3 MB
opentracing 0.14.7 194.81 kB 194.81 kB
semver 7.3.8 88.2 kB 118.6 kB
@datadog/sketches-js 2.1.0 109.9 kB 109.9 kB
lodash.sortby 4.7.0 75.76 kB 75.76 kB
lru-cache 7.14.0 74.95 kB 74.95 kB
ipaddr.js 2.0.1 59.52 kB 59.52 kB
ignore 5.2.0 48.87 kB 48.87 kB
import-in-the-middle 1.3.5 34.34 kB 38.81 kB
istanbul-lib-coverage 3.2.0 29.34 kB 29.34 kB
retry 0.10.1 27.44 kB 27.44 kB
lodash.uniq 4.5.0 25.01 kB 25.01 kB
limiter 1.1.5 23.17 kB 23.17 kB
lodash.kebabcase 4.1.1 17.75 kB 17.75 kB
lodash.pick 4.4.0 16.33 kB 16.33 kB
node-abort-controller 3.0.1 14.33 kB 14.33 kB
crypto-randomuuid 1.0.0 11.18 kB 11.18 kB
diagnostics_channel 1.1.0 7.07 kB 7.07 kB
path-to-regexp 0.1.7 6.78 kB 6.78 kB
koalas 1.0.2 6.47 kB 6.47 kB
methods 1.1.2 5.29 kB 5.29 kB
module-details-from-path 1.0.3 4.47 kB 4.47 kB

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@codecov
Copy link

codecov bot commented May 15, 2023

Codecov Report

Merging #3154 (da59b75) into master (15b2767) will increase coverage by 0.03%.
The diff coverage is 82.50%.

@@            Coverage Diff             @@
##           master    #3154      +/-   ##
==========================================
+ Coverage   86.54%   86.57%   +0.03%     
==========================================
  Files         333      333              
  Lines       11895    11922      +27     
  Branches       33       33              
==========================================
+ Hits        10295    10322      +27     
  Misses       1600     1600              
Impacted Files Coverage Δ
...rc/appsec/iast/analyzers/sql-injection-analyzer.js 78.94% <53.33%> (-17.35%) ⬇️
...rc/appsec/iast/analyzers/vulnerability-analyzer.js 79.06% <100.00%> (ø)
packages/dd-trace/src/appsec/iast/path-line.js 100.00% <100.00%> (ø)
.../dd-trace/src/appsec/iast/taint-tracking/plugin.js 100.00% <100.00%> (+11.11%) ⬆️
...tion/sensitive-analyzers/sql-sensitive-analyzer.js 96.15% <100.00%> (+4.66%) ⬆️

... and 2 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@pr-commenter
Copy link

pr-commenter bot commented May 15, 2023

Benchmarks

Comparing candidate commit da59b75 in PR branch ugaitz/fix-sequelize-sql-detection with baseline commit 15b2767 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 441 metrics, 31 unstable metrics.

@uurien uurien force-pushed the ugaitz/fix-sequelize-sql-detection branch from 86a79af to 95d4666 Compare May 17, 2023 10:26
@uurien uurien force-pushed the ugaitz/fix-sequelize-sql-detection branch from bc238c1 to 5a707ad Compare May 17, 2023 10:39
@uurien uurien changed the title Detect vulnerabilities in sequelize and ignore when sql is already va… SQL injection with sequelize May 17, 2023
@uurien uurien marked this pull request as ready for review May 17, 2023 13:57
@uurien uurien requested review from a team as code owners May 17, 2023 13:57
if (parentStore) {
this.analyze(sql, dialect.toUpperCase())

storage.enterWith({ ...parentStore, sqlAnalyzed: true, sequelizeParentStore: parentStore })
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data doesn't seem to ever get cleared from the store so it may have some unintended side-effects. 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is restored on datadog:sequelize:query:finish

The purpose of this lines is prevent double detections of the same vulnerability. As sequelize library uses pg or mysql2 libraries, we need a way to set in store that we are already in the query. For that reason we are entering with new store in :start and restoring the old one in :finish.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, true. Do you know if sequelize could trigger these in a nested way? Setting on the store rather than storing on the span could make things leak beyond where it should. 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've reviewed it after your comment. The answer is not, sequelize.query method does not call internally again to the same query method.
sequelize.query method calls to the query method of the select dialect (pg, sqlite, mysql...)

With sequelize we are not creating new span, so current span is the parent span, and the parent span can have multiple calls to sequelize.query method, that the reason that we should save the data in AsyncResource (that is new asyncresource, created in the instrumentation point) and not in the parent span.

@uurien uurien changed the title SQL injection with sequelize Detect SQL injection with sequelize May 18, 2023
@uurien uurien force-pushed the ugaitz/fix-sequelize-sql-detection branch from 64d6e66 to fd087a9 Compare May 19, 2023 06:53
const startCh = channel('datadog:sequelize:query:start')
const finishCh = channel('datadog:sequelize:query:finish')

shimmer.wrap(Sequelize.prototype, 'query', query => function (sql) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERY weird syntax, i didn't know you could even do that, maybe it's worth to declare the functions above with names instead of putting everything inline

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I can just do something like, that looks easier to read and understand.

shimmer.wrap(Sequelize.prototype, 'query', query => {
  return function (sql) {
    ...
  }
}

(I'm doing this because I've seen it in other files:

shimmer.wrap(Connection.prototype, 'addCommand', addCommand => function (cmd) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fairly common pattern actually, but usually it would all be arrow functions, for example query => sql => {}. The reason for using regular functions originally was to be able to name them, but I'm not sure if that's relevant here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use arrow functions to wrap methods, we will override the this parameter into the methods, because we are not going to be able to get the original this because in the arrow functions, this makes reference to the parent function this.

@uurien uurien force-pushed the ugaitz/fix-sequelize-sql-detection branch from d31cc9e to da59b75 Compare May 23, 2023 12:43
@uurien uurien merged commit 1b104ad into master May 25, 2023
104 checks passed
@uurien uurien deleted the ugaitz/fix-sequelize-sql-detection branch May 25, 2023 07:00
thedavl pushed a commit that referenced this pull request May 30, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
uurien added a commit that referenced this pull request Jun 1, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
uurien added a commit that referenced this pull request Jun 1, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
uurien added a commit that referenced this pull request Jun 1, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
This was referenced Jun 1, 2023
uurien added a commit that referenced this pull request Jun 2, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
uurien added a commit that referenced this pull request Jun 2, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
uurien added a commit that referenced this pull request Jun 2, 2023

---------

Co-authored-by: Stephen Belanger <stephen.belanger@datadoghq.com>
Co-authored-by: Igor Unanua <igor.unanua@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants