dd-trace 5.45.0 → 5.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/LICENSE-3rdparty.csv +1 -2
  2. package/ci/init.js +8 -0
  3. package/ext/exporters.d.ts +2 -1
  4. package/ext/exporters.js +2 -1
  5. package/package.json +8 -9
  6. package/packages/datadog-instrumentations/orchestrion.yml +52 -0
  7. package/packages/datadog-instrumentations/src/cucumber.js +2 -1
  8. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  9. package/packages/datadog-instrumentations/src/helpers/register.js +41 -1
  10. package/packages/datadog-instrumentations/src/jest.js +11 -2
  11. package/packages/datadog-instrumentations/src/langchain.js +49 -53
  12. package/packages/datadog-instrumentations/src/mariadb.js +19 -0
  13. package/packages/datadog-instrumentations/src/mocha/main.js +1 -1
  14. package/packages/datadog-instrumentations/src/mocha/utils.js +11 -3
  15. package/packages/datadog-instrumentations/src/orchestrion-config/index.js +5 -0
  16. package/packages/datadog-instrumentations/src/playwright.js +333 -46
  17. package/packages/datadog-instrumentations/src/router.js +1 -7
  18. package/packages/datadog-instrumentations/src/vitest.js +11 -3
  19. package/packages/datadog-plugin-cucumber/src/index.js +11 -4
  20. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +17 -5
  21. package/packages/datadog-plugin-jest/src/index.js +11 -4
  22. package/packages/datadog-plugin-langchain/src/index.js +18 -12
  23. package/packages/datadog-plugin-langchain/src/tracing.js +66 -6
  24. package/packages/datadog-plugin-mocha/src/index.js +17 -5
  25. package/packages/datadog-plugin-mongodb-core/src/index.js +24 -0
  26. package/packages/datadog-plugin-playwright/src/index.js +124 -10
  27. package/packages/datadog-plugin-vitest/src/index.js +13 -8
  28. package/packages/datadog-shimmer/src/shimmer.js +3 -42
  29. package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +39 -15
  30. package/packages/dd-trace/src/appsec/iast/taint-tracking/filter.js +3 -3
  31. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +0 -3
  32. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +25 -12
  33. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-telemetry.js +3 -32
  34. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +99 -57
  35. package/packages/dd-trace/src/appsec/rasp/command_injection.js +1 -1
  36. package/packages/dd-trace/src/appsec/rasp/index.js +4 -2
  37. package/packages/dd-trace/src/appsec/rasp/lfi.js +1 -1
  38. package/packages/dd-trace/src/appsec/rasp/sql_injection.js +1 -1
  39. package/packages/dd-trace/src/appsec/rasp/ssrf.js +1 -1
  40. package/packages/dd-trace/src/appsec/rasp/utils.js +12 -7
  41. package/packages/dd-trace/src/appsec/recommended.json +256 -84
  42. package/packages/dd-trace/src/appsec/reporter.js +6 -4
  43. package/packages/dd-trace/src/appsec/telemetry/index.js +27 -3
  44. package/packages/dd-trace/src/appsec/telemetry/rasp.js +70 -6
  45. package/packages/dd-trace/src/appsec/telemetry/waf.js +0 -30
  46. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +4 -0
  47. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +8 -3
  48. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +6 -4
  49. package/packages/dd-trace/src/config.js +9 -0
  50. package/packages/dd-trace/src/constants.js +1 -0
  51. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +102 -22
  52. package/packages/dd-trace/src/debugger/devtools_client/condition.js +263 -0
  53. package/packages/dd-trace/src/debugger/devtools_client/index.js +69 -36
  54. package/packages/dd-trace/src/debugger/devtools_client/lock.js +8 -0
  55. package/packages/dd-trace/src/debugger/devtools_client/remote_config.js +1 -7
  56. package/packages/dd-trace/src/debugger/devtools_client/send.js +2 -2
  57. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +15 -10
  58. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +3 -3
  59. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +69 -62
  60. package/packages/dd-trace/src/debugger/devtools_client/state.js +3 -2
  61. package/packages/dd-trace/src/debugger/index.js +3 -0
  62. package/packages/dd-trace/src/encode/0.4.js +24 -17
  63. package/packages/dd-trace/src/exporter.js +1 -0
  64. package/packages/dd-trace/src/exporters/common/docker.js +37 -7
  65. package/packages/dd-trace/src/exporters/common/request.js +1 -4
  66. package/packages/dd-trace/src/format.js +58 -60
  67. package/packages/dd-trace/src/llmobs/plugins/base.js +2 -2
  68. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +62 -3
  69. package/packages/dd-trace/src/llmobs/plugins/openai.js +1 -0
  70. package/packages/dd-trace/src/llmobs/plugins/vertexai.js +2 -1
  71. package/packages/dd-trace/src/llmobs/writers/spans/base.js +3 -3
  72. package/packages/dd-trace/src/log/index.js +2 -0
  73. package/packages/dd-trace/src/log/writer.js +19 -2
  74. package/packages/dd-trace/src/opentelemetry/span.js +4 -4
  75. package/packages/dd-trace/src/opentracing/propagation/text_map.js +17 -3
  76. package/packages/dd-trace/src/opentracing/span.js +10 -0
  77. package/packages/dd-trace/src/plugin_manager.js +2 -0
  78. package/packages/dd-trace/src/plugins/util/test.js +11 -0
  79. package/packages/dd-trace/src/profiler.js +1 -1
  80. package/packages/dd-trace/src/profiling/config.js +6 -0
  81. package/packages/dd-trace/src/profiling/exporters/agent.js +1 -5
  82. package/packages/dd-trace/src/profiling/profiler.js +4 -3
  83. package/packages/dd-trace/src/profiling/profilers/wall.js +12 -8
  84. package/packages/dd-trace/src/proxy.js +5 -1
  85. package/packages/dd-trace/src/tagger.js +38 -26
  86. package/packages/dd-trace/src/util.js +1 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "2.2",
