pinata-security-cli 0.5.3 → 0.6.1

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 (31) hide show
  1. package/README.md +39 -2
  2. package/dist/cli/index.js +2423 -1909
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/index.d.ts +40 -1
  5. package/dist/index.js +10 -3
  6. package/dist/index.js.map +1 -1
  7. package/package.json +8 -1
  8. package/src/categories/definitions/concurrency/idempotency-missing.yml +5 -5
  9. package/src/categories/definitions/concurrency/race-condition.yml +2 -2
  10. package/src/categories/definitions/data/data-race.yml +15 -18
  11. package/src/categories/definitions/data/encoding-mismatch.yml +4 -4
  12. package/src/categories/definitions/data/null-handling.yml +8 -23
  13. package/src/categories/definitions/input/boundary-testing.yml +12 -40
  14. package/src/categories/definitions/input/injection-fuzzing.yml +19 -0
  15. package/src/categories/definitions/input/null-undefined.yml +11 -39
  16. package/src/categories/definitions/network/connection-failure.yml +9 -3
  17. package/src/categories/definitions/resource/memory-leak.yml +15 -17
  18. package/src/categories/definitions/security/auth-failures.yml +8 -0
  19. package/src/categories/definitions/security/command-injection.yml +17 -0
  20. package/src/categories/definitions/security/csrf.yml +19 -0
  21. package/src/categories/definitions/security/data-exposure.yml +24 -0
  22. package/src/categories/definitions/security/dependency-risks.yml +6 -6
  23. package/src/categories/definitions/security/deserialization.yml +44 -0
  24. package/src/categories/definitions/security/file-upload.yml +39 -0
  25. package/src/categories/definitions/security/ldap-injection.yml +23 -0
  26. package/src/categories/definitions/security/path-traversal.yml +13 -0
  27. package/src/categories/definitions/security/prompt-injection.yml +14 -0
  28. package/src/categories/definitions/security/sql-injection.yml +30 -0
  29. package/src/categories/definitions/security/ssrf.yml +60 -0
  30. package/src/categories/definitions/security/xss.yml +36 -0
  31. package/src/categories/definitions/security/xxe.yml +32 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinata-security-cli",
3
- "version": "0.5.3",
3
+ "version": "0.6.1",
4
4
  "description": "AI-powered test coverage analysis and generation tool. Find security blind spots before attackers do.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -75,17 +75,24 @@
75
75
  },
