Conversation
Overall package sizeSelf size: 9.45 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | @datadog/libdatadog | 0.5.1 | 29.73 MB | 29.73 MB | | @datadog/native-appsec | 8.5.2 | 19.33 MB | 19.34 MB | | @datadog/pprof | 5.8.0 | 12.55 MB | 12.92 MB | | @datadog/native-iast-taint-tracking | 4.0.0 | 11.72 MB | 11.73 MB | | @opentelemetry/core | 1.30.1 | 908.66 kB | 7.16 MB | | protobufjs | 7.4.0 | 2.77 MB | 5.42 MB | | @datadog/wasm-js-rewriter | 4.0.1 | 2.85 MB | 3.58 MB | | @datadog/native-metrics | 3.1.1 | 1.02 MB | 1.43 MB | | @opentelemetry/api | 1.8.0 | 1.21 MB | 1.21 MB | | import-in-the-middle | 1.13.1 | 117.64 kB | 839.26 kB | | source-map | 0.7.4 | 226 kB | 226 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | lru-cache | 7.18.3 | 133.92 kB | 133.92 kB | | pprof-format | 2.1.0 | 111.69 kB | 111.69 kB | | @datadog/sketches-js | 2.1.1 | 109.9 kB | 109.9 kB | | lodash.sortby | 4.7.0 | 75.76 kB | 75.76 kB | | ignore | 5.3.2 | 53.63 kB | 53.63 kB | | istanbul-lib-coverage | 3.2.0 | 29.34 kB | 29.34 kB | | rfdc | 1.4.1 | 27.15 kB | 27.15 kB | | @isaacs/ttlcache | 1.4.1 | 25.2 kB | 25.2 kB | | dc-polyfill | 0.1.8 | 25.08 kB | 25.08 kB | | tlhunter-sorted-set | 0.1.0 | 24.94 kB | 24.94 kB | | shell-quote | 1.8.2 | 23.54 kB | 23.54 kB | | limiter | 1.1.5 | 23.17 kB | 23.17 kB | | retry | 0.13.1 | 18.85 kB | 18.85 kB | | semifies | 1.0.0 | 15.84 kB | 15.84 kB | | jest-docblock | 29.7.0 | 8.99 kB | 12.76 kB | | crypto-randomuuid | 1.0.0 | 11.18 kB | 11.18 kB | | ttl-set | 1.0.0 | 4.61 kB | 9.69 kB | | mutexify | 1.4.0 | 5.71 kB | 8.74 kB | | path-to-regexp | 0.1.12 | 6.6 kB | 6.6 kB | | koalas | 1.0.2 | 6.47 kB | 6.47 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 ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #5709 +/- ##
==========================================
+ Coverage 78.92% 79.24% +0.31%
==========================================
Files 515 520 +5
Lines 23496 23826 +330
==========================================
+ Hits 18544 18880 +336
+ Misses 4952 4946 -6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Datadog Summary✅ Code Quality ✅ Code Security ✅ Dependencies Was this helpful? Give us feedback! |
BenchmarksBenchmark execution time: 2025-05-23 13:40:39 Comparing candidate commit 367d3a2 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 1269 metrics, 54 unstable metrics. |
Datadog ReportBranch report: ✅ 0 Failed, 1153 Passed, 0 Skipped, 20m 28.6s Total Time |
uurien
left a comment
There was a problem hiding this comment.
I miss integration or plugin style tests testing the whole feature.
74601af to
cc38d6d
Compare
|
@uurien New integration test have been added in order to test the feat. |
Co-authored-by: simon-id <simon.id@datadoghq.com>
Co-authored-by: simon-id <simon.id@datadoghq.com>
Co-authored-by: simon-id <simon.id@datadoghq.com>
Co-authored-by: simon-id <simon.id@datadoghq.com>
|
|
||
| async function assertHeadersReported (requestHeaders, responseHeaders) { | ||
| await agent.assertMessageReceived(({ headers, payload }) => { | ||
| // Request headers |
There was a problem hiding this comment.
NIT: I would like to check _dd.appsec.rasp.request_body_size.exceeded tag exist in this integration test but it's not a blocker
There was a problem hiding this comment.
Added a test case to check the tag and the reported truncated req body
| 'connection' | ||
| ] | ||
|
|
||
| const expectedResponseHeaders = [ |
There was a problem hiding this comment.
Can we add a comment to explain why do we expect 22 of x-datadog-res- and not 25? I expend few minutes understanding that it was because the DD_APPSEC_MAX_COLLECTED_HEADERS=25
| DD_APPSEC_RASP_ENABLED: true, | ||
| DD_APPSEC_RULES: path.join(cwd, 'appsec/rasp/rasp_rules.json') | ||
| DD_APPSEC_RULES: path.join(cwd, 'appsec/rasp/rasp_rules.json'), | ||
| DD_APPSEC_RASP_COLLECT_REQUEST_BODY: true |
There was a problem hiding this comment.
for headers you are testing also when the configuration is not enabled, could you do the same here?
| return { value: target.slice(0, COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH), truncated: true } | ||
| } | ||
| return { value: target, truncated: false } | ||
| case 'object': { |
There was a problem hiding this comment.
To limit the scope of the variables declared in the case. See this
| return { value: truncatedArray, truncated: wasTruncated } | ||
| } | ||
|
|
||
| if (typeof target.toJSON === 'function') { |
There was a problem hiding this comment.
Shouldn't this be before the Array.isArray?
* Headers collection config * Revamp headers collection + extended collection * Fix condition for extended collection * Body collection config * Check for RASP events * Testing extend header collection * RASP body collection tests * Minor reformats * Lint * Clearer condition * Truncate body on body collection * Complete config test * Fix lint * Reporter init w/ appsec config * Remove TODO * Clarify collection comments * Update test.ts with new configuration * Fix linting * Integration test for RASP request body collection * Set tag when reported request body is truncated * Integration test for data collection * Fix linting * Check for header names in integration test * Set the correct value for request body exceeded size tag * Add support for toJSON in request body truncation * Invert condition for early return * Avoid slicing on request body truncation and implement it in a for loop * Rename reporter config * Simplify condition logic * Create block scope in switch case to limit the scope of declared vars * Initialize Array with a fixed size Co-authored-by: simon-id <simon.id@datadoghq.com> * Switch to for loop Co-authored-by: simon-id <simon.id@datadoghq.com> * Set env var as strings Co-authored-by: simon-id <simon.id@datadoghq.com> * Set env var as string Co-authored-by: simon-id <simon.id@datadoghq.com> * Refactor headers group declaration + using set instead of arrays * Cache res.getHeaders() * Fix config and its test * Fix config test for defaults values * Check reported request body truncation on integration test * Add a comment to clarify the test case * Add a test case to check no request body is collected when feat is disabled * Manage custom toJSON function in arrays --------- Co-authored-by: simon-id <simon.id@datadoghq.com>
| try { | ||
| await axios.post('/ssrf', requestBody) | ||
| } catch (e) { | ||
| if (!e.response) { | ||
| throw e | ||
| } | ||
|
|
||
| await assertBodyReported(requestBody) | ||
| } |
There was a problem hiding this comment.
I just saw this by chance and noticed that we use try / catch here and in other tests. Sadly, we don't have a guarantee that these tests actually work as anticipated due to not checking if the post call would pass (which is likely not what is expected here).
I don't know about a eslint rule to enforce assert.throws / assert.rejects but that would solve that issue. It would detect if the test would not throw an error.
* Headers collection config * Revamp headers collection + extended collection * Fix condition for extended collection * Body collection config * Check for RASP events * Testing extend header collection * RASP body collection tests * Minor reformats * Lint * Clearer condition * Truncate body on body collection * Complete config test * Fix lint * Reporter init w/ appsec config * Remove TODO * Clarify collection comments * Update test.ts with new configuration * Fix linting * Integration test for RASP request body collection * Set tag when reported request body is truncated * Integration test for data collection * Fix linting * Check for header names in integration test * Set the correct value for request body exceeded size tag * Add support for toJSON in request body truncation * Invert condition for early return * Avoid slicing on request body truncation and implement it in a for loop * Rename reporter config * Simplify condition logic * Create block scope in switch case to limit the scope of declared vars * Initialize Array with a fixed size Co-authored-by: simon-id <simon.id@datadoghq.com> * Switch to for loop Co-authored-by: simon-id <simon.id@datadoghq.com> * Set env var as strings Co-authored-by: simon-id <simon.id@datadoghq.com> * Set env var as string Co-authored-by: simon-id <simon.id@datadoghq.com> * Refactor headers group declaration + using set instead of arrays * Cache res.getHeaders() * Fix config and its test * Fix config test for defaults values * Check reported request body truncation on integration test * Add a comment to clarify the test case * Add a test case to check no request body is collected when feat is disabled * Manage custom toJSON function in arrays --------- Co-authored-by: simon-id <simon.id@datadoghq.com>
What does this PR do?
Provides the feature to collect additional data on Appsec events.
Request and response headers collection
Adds the
APPSEC_COLLECT_ALL_HEADERSflag, which enables collection of all request and response headers. This feature is disabled by default.Adds the
APPSEC_HEADER_COLLECTION_REDACTION_ENABLEDflag, which enables header redaction. This feature istrueby default. (The redaction is out of the scope, right now we only want to collect the headers without redaction).Introduces the
APPSEC_MAX_COLLECTED_HEADERSsetting to limit the maximum number of headers collected.Updates the
Reporter.finishRequestlogic to collect all headers whenAPPSEC_COLLECT_ALL_HEADERSis enabled. Allowed headers are prioritized and must be collected if present.If the number of headers exceeds
APPSEC_MAX_COLLECTED_HEADERS, the following tags are added to the span indicating the number of discarded headers:dd.appsec.request.header_collection.discardeddd.appsec.response.header_collection.discardedRequest body collection
Adds the
APPSEC_RASP_COLLECT_REQUEST_BODYflag, which enables collection of request body on RASP events. This feature is disabled by default.When
APPSEC_RASP_COLLECT_REQUEST_BODYis enabled and there is a RASP event put the same parsed request body that is sent to the WAF viameta_structwithhttp.request.bodykey. The body data is truncated under certain conditions. When it happens, the boolean tag_dd.appsec.rasp.request_body_size.exceededis addedUpdates the
Reporter.reportAttacklogic to collect request body whenAPPSEC_RASP_COLLECT_REQUEST_BODYis enabled.Motivation
Meeting the need of more information for the in-depth investigation of high-risk events.
Additional Notes
APPSEC-57290
RFC-1031
ST