3
3
  "metadata": {
4
- "rules_version": "1.13.3"
4
+ "rules_version": "1.14.2"
5
5
  },
6
6
  "rules": [
7
7
  {
@@ -4864,6 +4864,36 @@
4864
4864
  ],
4865
4865
  "transformers": []
4866
4866
  },
4867
+ {
4868
+ "id": "ua0-600-68x",
4869
+ "name": "xorbot",
4870
+ "tags": {
4871
+ "type": "attack_tool",
4872
+ "category": "attack_attempt",
4873
+ "cwe": "200",
4874
+ "capec": "1000/118/169",
4875
+ "tool_name": "xorbot",
4876
+ "confidence": "0",
4877
+ "module": "waf"
4878
+ },
4879
+ "conditions": [
4880
+ {
4881
+ "parameters": {
4882
+ "inputs": [
4883
+ {
4884
+ "address": "server.request.headers.no_cookies",
4885
+ "key_path": [
4886
+ "user-agent"
4887
+ ]
4888
+ }
4889
+ ],
4890
+ "regex": "\\bmasjesu\\b"
4891
+ },
4892
+ "operator": "match_regex"
4893
+ }
4894
+ ],
4895
+ "transformers": []
4896
+ },
4867
4897
  {
4868
4898
  "id": "dog-913-001",
4869
4899
  "name": "BurpCollaborator OOB domain",
@@ -5422,6 +5452,82 @@
5422
5452
  ],
5423
5453
  "transformers": []
5424
5454
  },