76
76
  "devDependencies": {
77
77
  "@eslint/js": "^9.39.2",
78
+ "@stryker-mutator/core": "^9.5.1",
79
+ "@stryker-mutator/typescript-checker": "^9.5.1",
80
+ "@stryker-mutator/vitest-runner": "^9.5.1",
81
+ "@types/express": "^5.0.6",
78
82
  "@types/js-yaml": "^4.0.9",
79
83
  "@types/minimatch": "^5.1.2",
80
84
  "@types/node": "^20.14.10",
85
+ "@types/supertest": "^7.2.0",
81
86
  "@typescript-eslint/eslint-plugin": "^7.16.0",
82
87
  "@typescript-eslint/parser": "^7.16.0",
83
88
  "@vitest/coverage-v8": "^4.0.18",
84
89
  "eslint": "^8.57.1",
85
90
  "eslint-config-prettier": "^9.1.0",
86
91
  "eslint-plugin-import": "^2.29.1",
92
+ "express": "^5.2.1",
87
93
  "fast-check": "^4.5.3",
88
94
  "prettier": "^3.3.3",
95
+ "supertest": "^7.2.2",
89
96
  "tsup": "^8.1.0",
90
97
  "tsx": "^4.21.0",
91
98
  "typescript": "^5.5.3",
@@ -35,8 +35,8 @@ detectionPatterns:
35
35
  type: regex
36
36
  language: python
37
37
  pattern: "\\+=\\s*1|counter\\s*\\+|increment\\("
38
- confidence: low
39
- description: Detects counter increments (verify idempotency)
38
+ confidence: medium
39
+ description: Detects counter increments (may need idempotency guards in retry contexts)
40
40
 
41
41
  - id: python-payment-no-idem
42
42
  type: regex
@@ -69,9 +69,9 @@ detectionPatterns:
69
69
  - id: ts-counter-update
70
70
  type: regex
71
71
  language: typescript
72
- pattern: "\\+\\+|\\+=\\s*1|\\$inc"
73
- confidence: low
74
- description: Detects counter updates (verify idempotency)
72
+ pattern: "\\$inc|\\$push(?!.*idempotency|.*idempotent)"
73
+ confidence: medium
74
+ description: Detects MongoDB counter/array updates without idempotency
75
75
 
76
76
  - id: ts-webhook-no-dedup
77
77
  type: regex
@@ -65,9 +65,9 @@ detectionPatterns:
65
65
  - id: ts-check-then-act
66
66
  type: regex
67
67
  language: typescript
68
- pattern: "if\\s*\\(.*exists.*\\).*\\{.*create|if\\s*\\(!.*\\).*\\{"
68
+ pattern: "if\\s*\\(.*exists.*\\).*\\{.*(create|write|mkdir|insert)|if\\s*\\(!.*exists.*\\).*\\{.*(create|write|mkdir|insert)"
69
69
  confidence: medium
70
- description: Detects check-then-act pattern
70
+ description: Detects check-then-act TOCTOU pattern (check existence then create)
71
71
 
72
72
  - id: ts-promise-race-unsafe
73
73
  type: regex
@@ -28,19 +28,12 @@ detectionPatterns:
28
28
  confidence: medium
29
29
  description: Detects mutable global state
30
30
 
31
- - id: python-read-modify-write
31
+ - id: python-thread-no-lock
32
32
  type: regex
33
33
  language: python
34
- pattern: "\\w+\\s*\\+=|\\w+\\s*-=|\\w+\\s*=\\s*\\w+\\s*\\+\\s*1"
35
- confidence: low
36
- description: Detects increment/decrement (may need locking)
37
-
38
- - id: python-no-lock
39
- type: regex
40
- language: python
41
- pattern: "threading\\.Thread|multiprocessing\\.Process"
42
- confidence: low
43
- description: Detects threading (verify locking)
34
+ pattern: "threading\\.Thread.*(?!Lock\\(|RLock\\(|Semaphore\\()"
35
+ confidence: medium
36
+ description: Detects thread creation without visible locking in same scope
44
37
  negativePattern: "Lock\\(|RLock\\(|Semaphore\\("
45
38
 
46
39
  - id: python-check-then-act
@@ -50,12 +43,12 @@ detectionPatterns:
50
43
  confidence: medium
51
44
  description: Detects check-then-act pattern (TOCTOU)
52
45
 
53
- - id: ts-shared-variable
46
+ - id: ts-var-declaration
54
47
  type: regex
55
48
  language: typescript
56
- pattern: "let\\s+\\w+\\s*=|var\\s+\\w+\\s*="
57
- confidence: low
58
- description: Detects mutable shared state (verify thread safety)
49
+ pattern: "\\bvar\\s+\\w+\\s*="
50
+ confidence: medium
51
+ description: Detects var declarations (function-scoped, potential unintended sharing)
59
52
 
60
53
  - id: ts-async-race
61
54
  type: regex
@@ -67,9 +60,13 @@ detectionPatterns:
67
60
  - id: ts-non-atomic-update
68
61
  type: regex
69
62
  language: typescript
70
- pattern: "\\w+\\s*=\\s*\\w+\\s*\\+\\s*1|\\w+\\+\\+"
71
- confidence: low
72
- description: Detects non-atomic increment
63
+ pattern: "await.*\\w+\\s*=\\s*\\w+\\s*\\+\\s*1|await.*\\w+\\+\\+|\\w+\\+\\+.*await"
64
+ confidence: medium
65
+ description: Detects non-atomic increment in async context (potential race condition)
66
+ sources:
67
+ - "\\basync\\b"
68
+ - "\\bawait\\b"
69
+ - "\\bPromise\\b"
73
70
 
74
71
  - id: ts-database-upsert
75
72
  type: regex
@@ -56,7 +56,7 @@ detectionPatterns:
56
56
  type: regex
57
57
  language: typescript
58
58
  pattern: "new TextDecoder\\(\\)|TextDecoder\\(\\)"
59
- confidence: low
59
+ confidence: medium
60
60
  description: Detects TextDecoder without explicit encoding
61
61
 
62
62
  - id: ts-buffer-tostring-default
@@ -76,9 +76,9 @@ detectionPatterns:
76
76
  - id: ts-length-emoji
77
77
  type: regex
78
78
  language: typescript
79
- pattern: "\\.length(?!\\s*[=!<>])"
80
- confidence: low
81
- description: Detects string length (verify emoji handling)
79
+ pattern: "\\.length\\s*[<>]=?\\s*\\d+.*\\.charAt|\\.length.*\\.charCodeAt|\\.split\\(.*\\)\\.length"
80
+ confidence: medium
81
+ description: Detects string length used with char operations (may be wrong for emoji)
82
82
  negativePattern: "\\[\\.\\.\\.\\w+\\]\\.length|Array\\.from\\("
83
83
 
84
84
  testTemplates:
@@ -41,12 +41,12 @@ detectionPatterns:
41
41
  confidence: high
42
42
  description: Detects arithmetic with potential None values
43
43
 
44
- - id: python-json-null
44
+ - id: python-json-no-default
45
45
  type: regex
46
46
  language: python
47
- pattern: "json\\.loads|json\\.load"
48
- confidence: low
49
- description: Detects JSON parsing (verify null handling)
47
+ pattern: "json\\.loads?\\(.*\\)\\[|json\\.loads?\\(.*\\)\\."
48
+ confidence: medium
49
+ description: Detects JSON parse result accessed without null check
50
50
  negativePattern: "or\\s+\\{\\}|or\\s+\\[\\]|\\.get\\("
51
51
 
52
52
  - id: ts-null-vs-undefined
@@ -56,27 +56,12 @@ detectionPatterns:
56
56
  confidence: medium
57
57
  description: Detects checking only null or undefined, not both
58
58
 
59
- - id: ts-optional-chain-missing
60
- type: regex
61
- language: typescript
62
- pattern: "\\w+\\.\\w+\\.\\w+(?!\\.?)"
63
- confidence: low
64
- description: Detects deep property access without optional chaining
65
- negativePattern: "\\?\\."
66
-
67
- - id: ts-nullable-db-field
59
+ - id: ts-json-parse-no-try
68
60
  type: regex
69
61
  language: typescript
70
- pattern: "String\\s*\\|\\s*null|number\\s*\\|\\s*null"
71
- confidence: low
72
- description: Detects nullable types (verify null handling)
73
-
74
- - id: ts-json-parse-null
75
- type: regex
76
- language: typescript
77
- pattern: "JSON\\.parse\\s*\\("
78
- confidence: low
79
- description: Detects JSON parsing (verify null handling)
62
+ pattern: "JSON\\.parse\\s*\\((?!.*try|.*catch)"
63
+ confidence: medium
64
+ description: Detects JSON.parse without visible error handling
80
65
 
81
66
  testTemplates:
82
67
  - id: pytest-null-handling
@@ -21,54 +21,26 @@ references:
21
21
  - https://en.wikipedia.org/wiki/Boundary_testing
22
22
 
23
23
  detectionPatterns:
24
- - id: python-range-access
24
+ - id: python-unchecked-index-user-input
25
25
  type: regex
26
26
  language: python
27
- pattern: "\\[\\w+\\]|\\[\\w+\\s*-\\s*1\\]|\\[\\w+\\s*\\+\\s*1\\]"
28
- confidence: low
29
- description: Detects array index access (verify boundary checks)
30
-
31
- - id: python-comparison-boundary
32
- type: regex
33
- language: python
34
- pattern: "if\\s+\\w+\\s*[<>]=?\\s*\\d+|if\\s+\\d+\\s*[<>]=?\\s*\\w+"
35
- confidence: low
36
- description: Detects numeric comparisons (verify off-by-one)
37
-
38
- - id: python-slice-operation
39
- type: regex
40
- language: python
41
- pattern: "\\[:\\d+\\]|\\[\\d+:\\]|\\[-\\d+:\\]"
42
- confidence: low
43
- description: Detects slice operations (verify bounds)
44
-
45
- - id: python-loop-range
46
- type: regex
47
- language: python
48
- pattern: "for\\s+\\w+\\s+in\\s+range\\("
49
- confidence: low
50
- description: Detects range loops (verify inclusive/exclusive)
51
-
52
- - id: ts-array-access
53
- type: regex
54
- language: typescript
55
- pattern: "\\[\\w+\\]|\\[\\.length\\s*-\\s*1\\]"
56
- confidence: low
57
- description: Detects array index access
27
+ pattern: "\\w+\\[\\s*(request\\.|params\\.|args\\.|input)"
28
+ confidence: medium
29
+ description: Detects array indexing with user-controlled input without bounds check
58
30
 
59
- - id: ts-comparison-boundary
31
+ - id: ts-unchecked-index-user-input
60
32
  type: regex
61
33
  language: typescript
62
- pattern: "if\\s*\\(.*[<>]=?\\s*\\d+|\\w+\\s*[<>]=?\\s*\\w+\\.length"
63
- confidence: low
64
- description: Detects numeric/length comparisons
34
+ pattern: "\\w+\\[\\s*(req\\.|params\\.|query\\.|body\\.|input)"
35
+ confidence: medium
36
+ description: Detects array indexing with user-controlled input without bounds check
65
37
 
66
- - id: ts-substring
38
+ - id: python-no-length-check-slice
67
39
  type: regex
68
- language: typescript
69
- pattern: "\\.substring\\s*\\(|\\.slice\\s*\\(|\\.substr\\s*\\("
40
+ language: python
41
+ pattern: "\\w+\\[.*:\\s*\\]\\s*(?!.*(?:len|if|assert))"
70
42
  confidence: low
71
- description: Detects string slicing operations
43
+ description: Detects array slicing without prior length validation that may cause unexpected empty results
72
44
 
73
45
  testTemplates:
74
46
  - id: pytest-boundary-testing
@@ -59,6 +59,12 @@ detectionPatterns:
59
59
  pattern: "eval\\(|new Function\\(|setTimeout\\(.*\\+"
60
60
  confidence: high
61
61
  description: Detects dynamic code evaluation
62
+ sources:
63
+ - "req\\.(body|params|query|headers)"
64
+ - "\\buser[Ii]nput\\b"
65
+ - "searchParams\\.get\\("
66
+ - "\\bprocess\\.argv"
67
+ - "\\breadline"
62
68
 
63
69
  - id: ts-innerhtml-input
64
70
  type: regex
@@ -66,6 +72,19 @@ detectionPatterns:
66
72
  pattern: "\\.innerHTML\\s*=|\\.outerHTML\\s*="
67
73
  confidence: high
68
74
  description: Detects innerHTML assignment
75
+ sources:
76
+ - "req\\.(body|params|query|headers)"
77
+ - "\\buser[Ii]nput\\b"
78
+ - "searchParams\\.get\\("
79
+ - "\\blocation\\.(hash|search|href)"
80
+ - "\\bwindow\\.location"
81
+ - "\\bURLSearchParams"
82
+ sanitizers:
83
+ - "DOMPurify\\.sanitize\\("
84
+ - "escapeHtml\\("
85
+ - "sanitizeHtml\\("
86
+ - "encodeURIComponent\\("
87
+ - "textContent\\s*="
69
88
 
70
89
  - id: ts-template-injection
71
90
  type: regex
@@ -20,54 +20,26 @@ references:
20
20
  - https://cwe.mitre.org/data/definitions/457.html
21
21
 
22
22
  detectionPatterns:
23
- - id: python-no-none-check
23
+ - id: ts-non-null-assertion
24
24
  type: regex
25
- language: python
26
- pattern: "\\w+\\.\\w+(?!.*if.*is\\s+not\\s+None)"
27
- confidence: low
28
- description: Detects attribute access without None check
25
+ language: typescript
26
+ pattern: "\\w+!\\.|\\w+!\\["
27
+ confidence: high
28
+ description: Detects non-null assertion operator (unsafe type narrowing bypass)
29
29
 
30
- - id: python-dict-access-no-get
30
+ - id: python-none-attribute-access
31
31
  type: regex
32
32
  language: python
33
- pattern: "\\w+\\[[\"']\\w+[\"']\\](?!.*\\.get\\()"
33
+ pattern: "(?:return|=)\\s+\\w+\\.\\w+.*(?!.*(?:if|is not None|is None))"
34
34
  confidence: medium
35
- description: Detects dict access that may raise KeyError
35
+ description: Detects attribute access on a variable that may be None without a prior null check
36
36
 
37
- - id: python-optional-no-default
37
+ - id: python-no-default-dict-access
38
38
  type: regex
39
39
  language: python
40
- pattern: "Optional\\[.*\\](?!.*=\\s*None)"
41
- confidence: medium
42
- description: Detects Optional type without default value
43
-
44
- - id: ts-no-null-check
45
- type: regex
46
- language: typescript
47
- pattern: "\\w+\\.\\w+(?!.*\\?\\.|.*&&|.*\\|\\|)"
48
- confidence: low
49
- description: Detects property access without null check
50
-
51
- - id: ts-undefined-equality
52
- type: regex
53
- language: typescript
54
- pattern: "===\\s*undefined(?!.*null)|!==\\s*undefined(?!.*null)"
55
- confidence: medium
56
- description: Detects undefined check without null check
57
-
58
- - id: ts-non-null-assertion
59
- type: regex
60
- language: typescript
61
- pattern: "\\w+!\\.|\\w+!\\["
62
- confidence: high
63
- description: Detects non-null assertion operator
64
-
65
- - id: ts-optional-chaining-missing
66
- type: regex
67
- language: typescript
68
- pattern: "\\w+\\.\\w+\\.\\w+(?!\\?\\.)"
40
+ pattern: "\\w+\\[\\s*['\"]\\w+['\"]\\s*\\](?!.*\\.get)"
69
41
  confidence: low
70
- description: Detects deep access without optional chaining
42
+ description: Detects direct dictionary bracket access without using .get() which raises KeyError on missing keys
71
43
 
72
44
  testTemplates:
73
45
  - id: pytest-null-undefined
@@ -70,9 +70,15 @@ detectionPatterns:
70
70
  - id: ts-no-econnrefused
71
71
  type: regex
72
72
  language: typescript
73
- pattern: "catch\\s*\\([^)]*\\)\\s*\\{(?!.*ECONNREFUSED|.*code)"
74
- confidence: low
75
- description: Detects catch block not checking error codes
73
+ pattern: "(fetch|axios|got|request|http\\.get|https\\.get).*catch\\s*\\([^)]*\\)\\s*\\{(?!.*ECONNREFUSED|.*code|.*retry)"
74
+ confidence: medium
75
+ description: Detects network request catch block not checking error codes
76
+ sources:
77
+ - "\\bfetch\\("
78
+ - "\\baxios\\b"
79
+ - "\\bgot\\("
80
+ - "\\bhttp\\.get\\("
81
+ - "\\bhttps\\.get\\("
76
82
 
77
83
  - id: ts-socket-no-error-event
78
84
  type: regex
@@ -25,19 +25,12 @@ references:
25
25
  - https://developer.chrome.com/docs/devtools/memory-problems/
26
26
 
27
27
  detectionPatterns:
28
- - id: python-cache-no-limit
28
+ - id: python-global-list-append
29
29
  type: regex
30
30
  language: python
31
- pattern: "\\{\\}|dict\\(\\)(?!.*maxsize|.*lru_cache|.*TTLCache)"
32
- confidence: low
33
- description: Detects unbounded dict cache (verify eviction)
34
-
35
- - id: python-list-append-loop
36
- type: regex
37
- language: python
38
- pattern: "while.*\\.append\\(|for.*\\.append\\("
39
- confidence: low
40
- description: Detects list growing in loop (verify bounds)
31
+ pattern: "^\\w+\\s*=\\s*\\[\\].*\\.append\\("
32
+ confidence: medium
33
+ description: Detects module-level list accumulation without bounds
41
34
 
42
35
  - id: python-global-accumulator
43
36
  type: regex
@@ -60,12 +53,12 @@ detectionPatterns:
60
53
  confidence: medium
61
54
  description: Detects potential circular references
62
55
 
63
- - id: ts-cache-no-limit
56
+ - id: ts-module-level-map
64
57
  type: regex
65
58
  language: typescript
66
- pattern: "new\\s+Map\\(\\)|new\\s+Set\\(\\)|\\{\\}\\s*as\\s+Record"
67
- confidence: low
68
- description: Detects unbounded cache structures
59
+ pattern: "^(?:export\\s+)?const\\s+\\w+\\s*=\\s*new\\s+Map\\(\\)"
60
+ confidence: medium
61
+ description: Detects module-level Map without eviction (potential memory leak in long-running servers)
69
62
 
70
63
  - id: ts-event-listener-no-remove
71
64
  type: regex
@@ -84,9 +77,14 @@ detectionPatterns:
84
77
  - id: ts-array-push-unbounded
85
78
  type: regex
86
79
  language: typescript
87
- pattern: "\\.push\\(.*\\)(?!.*slice|.*splice|.*shift|.*length\\s*=)"
80
+ pattern: "\\bmodule\\b.*\\.push\\(|\\bglobal\\b.*\\.push\\(|\\bthis\\.\\w+\\.push\\("
88
81
  confidence: low
89
- description: Detects array growth without bounds
82
+ description: Detects unbounded growth on module/global/instance arrays (potential leak in long-running processes)
83
+ sources:
84
+ - "\\bsetInterval\\("
85
+ - "\\b\\.on\\("
86
+ - "\\bEventEmitter\\b"
87
+ - "\\bserver\\b"
90
88
 
91
89
  testTemplates:
92
90
  - id: pytest-memory-leak
@@ -118,6 +118,14 @@ detectionPatterns:
118
118
  description: |
119
119
  [REVIEW REQUIRED] User ID taken from request parameter.
120
120
  Verify ownership check exists before accessing resources.
121
+ sources:
122
+ - "req\\.(body|params|query|headers)"
123
+ - "searchParams\\.get\\("
124
+ sanitizers:
125
+ - "req\\.user\\.id\\s*===|req\\.user\\.id\\s*=="
126
+ - "ownershipCheck\\(|verifyOwnership\\("
127
+ - "isOwner\\("
128
+ - "req\\.user\\.id\\s*!==.*throw|req\\.user\\.id\\s*!=.*throw"
121
129
 
122
130
  - id: idor-direct-lookup
123
131
  type: regex
@@ -77,6 +77,16 @@ detectionPatterns:
77
77
  pattern: "child_process\\.exec\\s*\\(|exec\\s*\\(`.*\\$\\{"
78
78
  confidence: high
79
79
  description: Detects child_process.exec with potential user input
80
+ sources:
81
+ - "req\\.(body|params|query|headers)"
82
+ - "\\buser[Ii]nput\\b"
83
+ - "searchParams\\.get\\("
84
+ - "\\bprocess\\.argv"
85
+ sanitizers:
86
+ - "\\bexecFile\\("
87
+ - "\\bspawnSync\\(.*\\["
88
+ - "\\bshellEscape\\("
89
+ - "\\bescapeShellArg\\("
80
90
 
81
91
  - id: ts-child-process-spawn-shell
82
92
  type: regex
@@ -84,6 +94,13 @@ detectionPatterns:
84
94
  pattern: "spawn\\s*\\(.*shell:\\s*true"
85
95
  confidence: high
86
96
  description: Detects spawn with shell option enabled
97
+ sources:
98
+ - "req\\.(body|params|query|headers)"
99
+ - "\\buser[Ii]nput\\b"
100
+ - "searchParams\\.get\\("
101
+ sanitizers:
102
+ - "\\bshellEscape\\("
103
+ - "\\bescapeShellArg\\("
87
104
 
88
105
  - id: ts-execsync
89
106
  type: regex
@@ -64,6 +64,16 @@ detectionPatterns:
64
64
  confidence: low
65
65
  description: Detects Express state-changing routes without csrf middleware
66
66
  negativePattern: "csurf|csrf\\(|csrfProtection"
67
+ sources:
68
+ - "req\\.(body|params|query|headers)"
69
+ - "\\buser[Ii]nput\\b"
70
+ sanitizers:
71
+ - "csurf\\("
72
+ - "csrfProtection"
73
+ - "csrf\\("
74
+ - "SameSite=Strict|sameSite:\\s*[\"']strict[\"']"
75
+ - "SameSite=Lax|sameSite:\\s*[\"']lax[\"']"
76
+ - "lusca\\.csrf"
67
77
 
68
78
  - id: ts-fetch-no-credentials
69
79
  type: regex
@@ -72,6 +82,15 @@ detectionPatterns:
72
82
  confidence: low
73
83
  description: Detects fetch with state-changing methods (needs CSRF token)
74
84
  negativePattern: "X-CSRF|csrf|_token"
85
+ sources:
86
+ - "req\\.(body|params|query|headers)"
87
+ - "\\buser[Ii]nput\\b"
88
+ sanitizers:
89
+ - "X-CSRF-Token"
90
+ - "csrf[Tt]oken"
91
+ - "_csrf"
92
+ - "SameSite=Strict|sameSite:\\s*[\"']strict[\"']"
93
+ - "SameSite=Lax|sameSite:\\s*[\"']lax[\"']"
75
94
 
76
95
  - id: ts-axios-no-csrf
77
96
  type: regex
@@ -51,6 +51,13 @@ detectionPatterns:
51
51
  [REVIEW REQUIRED] API returns full user/account object.
52
52
  Verify sensitive fields (password, SSN, etc.) are excluded.
53
53
  negativePattern: "\\.omit\\(|\\.pick\\(|\\.select\\(|exclude|sanitize"
54
+ sanitizers:
55
+ - "\\.select\\("
56
+ - "\\.omit\\("
57
+ - "\\bpick\\("
58
+ - "\\bomit\\("
59
+ - "\\.exclude\\("
60
+ - "\\bsanitize(User|Response)\\("
54
61
 
55
62
  - id: returning-full-object-py
56
63
  type: regex
@@ -79,6 +86,11 @@ detectionPatterns:
79
86
  description: |
80
87
  [REVIEW REQUIRED] SELECT * query on user table.
81
88
  Select only required fields to prevent data leakage.
89
+ sanitizers:
90
+ - "\\.select\\("
91
+ - "SELECT\\s+(id|name|email|username)"
92
+ - "\\.omit\\("
93
+ - "\\bpick\\("
82
94
 
83
95
  # ORM without field selection
84
96
  - id: prisma-findmany-no-select
@@ -89,6 +101,11 @@ detectionPatterns:
89
101
  description: |
90
102
  [REVIEW REQUIRED] Prisma query without select clause.
91
103
  Returns all fields by default.
104
+ sanitizers:
105
+ - "select:"
106
+ - "\\.omit\\("
107
+ - "\\bpick\\("
108
+ - "exclude:"
92
109
 
93
110
  - id: sequelize-findall-no-attributes
94
111
  type: regex
@@ -134,6 +151,13 @@ detectionPatterns:
134
151
  description: |
135
152
  [REVIEW REQUIRED] Spreading user object in response.
136
153
  May include sensitive fields unintentionally.
154
+ sanitizers:
155
+ - "\\.select\\("
156
+ - "\\.omit\\("
157
+ - "\\bpick\\("
158
+ - "\\bomit\\("
159
+ - "\\bexclude\\("
160
+ - "const\\s*\\{\\s*password.*\\}\\s*=.*user"
137
161
 
138
162
  testTemplates:
139
163
  - id: pytest-data-exposure-review
@@ -88,16 +88,16 @@ detectionPatterns:
88
88
  - id: lodash-typosquat
89
89
  type: regex
90
90
  language: typescript
91
- pattern: "(l0dash|lodahs|1odash|lodassh|lodsh)(?![a-z])"
91
+ pattern: "(import|require).*[\"'](l0dash|lodahs|1odash|lodassh|lodsh)[\"']"
92
92
  confidence: high
93
- description: Potential lodash typosquat detected
93
+ description: Potential lodash typosquat in import/require statement
94
94
 
95
95
  - id: express-typosquat
96
96
  type: regex
97
97
  language: typescript
98
- pattern: "(expres(?!s)|expresss|3xpress)(?![a-z])"
98
+ pattern: "(import|require).*[\"'](expres|expresss|3xpress)[\"']"
99
99
  confidence: high
100
- description: Potential express typosquat detected
100
+ description: Potential express typosquat in import/require statement
101
101
 
102
102
  - id: requests-typosquat
103
103
  type: regex
@@ -130,7 +130,7 @@ detectionPatterns:
130
130
  - id: shai-hulud-packages
131
131
  type: regex
132
132
  language: typescript
133
- pattern: "[\"'`](ngx-bootstrap|ng2-file-upload|@ctrl/tinycolor|valor-software/ngx-bootstrap)[\"'`]"
133
+ pattern: "(import|require|from).*[\"'`](ngx-bootstrap|ng2-file-upload|@ctrl/tinycolor)[\"'`]"
134
134
  confidence: high
135
135
  description: |
136
136
  CRITICAL: Package affected by Shai-Hulud supply chain attack (Sep 2025).
@@ -139,7 +139,7 @@ detectionPatterns:
139
139
  - id: compromised-packages-wave2
140
140
  type: regex
141
141
  language: typescript
142
- pattern: "[\"'`](@acitons/artifact|huggingface-cli|react-dom-utils-helper)[\"'`]"
142
+ pattern: "(import|require|from).*[\"'`](@acitons/artifact|huggingface-cli|react-dom-utils-helper)[\"'`]"
143
143
  confidence: high
144
144
  description: |
145
145
  CRITICAL: Known malicious/typosquatted package.