5455
+ {
5456
+ "id": "dog-913-013",
5457
+ "name": "Public PoC for CVE-2025-24813",
5458
+ "tags": {
5459
+ "type": "attack_tool",
5460
+ "category": "attack_attempt",
5461
+ "cwe": "200",
5462
+ "capec": "1000/118/169",
5463
+ "confidence": "1",
5464
+ "module": "waf"
5465
+ },
5466
+ "conditions": [
5467
+ {
5468
+ "parameters": {
5469
+ "inputs": [
5470
+ {
5471
+ "address": "server.request.uri.raw"
5472
+ }
5473
+ ],
5474
+ "regex": "/iSee857/session",
5475
+ "options": {
5476
+ "case_sensitive": false,
5477
+ "min_length": 16
5478
+ }
5479
+ },
5480
+ "operator": "match_regex"
5481
+ }
5482
+ ],
5483
+ "transformers": []
5484
+ },
5485
+ {
5486
+ "id": "dog-913-014",
5487
+ "name": "Exploit attempt for Next.js Middleware Exploit (CVE-2025-29927)",
5488
+ "tags": {
5489
+ "type": "security_scanner",
5490
+ "category": "attack_attempt",
5491
+ "cwe": "200",
5492
+ "capec": "1000/118/169",
5493
+ "confidence": "0",
5494
+ "module": "waf"
5495
+ },
5496
+ "conditions": [
5497
+ {
5498
+ "parameters": {
5499
+ "inputs": [
5500
+ {
5501
+ "address": "server.request.headers.no_cookies",
5502
+ "key_path": [
5503
+ "x-middleware-subrequest"
5504
+ ]
5505
+ }
5506
+ ],
5507
+ "regex": ".*",
5508
+ "options": {
5509
+ "min_length": 1
5510
+ }
5511
+ },
5512
+ "operator": "match_regex"
5513
+ },
5514
+ {
5515
+ "parameters": {
5516
+ "inputs": [
5517
+ {
5518
+ "address": "server.request.headers.no_cookies",
5519
+ "key_path": [
5520
+ "x-middleware-subrequest"
5521
+ ]
5522
+ }
5523
+ ],
5524
+ "regex": "[0-9a-fA-F]{40}|\\[\\w+\\]"
5525
+ },
5526
+ "operator": "!match_regex"
5527
+ }
5528
+ ],
5529
+ "transformers": []
5530
+ },
5425
5531
  {
5426
5532
  "id": "dog-920-001",
5427
5533
  "name": "JWT authentication bypass",
@@ -6314,7 +6420,7 @@
6314
6420
  "address": "server.request.uri.raw"
6315
6421
  }
6316
6422
  ],
6317
- "regex": "(?:/swagger\\b|/api[-/]docs?\\b)",
6423
+ "regex": "(?:^|/)(?:swagger|api[-/]?docs?|openapi)\\b",
6318
6424
  "options": {
6319
6425
  "case_sensitive": false
6320
6426
  }
@@ -6331,7 +6437,7 @@
6331
6437
  "category": "vulnerability_trigger",
6332
6438
  "cwe": "22",
6333
6439
  "capec": "1000/255/153/126",
6334
- "confidence": "0",
6440
+ "confidence": "1",
6335
6441
  "module": "rasp"
6336
6442
  },
6337
6443
  "conditions": [
@@ -6379,7 +6485,7 @@
6379
6485
  "category": "vulnerability_trigger",
6380
6486
  "cwe": "77",
6381
6487
  "capec": "1000/152/248/88",
6382
- "confidence": "0",
6488
+ "confidence": "1",
6383
6489
  "module": "rasp"
6384
6490
  },
6385
6491
  "conditions": [
@@ -6427,7 +6533,7 @@
6427
6533
  "category": "vulnerability_trigger",
6428
6534
  "cwe": "77",
6429
6535
  "capec": "1000/152/248/88",
6430
- "confidence": "0",
6536
+ "confidence": "1",
6431
6537
  "module": "rasp"
6432
6538
  },
6433
6539
  "conditions": [
@@ -6479,6 +6585,20 @@
6479
6585
  "module": "rasp"
6480
6586
  },
6481
6587
  "conditions": [
6588
+ {
6589
+ "parameters": {
6590
+ "inputs": [
6591
+ {
6592
+ "address": "server.io.net.url"
6593
+ }
6594
+ ],
6595
+ "regex": "^(jar:)?https?:\\/\\/\\W*([0-9oq]{1,5}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|[0-9]{1,10}|(\\[)?[:0-9a-f\\.x]{2,}(\\])?|metadata\\.google\\.internal|(?:[a-z0-9:@\\.\\-]*\\.)?(?:burpcollaborator\\.net|localtest\\.me|mail\\.ebc\\.apple\\.com|bugbounty\\.dod\\.network|.*\\.[nx]ip\\.io|oastify\\.com|oast\\.(?:pro|live|site|online|fun|me)|sslip\\.io|requestbin\\.com|requestbin\\.net|hookbin\\.com|webhook\\.site|canarytokens\\.com|interact\\.sh|ngrok\\.io|bugbounty\\.click|prbly\\.win|qualysperiscope\\.com|vii\\.one|act1on3\\.ru|ifconfig\\.pro|dnslog\\.\\w+))(:[0-9]{1,5})?(\\/[^:@]*)?$",
6596
+ "options": {
6597
+ "case_sensitive": false
6598
+ }
6599
+ },
6600
+ "operator": "match_regex"
6601
+ },
6482
6602
  {
6483
6603
  "parameters": {
6484
6604
  "resource": [
@@ -6523,7 +6643,7 @@
6523
6643
  "category": "vulnerability_trigger",
6524
6644
  "cwe": "89",
6525
6645
  "capec": "1000/152/248/66",
6526
- "confidence": "0",
6646
+ "confidence": "1",
6527
6647
  "module": "rasp"
6528
6648
  },
6529
6649
  "conditions": [
@@ -6957,7 +7077,7 @@
6957
7077
  "address": "graphql.server.resolver"
6958
7078
  }
6959
7079
  ],
6960
- "regex": "(http|https):\\/\\/(?:.*\\.)?(?:burpcollaborator\\.net|localtest\\.me|mail\\.ebc\\.apple\\.com|bugbounty\\.dod\\.network|.*\\.[nx]ip\\.io|oastify\\.com|oast\\.(?:pro|live|site|online|fun|me)|sslip\\.io|requestbin\\.com|requestbin\\.net|hookbin\\.com|webhook\\.site|canarytokens\\.com|interact\\.sh|ngrok\\.io|bugbounty\\.click|prbly\\.win|qualysperiscope\\.com|vii\\.one|act1on3\\.ru)"
7080
+ "regex": "(http|https):\\/\\/(?:.*\\.)?(?:burpcollaborator\\.net|localtest\\.me|mail\\.ebc\\.apple\\.com|bugbounty\\.dod\\.network|.*\\.[nx]ip\\.io|oastify\\.com|oast\\.(?:pro|live|site|online|fun|me)|sslip\\.io|requestbin\\.com|requestbin\\.net|hookbin\\.com|webhook\\.site|canarytokens\\.com|interact\\.sh|ngrok\\.io|bugbounty\\.click|prbly\\.win|qualysperiscope\\.com|vii\\.one|act1on3\\.ru|dnslog\\.\\w+)"
6961
7081
  },
6962
7082
  "operator": "match_regex"
6963
7083
  }
@@ -7765,7 +7885,7 @@
7765
7885
  ]
7766
7886
  }
7767
7887
  ],
7768
- "regex": "nmap (nse|scripting engine)"
7888
+ "regex": "nmap (nse|scripting engine|icap-client/)"
7769
7889
  },
7770
7890
  "operator": "match_regex"
7771
7891
  }
@@ -8537,6 +8657,126 @@
8537
8657
  ],
8538
8658
  "transformers": []
8539
8659
  },
8660
+ {
8661
+ "id": "ua0-600-64x",
8662
+ "name": "ddg_win",
8663
+ "tags": {
8664
+ "type": "attack_tool",
8665
+ "category": "attack_attempt",
8666
+ "cwe": "200",
8667
+ "capec": "1000/118/169",
8668
+ "tool_name": "ddg_win",
8669
+ "confidence": "1",
8670
+ "module": "waf"
8671
+ },
8672
+ "conditions": [
8673
+ {
8674
+ "parameters": {
8675
+ "inputs": [
8676
+ {
8677
+ "address": "server.request.headers.no_cookies",
8678
+ "key_path": [
8679
+ "user-agent"
8680
+ ]
8681
+ }
8682
+ ],
8683
+ "regex": "\\bddg_win\\b"
8684
+ },
8685
+ "operator": "match_regex"
8686
+ }
8687
+ ],
8688
+ "transformers": []
8689
+ },
8690
+ {
8691
+ "id": "ua0-600-65x",
8692
+ "name": "ISS",
8693
+ "tags": {
8694
+ "type": "commercial_scanner",
8695
+ "category": "attack_attempt",
8696
+ "cwe": "200",
8697
+ "capec": "1000/118/169",
8698
+ "tool_name": "iss",
8699
+ "confidence": "0",
8700
+ "module": "waf"
8701
+ },
8702
+ "conditions": [
8703
+ {
8704
+ "parameters": {
8705
+ "inputs": [
8706
+ {
8707
+ "address": "server.request.headers.no_cookies",
8708
+ "key_path": [
8709
+ "user-agent"
8710
+ ]
8711
+ }
8712
+ ],
8713
+ "regex": "\\bisscyberriskcrawler/\\d\\.\\d"
8714
+ },
8715
+ "operator": "match_regex"
8716
+ }
8717
+ ],
8718
+ "transformers": []
8719
+ },
8720
+ {
8721
+ "id": "ua0-600-66x",
8722
+ "name": "BountyBot",
8723
+ "tags": {
8724
+ "type": "attack_tool",
8725
+ "category": "attack_attempt",
8726
+ "cwe": "200",
8727
+ "capec": "1000/118/169",
8728
+ "tool_name": "bountybot",
8729
+ "confidence": "1",
8730
+ "module": "waf"
8731
+ },
8732
+ "conditions": [
8733
+ {
8734
+ "parameters": {
8735
+ "inputs": [
8736
+ {
8737
+ "address": "server.request.headers.no_cookies",
8738
+ "key_path": [
8739
+ "user-agent"
8740
+ ]
8741
+ }
8742
+ ],
8743
+ "regex": "\\bbountybot\\b"
8744
+ },
8745
+ "operator": "match_regex"
8746
+ }
8747
+ ],
8748
+ "transformers": []
8749
+ },
8750
+ {
8751
+ "id": "ua0-600-67x",
8752
+ "name": "ZumBot",
8753
+ "tags": {
8754
+ "type": "attack_tool",
8755
+ "category": "attack_attempt",
8756
+ "cwe": "200",
8757
+ "capec": "1000/118/169",
8758
+ "tool_name": "zumbot",
8759
+ "confidence": "1",
8760
+ "module": "waf"
8761
+ },
8762
+ "conditions": [
8763
+ {
8764
+ "parameters": {
8765
+ "inputs": [
8766
+ {
8767
+ "address": "server.request.headers.no_cookies",
8768
+ "key_path": [
8769
+ "user-agent"
8770
+ ]
8771
+ }
8772
+ ],
8773
+ "regex": "\\bzumbot\\b"
8774
+ },
8775
+ "operator": "match_regex"
8776
+ }
8777
+ ],
8778
+ "transformers": []
8779
+ },
8540
8780
  {
8541
8781
  "id": "ua0-600-6xx",
8542
8782
  "name": "Stealthy scanner",
@@ -8634,24 +8874,7 @@
8634
8874
  {
8635
8875
  "id": "http-endpoint-fingerprint",
8636
8876
  "generator": "http_endpoint_fingerprint",
8637
- "conditions": [
8638
- {
8639
- "operator": "exists",
8640
- "parameters": {
8641
- "inputs": [
8642
- {
8643
- "address": "waf.context.event"
8644
- },
8645
- {
8646
- "address": "server.business_logic.users.login.failure"
8647
- },
8648
- {
8649
- "address": "server.business_logic.users.login.success"
8650
- }
8651
- ]
8652
- }
8653
- }
8654
- ],
8877
+ "conditions": [],
8655
8878
  "parameters": {
8656
8879
  "mappings": [
8657
8880
  {
@@ -8679,7 +8902,7 @@
8679
8902
  }
8680
8903
  ]
8681
8904
  },
8682
- "evaluate": false,
8905
+ "evaluate": true,
8683
8906
  "output": true
8684
8907
  },
8685
8908
  {
@@ -8835,24 +9058,7 @@
8835
9058
  {
8836
9059
  "id": "http-header-fingerprint",
8837
9060
  "generator": "http_header_fingerprint",
8838
- "conditions": [
8839
- {
8840
- "operator": "exists",
8841
- "parameters": {
8842
- "inputs": [
8843
- {
8844
- "address": "waf.context.event"
8845
- },
8846
- {
8847
- "address": "server.business_logic.users.login.failure"
8848
- },
8849
- {
8850
- "address": "server.business_logic.users.login.success"
8851
- }
8852
- ]
8853
- }
8854
- }
8855
- ],
9061
+ "conditions": [],
8856
9062
  "parameters": {
8857
9063
  "mappings": [
8858
9064
  {
@@ -8865,30 +9071,13 @@
8865
9071
  }
8866
9072
  ]
8867
9073
  },
8868
- "evaluate": false,
9074
+ "evaluate": true,
8869
9075
  "output": true
8870
9076
  },
8871
9077
  {
8872
9078
  "id": "http-network-fingerprint",
8873
9079
  "generator": "http_network_fingerprint",
8874
- "conditions": [
8875
- {
8876
- "operator": "exists",
8877
- "parameters": {
8878
- "inputs": [
8879
- {
8880
- "address": "waf.context.event"
8881
- },
8882
- {
8883
- "address": "server.business_logic.users.login.failure"
8884
- },
8885
- {
8886
- "address": "server.business_logic.users.login.success"
8887
- }
8888
- ]
8889
- }
8890
- }
8891
- ],
9080
+ "conditions": [],
8892
9081
  "parameters": {
8893
9082
  "mappings": [
8894
9083
  {
@@ -8901,30 +9090,13 @@
8901
9090
  }
8902
9091
  ]
8903
9092
  },
8904
- "evaluate": false,
9093
+ "evaluate": true,
8905
9094
  "output": true
8906
9095
  },
8907
9096
  {
8908
9097
  "id": "session-fingerprint",
8909
9098
  "generator": "session_fingerprint",
8910
- "conditions": [
8911
- {
8912
- "operator": "exists",
8913
- "parameters": {
8914
- "inputs": [
8915
- {
8916
- "address": "waf.context.event"
8917
- },
8918
- {
8919
- "address": "server.business_logic.users.login.failure"
8920
- },
8921
- {
8922
- "address": "server.business_logic.users.login.success"
8923
- }
8924
- ]
8925
- }
8926
- }
8927
- ],
9099
+ "conditions": [],
8928
9100
  "parameters": {
8929
9101
  "mappings": [
8930
9102
  {
@@ -8947,7 +9119,7 @@
8947
9119
  }
8948
9120
  ]
8949
9121
  },
8950
- "evaluate": false,
9122
+ "evaluate": true,
8951
9123
  "output": true
8952
9124
  }
8953
9125
  ],
@@ -6,12 +6,13 @@ const web = require('../plugins/util/web')
6
6
  const { ipHeaderList } = require('../plugins/util/ip_extractor')
7
7
  const {
8
8
  incrementWafInitMetric,
9
- updateWafRequestsMetricTags,
10
- updateRaspRequestsMetricTags,
11
9
  incrementWafUpdatesMetric,
12
10
  incrementWafRequestsMetric,
13
- getRequestMetrics,
14
- updateRateLimitedMetric
11
+ updateWafRequestsMetricTags,
12
+ updateRaspRequestsMetricTags,
13
+ updateRaspRuleSkippedMetricTags,
14
+ updateRateLimitedMetric,
15
+ getRequestMetrics
15
16
  } = require('./telemetry')
16
17
  const zlib = require('zlib')
17
18
  const { keepTrace } = require('../priority_sampler')
@@ -294,6 +295,7 @@ module.exports = {
294
295
  reportMetrics,
295
296
  reportAttack,
296
297
  reportWafUpdate: incrementWafUpdatesMetric,
298
+ reportRaspRuleSkipped: updateRaspRuleSkippedMetricTags,
297
299
  reportDerivatives,
298
300
  finishRequest,
299
301
  setRateLimit,
@@ -1,8 +1,13 @@
1
1
  'use strict'
2
2
 
3
3
  const { DD_TELEMETRY_REQUEST_METRICS } = require('./common')
4
- const { addRaspRequestMetrics, trackRaspMetrics } = require('./rasp')
5
4
  const { incrementMissingUserId, incrementMissingUserLogin, incrementSdkEvent } = require('./user')
5
+ const {
6
+ addRaspRequestMetrics,
7
+ trackRaspMetrics,
8
+ trackRaspRuleMatch,
9
+ trackRaspRuleSkipped
10
+ } = require('./rasp')
6
11
  const {
7
12
  addWafRequestMetrics,
8
13
  trackWafMetrics,
@@ -34,7 +39,10 @@ function newStore () {
34
39
  wafTimeouts: 0,
35
40
  raspTimeouts: 0,
36
41
  wafErrorCode: null,
37
- raspErrorCode: null
42
+ raspErrorCode: null,
43
+ wafVersion: null,
44
+ rulesVersion: null,
45
+ ruleTriggered: null
38
46
  }
39
47
  }
40
48
  }
@@ -58,7 +66,21 @@ function updateRaspRequestsMetricTags (metrics, req, raspRule) {
58
66
 
59
67
  if (!enabled) return
60
68
 
61
- trackRaspMetrics(metrics, raspRule)
69
+ trackRaspMetrics(store, metrics, raspRule)
70
+ }
71
+
72
+ function updateRaspRuleMatchMetricTags (req, raspRule, blockTriggered, blocked) {
73
+ if (!enabled || !req) return
74
+
75
+ const store = getStore(req)
76
+
77
+ trackRaspRuleMatch(store, raspRule, blockTriggered, blocked)
78
+ }
79
+
80
+ function updateRaspRuleSkippedMetricTags (raspRule, reason) {
81
+ if (!enabled) return
82
+
83
+ trackRaspRuleSkipped(raspRule, reason)
62
84
  }
63
85
 
64
86
  function updateWafRequestsMetricTags (metrics, req) {
@@ -142,6 +164,8 @@ module.exports = {
142
164
  updateRateLimitedMetric,
143
165
  updateBlockFailureMetric,
144
166
  updateRaspRequestsMetricTags,
167
+ updateRaspRuleMatchMetricTags,
168
+ updateRaspRuleSkippedMetricTags,
145
169
  incrementWafInitMetric,
146
170
  incrementWafUpdatesMetric,
147
171
  incrementWafRequestsMetric,
@@ -1,10 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const telemetryMetrics = require('../../telemetry/metrics')
4
- const { DD_TELEMETRY_REQUEST_METRICS } = require('./common')
4
+ const { DD_TELEMETRY_REQUEST_METRICS, getVersionsTags } = require('./common')
5
5
 
6
6
  const appsecMetrics = telemetryMetrics.manager.namespace('appsec')
7
7
 
8
+ const BLOCKING_STATUS = {
9
+ FAILURE: 'failure',
10
+ IRRELEVANT: 'irrelevant',
11
+ SUCCESS: 'success'
12
+ }
13
+
8
14
  function addRaspRequestMetrics (store, { duration, durationExt, wafTimeout, errorCode }) {
9
15
  store[DD_TELEMETRY_REQUEST_METRICS].raspDuration += duration || 0
10
16
  store[DD_TELEMETRY_REQUEST_METRICS].raspDurationExt += durationExt || 0
@@ -26,25 +32,83 @@ function addRaspRequestMetrics (store, { duration, durationExt, wafTimeout, erro
26
32
  }
27
33
  }
28
34
 
29
- function trackRaspMetrics (metrics, raspRule) {
30
- const tags = { rule_type: raspRule.type, waf_version: metrics.wafVersion }
35
+ function trackRaspMetrics (store, metrics, raspRule) {
36
+ const versionsTags = getVersionsTags(metrics.wafVersion, metrics.rulesVersion)
37
+ const tags = { rule_type: raspRule.type, ...versionsTags }
38
+ const telemetryMetrics = store[DD_TELEMETRY_REQUEST_METRICS]
31
39
 
32
40
  if (raspRule.variant) {
33
41
  tags.rule_variant = raspRule.variant
34
42
  }
35
43
 
44
+ if (metrics.wafVersion) {
45
+ telemetryMetrics.wafVersion = metrics.wafVersion
46
+ }
47
+
48
+ if (metrics.rulesVersion) {
49
+ telemetryMetrics.rulesVersion = metrics.rulesVersion
50
+ }
51
+
52
+ if (metrics.ruleTriggered) {
53
+ telemetryMetrics.ruleTriggered = true
54
+ }
55
+
36
56
  appsecMetrics.count('rasp.rule.eval', tags).inc(1)
37
57
 
58
+ if (metrics.errorCode) {
59
+ const errorTags = { ...tags, waf_error: metrics.errorCode }
60
+
61
+ appsecMetrics.count('rasp.error', errorTags).inc(1)
62
+ }
63
+
38
64
  if (metrics.wafTimeout) {
39
65
  appsecMetrics.count('rasp.timeout', tags).inc(1)
40
66
  }
67
+ }
41
68
 
42
- if (metrics.ruleTriggered) {
43
- appsecMetrics.count('rasp.rule.match', tags).inc(1)
69
+ function trackRaspRuleMatch (store, raspRule, blockTriggered, blocked) {
70
+ const telemetryMetrics = store[DD_TELEMETRY_REQUEST_METRICS]
71
+ if (!telemetryMetrics.ruleTriggered) return
72
+
73
+ const tags = {
74
+ waf_version: telemetryMetrics.wafVersion,
75
+ event_rules_version: telemetryMetrics.rulesVersion,
76
+ rule_type: raspRule.type,
77
+ block: getRuleMatchBlockingStatus(blockTriggered, blocked)
78
+ }
79
+
80
+ if (raspRule.variant) {
81
+ tags.rule_variant = raspRule.variant
82
+ }
83
+
84
+ appsecMetrics.count('rasp.rule.match', tags).inc(1)
85
+
86
+ // this is needed to not count it twice for the same match
87
+ // but it also means it can only be called once per waf call even if there are multiple rasp match
88
+ telemetryMetrics.ruleTriggered = null
89
+ }
90
+
91
+ function trackRaspRuleSkipped (raspRule, reason) {
92
+ const tags = { reason, rule_type: raspRule.type }
93
+
94
+ if (raspRule.variant) {
95
+ tags.rule_variant = raspRule.variant
96
+ }
97
+
98
+ appsecMetrics.count('rasp.rule.skipped', tags).inc(1)
99
+ }
100
+
101
+ function getRuleMatchBlockingStatus (blockTriggered, blocked) {
102
+ if (!blockTriggered) {
103
+ return BLOCKING_STATUS.IRRELEVANT
44
104
  }
105
+
106
+ return blocked ? BLOCKING_STATUS.SUCCESS : BLOCKING_STATUS.FAILURE
45
107
  }
46
108
 
47
109
  module.exports = {
48
110
  addRaspRequestMetrics,
49
- trackRaspMetrics
111
+ trackRaspMetrics,
112
+ trackRaspRuleMatch,
113
+ trackRaspRuleSkipped
50
114
  }