codelaw-rules-security-js 0.3.0__py3-none-any.whl

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 (148) hide show
  1. codelaw_rules_security_js/LICENSE +23 -0
  2. codelaw_rules_security_js/NOTICE +22 -0
  3. codelaw_rules_security_js/README.md +183 -0
  4. codelaw_rules_security_js/codelaw-pack.toml +6 -0
  5. codelaw_rules_security_js/corpus.toml +70 -0
  6. codelaw_rules_security_js/data/sources/browser.json +24 -0
  7. codelaw_rules_security_js/data/sources/express.json +28 -0
  8. codelaw_rules_security_js/data/sources/koa.json +18 -0
  9. codelaw_rules_security_js/data/sources/llm.json +14 -0
  10. codelaw_rules_security_js/data/sources/nextjs.json +13 -0
  11. codelaw_rules_security_js/presets/sec-js/recommended.toml +58 -0
  12. codelaw_rules_security_js/presets/sec-js/strict.toml +15 -0
  13. codelaw_rules_security_js/rules/sec-js/angularjs-sce-disabled.cases.md +129 -0
  14. codelaw_rules_security_js/rules/sec-js/angularjs-sce-disabled.md +132 -0
  15. codelaw_rules_security_js/rules/sec-js/cookie-flags.cases.md +41 -0
  16. codelaw_rules_security_js/rules/sec-js/cookie-flags.md +117 -0
  17. codelaw_rules_security_js/rules/sec-js/express-hardening.cases.md +12 -0
  18. codelaw_rules_security_js/rules/sec-js/express-hardening.md +135 -0
  19. codelaw_rules_security_js/rules/sec-js/express-session-secret.cases.md +21 -0
  20. codelaw_rules_security_js/rules/sec-js/express-session-secret.md +101 -0
  21. codelaw_rules_security_js/rules/sec-js/graphql-hardening.cases.md +21 -0
  22. codelaw_rules_security_js/rules/sec-js/graphql-hardening.md +116 -0
  23. codelaw_rules_security_js/rules/sec-js/helmet-config.cases.md +21 -0
  24. codelaw_rules_security_js/rules/sec-js/helmet-config.md +88 -0
  25. codelaw_rules_security_js/rules/sec-js/jwt-verify.cases.md +41 -0
  26. codelaw_rules_security_js/rules/sec-js/jwt-verify.md +107 -0
  27. codelaw_rules_security_js/rules/sec-js/missing-rate-limit.cases.md +22 -0
  28. codelaw_rules_security_js/rules/sec-js/missing-rate-limit.md +119 -0
  29. codelaw_rules_security_js/rules/sec-js/no-archive-slip.cases.md +11 -0
  30. codelaw_rules_security_js/rules/sec-js/no-archive-slip.md +119 -0
  31. codelaw_rules_security_js/rules/sec-js/no-bad-tag-filter.cases.md +11 -0
  32. codelaw_rules_security_js/rules/sec-js/no-bad-tag-filter.md +85 -0
  33. codelaw_rules_security_js/rules/sec-js/no-biased-random.cases.md +21 -0
  34. codelaw_rules_security_js/rules/sec-js/no-biased-random.md +115 -0
  35. codelaw_rules_security_js/rules/sec-js/no-bidi-characters.cases.md +21 -0
  36. codelaw_rules_security_js/rules/sec-js/no-bidi-characters.md +123 -0
  37. codelaw_rules_security_js/rules/sec-js/no-child-process-shell.cases.md +71 -0
  38. codelaw_rules_security_js/rules/sec-js/no-child-process-shell.md +141 -0
  39. codelaw_rules_security_js/rules/sec-js/no-cleartext-http.cases.md +41 -0
  40. codelaw_rules_security_js/rules/sec-js/no-cleartext-http.md +147 -0
  41. codelaw_rules_security_js/rules/sec-js/no-cors-wildcard-credentials.cases.md +21 -0
  42. codelaw_rules_security_js/rules/sec-js/no-cors-wildcard-credentials.md +92 -0
  43. codelaw_rules_security_js/rules/sec-js/no-csrf-before-method-override.cases.md +12 -0
  44. codelaw_rules_security_js/rules/sec-js/no-csrf-before-method-override.md +128 -0
  45. codelaw_rules_security_js/rules/sec-js/no-dangerously-set-inner-html.cases.md +141 -0
  46. codelaw_rules_security_js/rules/sec-js/no-dangerously-set-inner-html.md +107 -0
  47. codelaw_rules_security_js/rules/sec-js/no-document-cookie-token.cases.md +21 -0
  48. codelaw_rules_security_js/rules/sec-js/no-document-cookie-token.md +89 -0
  49. codelaw_rules_security_js/rules/sec-js/no-dynamic-script-src.cases.md +31 -0
  50. codelaw_rules_security_js/rules/sec-js/no-dynamic-script-src.md +100 -0
  51. codelaw_rules_security_js/rules/sec-js/no-electron-insecure.cases.md +41 -0
  52. codelaw_rules_security_js/rules/sec-js/no-electron-insecure.md +134 -0
  53. codelaw_rules_security_js/rules/sec-js/no-eval.cases.md +52 -0
  54. codelaw_rules_security_js/rules/sec-js/no-eval.md +102 -0
  55. codelaw_rules_security_js/rules/sec-js/no-format-string.cases.md +11 -0
  56. codelaw_rules_security_js/rules/sec-js/no-format-string.md +115 -0
  57. codelaw_rules_security_js/rules/sec-js/no-hardcoded-crypto-key.cases.md +41 -0
  58. codelaw_rules_security_js/rules/sec-js/no-hardcoded-crypto-key.md +96 -0
  59. codelaw_rules_security_js/rules/sec-js/no-hardcoded-secret.cases.md +61 -0
  60. codelaw_rules_security_js/rules/sec-js/no-hardcoded-secret.md +112 -0
  61. codelaw_rules_security_js/rules/sec-js/no-header-injection.cases.md +21 -0
  62. codelaw_rules_security_js/rules/sec-js/no-header-injection.md +95 -0
  63. codelaw_rules_security_js/rules/sec-js/no-incomplete-sanitization.cases.md +41 -0
  64. codelaw_rules_security_js/rules/sec-js/no-incomplete-sanitization.md +113 -0
  65. codelaw_rules_security_js/rules/sec-js/no-incomplete-url-check.cases.md +61 -0
  66. codelaw_rules_security_js/rules/sec-js/no-incomplete-url-check.md +118 -0
  67. codelaw_rules_security_js/rules/sec-js/no-insecure-random.cases.md +51 -0
  68. codelaw_rules_security_js/rules/sec-js/no-insecure-random.md +127 -0
  69. codelaw_rules_security_js/rules/sec-js/no-javascript-url.cases.md +61 -0
  70. codelaw_rules_security_js/rules/sec-js/no-javascript-url.md +102 -0
  71. codelaw_rules_security_js/rules/sec-js/no-jquery-html-sink.cases.md +139 -0
  72. codelaw_rules_security_js/rules/sec-js/no-jquery-html-sink.md +131 -0
  73. codelaw_rules_security_js/rules/sec-js/no-ldap-injection.cases.md +21 -0
  74. codelaw_rules_security_js/rules/sec-js/no-ldap-injection.md +87 -0
  75. codelaw_rules_security_js/rules/sec-js/no-llm-output-to-sink.cases.md +34 -0
  76. codelaw_rules_security_js/rules/sec-js/no-llm-output-to-sink.md +105 -0
  77. codelaw_rules_security_js/rules/sec-js/no-log-injection.cases.md +11 -0
  78. codelaw_rules_security_js/rules/sec-js/no-log-injection.md +113 -0
  79. codelaw_rules_security_js/rules/sec-js/no-mass-assignment.cases.md +51 -0
  80. codelaw_rules_security_js/rules/sec-js/no-mass-assignment.md +100 -0
  81. codelaw_rules_security_js/rules/sec-js/no-new-buffer.cases.md +41 -0
  82. codelaw_rules_security_js/rules/sec-js/no-new-buffer.md +120 -0
  83. codelaw_rules_security_js/rules/sec-js/no-non-literal-fs-filename.cases.md +31 -0
  84. codelaw_rules_security_js/rules/sec-js/no-non-literal-fs-filename.md +151 -0
  85. codelaw_rules_security_js/rules/sec-js/no-non-literal-require.cases.md +41 -0
  86. codelaw_rules_security_js/rules/sec-js/no-non-literal-require.md +88 -0
  87. codelaw_rules_security_js/rules/sec-js/no-nosql-injection.cases.md +41 -0
  88. codelaw_rules_security_js/rules/sec-js/no-nosql-injection.md +114 -0
  89. codelaw_rules_security_js/rules/sec-js/no-open-redirect.cases.md +21 -0
  90. codelaw_rules_security_js/rules/sec-js/no-open-redirect.md +106 -0
  91. codelaw_rules_security_js/rules/sec-js/no-path-traversal.cases.md +54 -0
  92. codelaw_rules_security_js/rules/sec-js/no-path-traversal.md +187 -0
  93. codelaw_rules_security_js/rules/sec-js/no-prompt-injection.cases.md +31 -0
  94. codelaw_rules_security_js/rules/sec-js/no-prompt-injection.md +118 -0
  95. codelaw_rules_security_js/rules/sec-js/no-prototype-pollution.cases.md +41 -0
  96. codelaw_rules_security_js/rules/sec-js/no-prototype-pollution.md +135 -0
  97. codelaw_rules_security_js/rules/sec-js/no-secret-in-log.cases.md +31 -0
  98. codelaw_rules_security_js/rules/sec-js/no-secret-in-log.md +86 -0
  99. codelaw_rules_security_js/rules/sec-js/no-sensitive-get-query.cases.md +21 -0
  100. codelaw_rules_security_js/rules/sec-js/no-sensitive-get-query.md +89 -0
  101. codelaw_rules_security_js/rules/sec-js/no-server-env-in-client.cases.md +42 -0
  102. codelaw_rules_security_js/rules/sec-js/no-server-env-in-client.md +107 -0
  103. codelaw_rules_security_js/rules/sec-js/no-sql-template.cases.md +51 -0
  104. codelaw_rules_security_js/rules/sec-js/no-sql-template.md +112 -0
  105. codelaw_rules_security_js/rules/sec-js/no-ssrf.cases.md +41 -0
  106. codelaw_rules_security_js/rules/sec-js/no-ssrf.md +165 -0
  107. codelaw_rules_security_js/rules/sec-js/no-ssti.cases.md +54 -0
  108. codelaw_rules_security_js/rules/sec-js/no-ssti.md +128 -0
  109. codelaw_rules_security_js/rules/sec-js/no-stack-trace-response.cases.md +41 -0
  110. codelaw_rules_security_js/rules/sec-js/no-stack-trace-response.md +102 -0
  111. codelaw_rules_security_js/rules/sec-js/no-tls-bypass.cases.md +31 -0
  112. codelaw_rules_security_js/rules/sec-js/no-tls-bypass.md +117 -0
  113. codelaw_rules_security_js/rules/sec-js/no-token-in-web-storage.cases.md +41 -0
  114. codelaw_rules_security_js/rules/sec-js/no-token-in-web-storage.md +92 -0
  115. codelaw_rules_security_js/rules/sec-js/no-unsafe-deserialize.cases.md +41 -0
  116. codelaw_rules_security_js/rules/sec-js/no-unsafe-deserialize.md +115 -0
  117. codelaw_rules_security_js/rules/sec-js/no-unsafe-regex.cases.md +41 -0
  118. codelaw_rules_security_js/rules/sec-js/no-unsafe-regex.md +93 -0
  119. codelaw_rules_security_js/rules/sec-js/no-unsanitized-html.cases.md +199 -0
  120. codelaw_rules_security_js/rules/sec-js/no-unsanitized-html.md +143 -0
  121. codelaw_rules_security_js/rules/sec-js/no-unvalidated-dynamic-method.cases.md +34 -0
  122. codelaw_rules_security_js/rules/sec-js/no-unvalidated-dynamic-method.md +94 -0
  123. codelaw_rules_security_js/rules/sec-js/no-user-controlled-auth-bypass.cases.md +11 -0
  124. codelaw_rules_security_js/rules/sec-js/no-user-controlled-auth-bypass.md +102 -0
  125. codelaw_rules_security_js/rules/sec-js/no-weak-cipher.cases.md +41 -0
  126. codelaw_rules_security_js/rules/sec-js/no-weak-cipher.md +95 -0
  127. codelaw_rules_security_js/rules/sec-js/no-weak-hash.cases.md +31 -0
  128. codelaw_rules_security_js/rules/sec-js/no-weak-hash.md +97 -0
  129. codelaw_rules_security_js/rules/sec-js/no-weak-key-size.cases.md +31 -0
  130. codelaw_rules_security_js/rules/sec-js/no-weak-key-size.md +117 -0
  131. codelaw_rules_security_js/rules/sec-js/no-window-open-opener.cases.md +31 -0
  132. codelaw_rules_security_js/rules/sec-js/no-window-open-opener.md +115 -0
  133. codelaw_rules_security_js/rules/sec-js/no-xpath-injection.cases.md +21 -0
  134. codelaw_rules_security_js/rules/sec-js/no-xpath-injection.md +95 -0
  135. codelaw_rules_security_js/rules/sec-js/no-xxe.cases.md +21 -0
  136. codelaw_rules_security_js/rules/sec-js/no-xxe.md +124 -0
  137. codelaw_rules_security_js/rules/sec-js/password-hash-effort.cases.md +41 -0
  138. codelaw_rules_security_js/rules/sec-js/password-hash-effort.md +97 -0
  139. codelaw_rules_security_js/rules/sec-js/postmessage-origin.cases.md +41 -0
  140. codelaw_rules_security_js/rules/sec-js/postmessage-origin.md +125 -0
  141. codelaw_rules_security_js/rules/sec-js/timing-safe-compare.cases.md +41 -0
  142. codelaw_rules_security_js/rules/sec-js/timing-safe-compare.md +142 -0
  143. codelaw_rules_security_js/rules/sec-js/upload-limits.cases.md +21 -0
  144. codelaw_rules_security_js/rules/sec-js/upload-limits.md +115 -0
  145. codelaw_rules_security_js-0.3.0.dist-info/METADATA +193 -0
  146. codelaw_rules_security_js-0.3.0.dist-info/RECORD +148 -0
  147. codelaw_rules_security_js-0.3.0.dist-info/WHEEL +4 -0
  148. codelaw_rules_security_js-0.3.0.dist-info/licenses/LICENSE +23 -0
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arpit Arya
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ SPDX-License-Identifier: MIT
@@ -0,0 +1,22 @@
1
+ @codelaw/rules-security-js · codelaw-rules-security-js
2
+
3
+ Every rule in this pack is written for codelaw. Rules whose `ported_from:` names a
4
+ source reimplement the documented behaviour of that rule; no source code, pattern or
5
+ documentation text is copied:
6
+
7
+ - eslint-plugin-security (Apache-2.0): detect-buffer-noassert, detect-child-process,
8
+ detect-eval-with-expression, detect-new-buffer, detect-non-literal-fs-filename,
9
+ detect-non-literal-regexp, detect-non-literal-require, detect-object-injection,
10
+ detect-possible-timing-attacks, detect-pseudoRandomBytes, detect-unsafe-regex,
11
+ detect-bidi-characters.
12
+ - Bandit (Apache-2.0): B105, B202, B304, B307, B310, B311, B324, B501, B505, B506, B602, B608.
13
+ - Ruff's `S` rules (MIT): S105, S202, S304, S307, S310, S311, S324, S501, S505, S506, S602, S608.
14
+ - ESLint (MIT): no-script-url.
15
+
16
+ data/sources/*.json are request-source lists (`req.query`, `location.hash`, …) written for this
17
+ pack from the frameworks' public documentation (Express, Koa, Next.js, the DOM).
18
+
19
+ Rule sets under a copyleft or source-available licence — eslint-plugin-no-unsanitized
20
+ (MPL-2.0), njsscan (LGPL-3.0), Semgrep's rules (the Semgrep Rules License) — are
21
+ read for ideas only; no text, pattern or code is taken from them (L2). CodeQL's JavaScript
22
+ queries (MIT) and the OWASP cheat sheets were read for ideas; nothing is copied.
@@ -0,0 +1,183 @@
1
+ # `@codelaw/rules-security-js` · `codelaw-rules-security-js`
2
+
3
+ codelaw's JavaScript (Node, the browser, Express) security rules: 66 of them, each mapped to a CWE and an OWASP Top 10:2025 category, each with
4
+ a fix class and examples in all four languages. One of codelaw's first-party rule packs
5
+ ([SR-RULE-PACKS](../../records/0101_rule-packs.md)). The same files ship on npm as `@codelaw/rules-security-js` and on PyPI as
6
+ `codelaw-rules-security-js`: a Python repository with JavaScript in it gets them too.
7
+
8
+ ```toml
9
+ # codelaw.toml
10
+ extends = ["codelaw:js/recommended", "codelaw:sec-js/recommended"]
11
+ preview = true # every rule is `preview` until a corpus run promotes it
12
+ ```
13
+
14
+ `codelaw init` does not add it: a security pack is chosen, not detected. The rules run on JS, JSX, TS and TSX
15
+ files; the TypeScript-only rules (Angular, NestJS, Prisma, typed casts) are in
16
+ [`security-ts`](../security-ts/README.md), which extends this pack.
17
+
18
+ ## Presets
19
+
20
+ <!-- docs-sync:presets -->
21
+
22
+ | preset | rules | ported from |
23
+ |---|---|---|
24
+ | `sec-js/recommended` | 55 | high-confidence rules, at `error` |
25
+ | `sec-js/strict` | 66 | `sec-js/recommended` and the heuristic rules, at `warn` |
26
+
27
+ <!-- /docs-sync:presets -->
28
+
29
+ `recommended` holds the 55 high-confidence rules, at `error`; `strict` adds the 11 heuristic ones, at `warn`, so a team can
30
+ start without noise. 17 rules offer a mechanical fix (`auto` 0, `suggest` 17); the other
31
+ 49 are `manual`, and each names the safe API in its `How to fix` steps, which the `codelaw-fix` skill walks through.
32
+
33
+ ## Rules
34
+
35
+ Every rule carries `security: { cwe, owasp, severity }` ([SR-RULE-FORMAT](../../records/0112_rule-format.md) decision 2a), so
36
+
37
+ - its finding names the CWE (`sec-js/<rule> (CWE-79) …`);
38
+ - `codelaw rules --tag cwe:79` and `--tag owasp:A05` find it, and `codelaw rules --security-coverage` puts it in the OWASP Top 10:2025 matrix;
39
+ - SARIF carries its `security` and `external/cwe/cwe-<n>` tags and a `security-severity` that GitHub code scanning ranks by
40
+ ([SR-CLI-MCP](../../records/0115_cli-and-mcp.md) decision 4).
41
+
42
+ ### Injection and code execution
43
+
44
+ | rule | rule says | CWE | OWASP 2025 | fix | preset |
45
+ |---|---|---|---|---|---|
46
+ | [`sec-js/no-eval`](rules/sec-js/no-eval.md) | No eval, new Function or string timers | 94 | A05 | manual | recommended |
47
+ | [`sec-js/no-child-process-shell`](rules/sec-js/no-child-process-shell.md) | No shell command built from a value | 78 | A05 | manual | recommended |
48
+ | [`sec-js/no-sql-template`](rules/sec-js/no-sql-template.md) | No SQL built from a template or concatenation | 89 | A05 | manual | recommended |
49
+ | [`sec-js/no-nosql-injection`](rules/sec-js/no-nosql-injection.md) | No request object passed straight to a query, no $where | 943 | A05 | manual | recommended |
50
+ | [`sec-js/no-xpath-injection`](rules/sec-js/no-xpath-injection.md) | No XPath built from a template or concatenation | 643 | A05 | manual | recommended |
51
+ | [`sec-js/no-ldap-injection`](rules/sec-js/no-ldap-injection.md) | No LDAP filter built from a template or concatenation | 90 | A05 | manual | recommended |
52
+ | [`sec-js/no-ssti`](rules/sec-js/no-ssti.md) | No template compiled from a request, no template data taken whole from a request | 1336, 73 | A05 | manual | recommended |
53
+ | [`sec-js/no-header-injection`](rules/sec-js/no-header-injection.md) | No response header value taken from a request | 113 | A05 | manual | recommended |
54
+ | [`sec-js/no-log-injection`](rules/sec-js/no-log-injection.md) | No request data written to a log unchanged | 117 | A09 | manual | strict |
55
+ | [`sec-js/no-format-string`](rules/sec-js/no-format-string.md) | No request data as a format string | 134 | A05 | suggest | strict |
56
+ | [`sec-js/no-non-literal-require`](rules/sec-js/no-non-literal-require.md) | No require or import of a computed module name | 829, 95 | A08 | manual | recommended |
57
+ | [`sec-js/no-unvalidated-dynamic-method`](rules/sec-js/no-unvalidated-dynamic-method.md) | No method chosen by a request value | 470 | A05 | manual | recommended |
58
+ | [`sec-js/no-xxe`](rules/sec-js/no-xxe.md) | No XML entity expansion | 611, 776 | A05 | suggest | recommended |
59
+ | [`sec-js/no-unsafe-deserialize`](rules/sec-js/no-unsafe-deserialize.md) | No deserializer that builds objects or runs code | 502 | A08 | suggest | recommended |
60
+ | [`sec-js/no-new-buffer`](rules/sec-js/no-new-buffer.md) | No new Buffer, no noAssert | 119 | A06 | suggest | recommended |
61
+ | [`sec-js/no-unsafe-regex`](rules/sec-js/no-unsafe-regex.md) | No regular expression that can run for ever, no regular expression built from a request | 1333 | A06 | manual | strict |
62
+ | [`sec-js/no-prototype-pollution`](rules/sec-js/no-prototype-pollution.md) | No request value used as a key to write or merge | 1321 | A08 | manual | recommended |
63
+
64
+ ### Cross-site scripting and the browser
65
+
66
+ | rule | rule says | CWE | OWASP 2025 | fix | preset |
67
+ |---|---|---|---|---|---|
68
+ | [`sec-js/no-unsanitized-html`](rules/sec-js/no-unsanitized-html.md) | No HTML written from a value that is not a literal | 79 | A05 | suggest | recommended |
69
+ | [`sec-js/no-dangerously-set-inner-html`](rules/sec-js/no-dangerously-set-inner-html.md) | No dangerouslySetInnerHTML from a value that is not sanitized | 79 | A05 | manual | recommended |
70
+ | [`sec-js/no-javascript-url`](rules/sec-js/no-javascript-url.md) | No javascript: URL, no navigation to a URL taken from the address | 79 | A05 | manual | recommended |
71
+ | [`sec-js/postmessage-origin`](rules/sec-js/postmessage-origin.md) | postMessage names its target, a message handler checks the sender | 346 | A01 | manual | recommended |
72
+ | [`sec-js/no-jquery-html-sink`](rules/sec-js/no-jquery-html-sink.md) | No jQuery call that parses a built string as HTML | 79 | A05 | manual | recommended |
73
+ | [`sec-js/no-window-open-opener`](rules/sec-js/no-window-open-opener.md) | No window.open without noopener | 1022 | A05 | suggest | recommended |
74
+ | [`sec-js/no-dynamic-script-src`](rules/sec-js/no-dynamic-script-src.md) | No script or frame source taken from a value that is not a literal | 829 | A08 | manual | recommended |
75
+ | [`sec-js/no-incomplete-url-check`](rules/sec-js/no-incomplete-url-check.md) | No URL checked with a substring test | 20 | A01 | manual | recommended |
76
+ | [`sec-js/no-incomplete-sanitization`](rules/sec-js/no-incomplete-sanitization.md) | No escaping that stops at the first match, no one-pass stripping | 116 | A05 | suggest | recommended |
77
+ | [`sec-js/no-bad-tag-filter`](rules/sec-js/no-bad-tag-filter.md) | No regular expression that filters HTML tags | 116, 185 | A05 | manual | recommended |
78
+ | [`sec-js/angularjs-sce-disabled`](rules/sec-js/angularjs-sce-disabled.md) | No AngularJS strict contextual escaping switched off | 79 | A05 | manual | strict |
79
+ | [`sec-js/no-bidi-characters`](rules/sec-js/no-bidi-characters.md) | No hidden bidirectional control characters in code | — | A08 | suggest | recommended |
80
+ | [`sec-js/no-document-cookie-token`](rules/sec-js/no-document-cookie-token.md) | No token or session written to document.cookie | 1004 | A07 | manual | recommended |
81
+ | [`sec-js/no-token-in-web-storage`](rules/sec-js/no-token-in-web-storage.md) | No token kept in localStorage or sessionStorage | 922 | A07 | manual | recommended |
82
+ | [`sec-js/no-server-env-in-client`](rules/sec-js/no-server-env-in-client.md) | No server environment variable in a client component, no secret in a public one | 200 | A02 | manual | recommended |
83
+ | [`sec-js/no-electron-insecure`](rules/sec-js/no-electron-insecure.md) | No insecure Electron window setting | 79, 829 | A02 | suggest | recommended |
84
+
85
+ ### Access, requests and the server
86
+
87
+ | rule | rule says | CWE | OWASP 2025 | fix | preset |
88
+ |---|---|---|---|---|---|
89
+ | [`sec-js/no-path-traversal`](rules/sec-js/no-path-traversal.md) | No file path taken from a request | 22 | A01 | manual | recommended |
90
+ | [`sec-js/no-archive-slip`](rules/sec-js/no-archive-slip.md) | No archive entry name written to disk unchecked | 22 | A01 | manual | recommended |
91
+ | [`sec-js/no-open-redirect`](rules/sec-js/no-open-redirect.md) | No redirect to an address taken from a request | 601 | A01 | manual | recommended |
92
+ | [`sec-js/no-ssrf`](rules/sec-js/no-ssrf.md) | No request made to an address taken from a request | 918 | A01 | manual | recommended |
93
+ | [`sec-js/no-tls-bypass`](rules/sec-js/no-tls-bypass.md) | No switching off of certificate checks | 295 | A04 | suggest | recommended |
94
+ | [`sec-js/no-cleartext-http`](rules/sec-js/no-cleartext-http.md) | No request made over http:// | 319 | A04 | manual | recommended |
95
+ | [`sec-js/no-cors-wildcard-credentials`](rules/sec-js/no-cors-wildcard-credentials.md) | No CORS that allows every origin together with credentials | 942 | A02 | manual | recommended |
96
+ | [`sec-js/express-hardening`](rules/sec-js/express-hardening.md) | An Express app turns off x-powered-by or uses helmet | 200 | A02 | suggest | strict |
97
+ | [`sec-js/helmet-config`](rules/sec-js/helmet-config.md) | helmet is not given false for a header it sets | 693 | A02 | manual | recommended |
98
+ | [`sec-js/cookie-flags`](rules/sec-js/cookie-flags.md) | A cookie sets httpOnly, secure and sameSite | 614, 1004 | A02 | suggest | recommended |
99
+ | [`sec-js/express-session-secret`](rules/sec-js/express-session-secret.md) | express-session has a secret from the environment and a secure cookie | 798, 614 | A07 | manual | recommended |
100
+ | [`sec-js/no-csrf-before-method-override`](rules/sec-js/no-csrf-before-method-override.md) | No method-override before the CSRF check | 352 | A01 | suggest | recommended |
101
+ | [`sec-js/missing-rate-limit`](rules/sec-js/missing-rate-limit.md) | A login or reset route has a rate limit | 770, 307 | A07 | manual | strict |
102
+ | [`sec-js/no-sensitive-get-query`](rules/sec-js/no-sensitive-get-query.md) | No password, token or secret read from the query string | 598 | A04 | manual | recommended |
103
+ | [`sec-js/no-mass-assignment`](rules/sec-js/no-mass-assignment.md) | No request body written straight into a model | 915 | A01 | manual | recommended |
104
+ | [`sec-js/no-user-controlled-auth-bypass`](rules/sec-js/no-user-controlled-auth-bypass.md) | No privileged branch decided by a request value | 807 | A01 | manual | strict |
105
+ | [`sec-js/upload-limits`](rules/sec-js/upload-limits.md) | multer has size limits and a file filter | 434, 770 | A06 | manual | recommended |
106
+ | [`sec-js/graphql-hardening`](rules/sec-js/graphql-hardening.md) | A GraphQL server limits query depth and cost, and hides introspection | 200, 770 | A02 | manual | strict |
107
+ | [`sec-js/no-non-literal-fs-filename`](rules/sec-js/no-non-literal-fs-filename.md) | No file path that is not a literal | 22 | A01 | manual | strict |
108
+ | [`sec-js/no-stack-trace-response`](rules/sec-js/no-stack-trace-response.md) | No error object or stack trace in a response | 209 | A10 | manual | recommended |
109
+
110
+ ### Cryptography, secrets and models
111
+
112
+ | rule | rule says | CWE | OWASP 2025 | fix | preset |
113
+ |---|---|---|---|---|---|
114
+ | [`sec-js/no-weak-hash`](rules/sec-js/no-weak-hash.md) | No MD5 or SHA-1 | 327 | A04 | manual | recommended |
115
+ | [`sec-js/no-weak-cipher`](rules/sec-js/no-weak-cipher.md) | No createCipher, no DES, RC4, Blowfish or ECB | 327 | A04 | manual | recommended |
116
+ | [`sec-js/no-weak-key-size`](rules/sec-js/no-weak-key-size.md) | No short RSA key, no weak elliptic curve | 326 | A04 | suggest | recommended |
117
+ | [`sec-js/no-hardcoded-crypto-key`](rules/sec-js/no-hardcoded-crypto-key.md) | No key or IV written into the source | 321, 329 | A04 | manual | recommended |
118
+ | [`sec-js/no-biased-random`](rules/sec-js/no-biased-random.md) | No byte taken modulo a number that does not divide 256 | 327 | A04 | suggest | recommended |
119
+ | [`sec-js/no-insecure-random`](rules/sec-js/no-insecure-random.md) | No Math.random for a token, a secret or a password | 338 | A04 | suggest | recommended |
120
+ | [`sec-js/password-hash-effort`](rules/sec-js/password-hash-effort.md) | A password is stored with a slow, salted hash | 916 | A04 | manual | recommended |
121
+ | [`sec-js/no-hardcoded-secret`](rules/sec-js/no-hardcoded-secret.md) | No secret written into the source | 798 | A07 | manual | recommended |
122
+ | [`sec-js/timing-safe-compare`](rules/sec-js/timing-safe-compare.md) | A token, hash or signature is compared in constant time | 208 | A07 | suggest | strict |
123
+ | [`sec-js/jwt-verify`](rules/sec-js/jwt-verify.md) | A JWT is verified with a named algorithm, never `none` | 347 | A07 | manual | recommended |
124
+ | [`sec-js/no-secret-in-log`](rules/sec-js/no-secret-in-log.md) | No password, token or secret written to a log | 532 | A09 | manual | strict |
125
+ | [`sec-js/no-llm-output-to-sink`](rules/sec-js/no-llm-output-to-sink.md) | No model output run, written as HTML or used as SQL | 94, 79 | A05 | manual | recommended |
126
+ | [`sec-js/no-prompt-injection`](rules/sec-js/no-prompt-injection.md) | No request data in a model's system prompt | 1427 | A05 | manual | recommended |
127
+
128
+ ## How the rules know a value comes from a request
129
+
130
+ Several rules ask whether a sink's argument comes from a request (`sec-js/no-path-traversal`, `no-ssrf`, `no-open-redirect`, `no-ssti`,
131
+ `no-header-injection`, `no-log-injection`, `no-format-string`, `no-unvalidated-dynamic-method`, `no-prototype-pollution`, `no-llm-output-to-sink`,
132
+ `no-prompt-injection`). They use the `from_source:` predicate ([SR-RULE-FORMAT](../../records/0112_rule-format.md) decision 3a). It holds when the
133
+ argument **is** a listed request source (or a method called on one), is built from one by concatenation, interpolation or `?:`, or is a local name
134
+ bound to one **in the same function**, one or more assignments or destructurings away. The sources are in this pack's `data/sources/`:
135
+
136
+ | table | sources |
137
+ |---|---|
138
+ | `sources/express` | `req.body`, `req.query`, `req.params`, `req.headers`, `req.cookies`, `req.url`, … and the same on `request` (Fastify, Hapi) |
139
+ | `sources/koa` | `ctx.request.body`, `ctx.query`, `ctx.params`, `ctx.headers`, `ctx.cookies.get`, … |
140
+ | `sources/nextjs` | `searchParams`, `request.nextUrl.searchParams`, `request.json`, `request.formData`, … |
141
+ | `sources/browser` | `location.hash`, `location.search`, `document.referrer`, `window.name`, `document.cookie`, `event.data`, … |
142
+ | `sources/llm` | `completion.choices`, `response.content`, `message.content`, `result.text`, … (a model SDK's answer) |
143
+
144
+ **`from_source:` is not taint analysis.** It never follows a call (a value passed through any function, a sanitizer or not, stops being a
145
+ source), a return value, a parameter, a closure's outer variable or another file. A rule page that uses it says so. Rules that need to see more
146
+ than one argument position (`path.join(a, b)`) look for a request path in the whole call instead.
147
+ Every other rule fires on a dangerous sink with a value that is not a literal, or on a setting that is unsafe in itself.
148
+
149
+ ## What the rules are not
150
+
151
+ - **Not a scanner for the whole program.** They read one file at a time and one function at a time; a value that crosses a function boundary is not seen.
152
+ - **Not a proof of safety.** A clean run means no known-bad shape was found, not that the code is safe. `strict` rules are heuristics and warn.
153
+ - **Not for generated code or tests without care.** Turn rules off for a folder with an `[[overrides]]` entry in `codelaw.toml`; `sec-js/no-hardcoded-secret` and
154
+ `sec-js/no-insecure-random` fire in test helpers too.
155
+ - **Deviations from the first catalogue (W-54).** `sec-js/no-cleartext-http` is `manual`: an edit primitive cannot rewrite the text inside a URL. `sec-js/no-bidi-characters`
156
+ is `suggest`, not `auto`: only a comment is removed whole, and a string or regular expression with a hidden character is left for you.
157
+ `sec-js/no-prototype-pollution` does not flag a literal `.__proto__` write, only a request value used as a key or merged; `sec-js/no-javascript-url` reads the
158
+ address by its text (`location.hash`, `document.referrer`, …), not through a local name.
159
+
160
+ ## Not ported, and why
161
+
162
+ [eslint-plugin-security](https://github.com/eslint-community/eslint-plugin-security) (Apache-2.0) is the source of the rules whose `ported_from:` names it; this
163
+ table covers each of its rules. Bandit (Apache-2.0) and Ruff's `S` rules (MIT) are named in `ported_from:` the same way.
164
+
165
+ | eslint-plugin-security rule | here | why |
166
+ |---|---|---|
167
+ | `detect-buffer-noassert` | `sec-js/no-new-buffer` | the `noAssert` argument is flagged there |
168
+ | `detect-child-process` | `sec-js/no-child-process-shell` | narrowed: a literal command is fine; `shell: true` is flagged |
169
+ | `detect-disable-mustache-escape` | not ported | the `escapeMarkup = false` switch is of one old template engine; the XSS it allows is flagged where the output is written (`no-unsanitized-html`, `no-ssti`) |
170
+ | `detect-eval-with-expression` | `sec-js/no-eval` | widened to `new Function` and string timers |
171
+ | `detect-new-buffer` | `sec-js/no-new-buffer` | with a suggested fix |
172
+ | `detect-no-csrf-before-method-override` | `sec-js/no-csrf-before-method-override` | with a suggested reorder |
173
+ | `detect-non-literal-fs-filename` | `sec-js/no-path-traversal` (a request value), `sec-js/no-non-literal-fs-filename` (`strict`) | split: the first is precise, the second is the original's breadth |
174
+ | `detect-non-literal-regexp` | `sec-js/no-unsafe-regex` | only a pattern built from a request is flagged |
175
+ | `detect-non-literal-require` | `sec-js/no-non-literal-require` | |
176
+ | `detect-object-injection` | `sec-js/no-unvalidated-dynamic-method`, `sec-js/no-prototype-pollution` | not ported as written: it flags every `obj[key]`, which is most code; only a key a request supplies is flagged |
177
+ | `detect-possible-timing-attacks` | `sec-js/timing-safe-compare` (`strict`) | limited to names that hold a secret, with a suggested fix |
178
+ | `detect-pseudoRandomBytes` | `sec-js/no-insecure-random` | folded in |
179
+ | `detect-unsafe-regex` | `sec-js/no-unsafe-regex` | nested quantifiers in a regular expression literal |
180
+ | `detect-bidi-characters` | `sec-js/no-bidi-characters` | |
181
+
182
+ Read for ideas only, never copied (L2): CodeQL's JavaScript queries (MIT), the OWASP cheat sheets, and — under licences that forbid copying —
183
+ eslint-plugin-no-unsanitized (MPL-2.0), njsscan (LGPL-3.0) and Semgrep's rules (the Semgrep Rules License).
@@ -0,0 +1,6 @@
1
+ name = "@codelaw/rules-security-js"
2
+ version = "0.3.0"
3
+ min_codelaw = "0.2.0"
4
+ languages = ["javascript", "jsx", "typescript", "tsx"]
5
+ presets = ["sec-js/recommended", "sec-js/strict"]
6
+ description = "codelaw's security rules for JavaScript and JSX, and the TypeScript that runs them: CWE and OWASP Top 10:2025 mapped (SR-RULE-PACKS)"
@@ -0,0 +1,70 @@
1
+ # `codelaw test --corpus` finding counts (SR-RULE-AUTHORING decision 4).
2
+ # Rewrite with --update-snapshot, and review the change.
3
+
4
+ [findings]
5
+ "sec-js/angularjs-sce-disabled" = 0
6
+ "sec-js/cookie-flags" = 0
7
+ "sec-js/express-hardening" = 3
8
+ "sec-js/express-session-secret" = 0
9
+ "sec-js/graphql-hardening" = 0
10
+ "sec-js/helmet-config" = 0
11
+ "sec-js/jwt-verify" = 0
12
+ "sec-js/missing-rate-limit" = 0
13
+ "sec-js/no-archive-slip" = 0
14
+ "sec-js/no-bad-tag-filter" = 0
15
+ "sec-js/no-biased-random" = 0
16
+ "sec-js/no-bidi-characters" = 0
17
+ "sec-js/no-child-process-shell" = 0
18
+ "sec-js/no-cleartext-http" = 0
19
+ "sec-js/no-cors-wildcard-credentials" = 0
20
+ "sec-js/no-csrf-before-method-override" = 0
21
+ "sec-js/no-dangerously-set-inner-html" = 0
22
+ "sec-js/no-document-cookie-token" = 0
23
+ "sec-js/no-dynamic-script-src" = 0
24
+ "sec-js/no-electron-insecure" = 0
25
+ "sec-js/no-eval" = 0
26
+ "sec-js/no-format-string" = 0
27
+ "sec-js/no-hardcoded-crypto-key" = 0
28
+ "sec-js/no-hardcoded-secret" = 0
29
+ "sec-js/no-header-injection" = 0
30
+ "sec-js/no-incomplete-sanitization" = 0
31
+ "sec-js/no-incomplete-url-check" = 0
32
+ "sec-js/no-insecure-random" = 1
33
+ "sec-js/no-javascript-url" = 0
34
+ "sec-js/no-jquery-html-sink" = 0
35
+ "sec-js/no-ldap-injection" = 0
36
+ "sec-js/no-llm-output-to-sink" = 0
37
+ "sec-js/no-log-injection" = 0
38
+ "sec-js/no-mass-assignment" = 0
39
+ "sec-js/no-new-buffer" = 0
40
+ "sec-js/no-non-literal-fs-filename" = 9
41
+ "sec-js/no-non-literal-require" = 0
42
+ "sec-js/no-nosql-injection" = 0
43
+ "sec-js/no-open-redirect" = 0
44
+ "sec-js/no-path-traversal" = 0
45
+ "sec-js/no-prompt-injection" = 0
46
+ "sec-js/no-prototype-pollution" = 0
47
+ "sec-js/no-secret-in-log" = 0
48
+ "sec-js/no-sensitive-get-query" = 0
49
+ "sec-js/no-server-env-in-client" = 1
50
+ "sec-js/no-sql-template" = 0
51
+ "sec-js/no-ssrf" = 0
52
+ "sec-js/no-ssti" = 0
53
+ "sec-js/no-stack-trace-response" = 0
54
+ "sec-js/no-tls-bypass" = 0
55
+ "sec-js/no-token-in-web-storage" = 2
56
+ "sec-js/no-unsafe-deserialize" = 0
57
+ "sec-js/no-unsafe-regex" = 0
58
+ "sec-js/no-unsanitized-html" = 0
59
+ "sec-js/no-unvalidated-dynamic-method" = 0
60
+ "sec-js/no-user-controlled-auth-bypass" = 0
61
+ "sec-js/no-weak-cipher" = 0
62
+ "sec-js/no-weak-hash" = 0
63
+ "sec-js/no-weak-key-size" = 0
64
+ "sec-js/no-window-open-opener" = 0
65
+ "sec-js/no-xpath-injection" = 0
66
+ "sec-js/no-xxe" = 0
67
+ "sec-js/password-hash-effort" = 0
68
+ "sec-js/postmessage-origin" = 3
69
+ "sec-js/timing-safe-compare" = 3
70
+ "sec-js/upload-limits" = 0
@@ -0,0 +1,24 @@
1
+ [
2
+ "location.hash",
3
+ "location.search",
4
+ "location.href",
5
+ "location.pathname",
6
+ "document.location.hash",
7
+ "document.location.search",
8
+ "document.location.href",
9
+ "window.location.hash",
10
+ "window.location.search",
11
+ "window.location.href",
12
+ "window.location.pathname",
13
+ "document.URL",
14
+ "document.documentURI",
15
+ "document.baseURI",
16
+ "document.referrer",
17
+ "document.cookie",
18
+ "window.name",
19
+ "event.data",
20
+ "e.data",
21
+ "evt.data",
22
+ "message.data",
23
+ "event.newValue"
24
+ ]
@@ -0,0 +1,28 @@
1
+ [
2
+ "req.body",
3
+ "req.query",
4
+ "req.params",
5
+ "req.headers",
6
+ "req.header",
7
+ "req.get",
8
+ "req.cookies",
9
+ "req.signedCookies",
10
+ "req.url",
11
+ "req.originalUrl",
12
+ "req.path",
13
+ "req.hostname",
14
+ "req.host",
15
+ "req.files",
16
+ "req.file",
17
+ "request.body",
18
+ "request.query",
19
+ "request.params",
20
+ "request.headers",
21
+ "request.header",
22
+ "request.cookies",
23
+ "request.url",
24
+ "request.originalUrl",
25
+ "request.hostname",
26
+ "request.raw.url",
27
+ "request.files"
28
+ ]
@@ -0,0 +1,18 @@
1
+ [
2
+ "ctx.request.body",
3
+ "ctx.request.query",
4
+ "ctx.request.querystring",
5
+ "ctx.request.headers",
6
+ "ctx.request.url",
7
+ "ctx.request.href",
8
+ "ctx.query",
9
+ "ctx.querystring",
10
+ "ctx.params",
11
+ "ctx.headers",
12
+ "ctx.url",
13
+ "ctx.originalUrl",
14
+ "ctx.path",
15
+ "ctx.hostname",
16
+ "ctx.cookies.get",
17
+ "ctx.get"
18
+ ]
@@ -0,0 +1,14 @@
1
+ [
2
+ "completion.choices",
3
+ "chatCompletion.choices",
4
+ "response.choices",
5
+ "completion.content",
6
+ "response.content",
7
+ "message.content",
8
+ "msg.content",
9
+ "completion.text",
10
+ "response.output_text",
11
+ "result.output_text",
12
+ "result.text",
13
+ "result.content"
14
+ ]
@@ -0,0 +1,13 @@
1
+ [
2
+ "searchParams",
3
+ "req.nextUrl.searchParams",
4
+ "request.nextUrl.searchParams",
5
+ "request.nextUrl.pathname",
6
+ "req.nextUrl.pathname",
7
+ "request.formData",
8
+ "request.json",
9
+ "req.json",
10
+ "req.formData",
11
+ "req.query",
12
+ "req.body"
13
+ ]
@@ -0,0 +1,58 @@
1
+ description = "high-confidence security rules for JavaScript, at error"
2
+
3
+ [rules]
4
+ "sec-js/cookie-flags" = "error"
5
+ "sec-js/express-session-secret" = "error"
6
+ "sec-js/helmet-config" = "error"
7
+ "sec-js/jwt-verify" = "error"
8
+ "sec-js/no-archive-slip" = "error"
9
+ "sec-js/no-bad-tag-filter" = "error"
10
+ "sec-js/no-biased-random" = "error"
11
+ "sec-js/no-bidi-characters" = "error"
12
+ "sec-js/no-child-process-shell" = "error"
13
+ "sec-js/no-cleartext-http" = "error"
14
+ "sec-js/no-cors-wildcard-credentials" = "error"
15
+ "sec-js/no-csrf-before-method-override" = "error"
16
+ "sec-js/no-dangerously-set-inner-html" = "error"
17
+ "sec-js/no-document-cookie-token" = "error"
18
+ "sec-js/no-dynamic-script-src" = "error"
19
+ "sec-js/no-electron-insecure" = "error"
20
+ "sec-js/no-eval" = "error"
21
+ "sec-js/no-hardcoded-crypto-key" = "error"
22
+ "sec-js/no-hardcoded-secret" = "error"
23
+ "sec-js/no-header-injection" = "error"
24
+ "sec-js/no-incomplete-sanitization" = "error"
25
+ "sec-js/no-incomplete-url-check" = "error"
26
+ "sec-js/no-insecure-random" = "error"
27
+ "sec-js/no-javascript-url" = "error"
28
+ "sec-js/no-jquery-html-sink" = "error"
29
+ "sec-js/no-ldap-injection" = "error"
30
+ "sec-js/no-llm-output-to-sink" = "error"
31
+ "sec-js/no-mass-assignment" = "error"
32
+ "sec-js/no-new-buffer" = "error"
33
+ "sec-js/no-non-literal-require" = "error"
34
+ "sec-js/no-nosql-injection" = "error"
35
+ "sec-js/no-open-redirect" = "error"
36
+ "sec-js/no-path-traversal" = "error"
37
+ "sec-js/no-prompt-injection" = "error"
38
+ "sec-js/no-prototype-pollution" = "error"
39
+ "sec-js/no-sensitive-get-query" = "error"
40
+ "sec-js/no-server-env-in-client" = "error"
41
+ "sec-js/no-sql-template" = "error"
42
+ "sec-js/no-ssrf" = "error"
43
+ "sec-js/no-ssti" = "error"
44
+ "sec-js/no-stack-trace-response" = "error"
45
+ "sec-js/no-tls-bypass" = "error"
46
+ "sec-js/no-token-in-web-storage" = "error"
47
+ "sec-js/no-unsafe-deserialize" = "error"
48
+ "sec-js/no-unsanitized-html" = "error"
49
+ "sec-js/no-unvalidated-dynamic-method" = "error"
50
+ "sec-js/no-weak-cipher" = "error"
51
+ "sec-js/no-weak-hash" = "error"
52
+ "sec-js/no-weak-key-size" = "error"
53
+ "sec-js/no-window-open-opener" = "error"
54
+ "sec-js/no-xpath-injection" = "error"
55
+ "sec-js/no-xxe" = "error"
56
+ "sec-js/password-hash-effort" = "error"
57
+ "sec-js/postmessage-origin" = "error"
58
+ "sec-js/upload-limits" = "error"
@@ -0,0 +1,15 @@
1
+ description = "sec-js/recommended and the heuristic security rules, at warn"
2
+ extends = ["codelaw:sec-js/recommended"]
3
+
4
+ [rules]
5
+ "sec-js/angularjs-sce-disabled" = "warn"
6
+ "sec-js/express-hardening" = "warn"
7
+ "sec-js/graphql-hardening" = "warn"
8
+ "sec-js/missing-rate-limit" = "warn"
9
+ "sec-js/no-format-string" = "warn"
10
+ "sec-js/no-log-injection" = "warn"
11
+ "sec-js/no-non-literal-fs-filename" = "warn"
12
+ "sec-js/no-secret-in-log" = "warn"
13
+ "sec-js/no-unsafe-regex" = "warn"
14
+ "sec-js/no-user-controlled-auth-bypass" = "warn"
15
+ "sec-js/timing-safe-compare" = "warn"
@@ -0,0 +1,129 @@
1
+ # sec-js/angularjs-sce-disabled — cases
2
+
3
+ ### case: resource whitelist
4
+
5
+ ```js
6
+ $sceDelegateProvider.resourceUrlWhitelist(["**"]);
7
+ ```
8
+
9
+ ```expect
10
+ 1:1 sec-js/angularjs-sce-disabled
11
+ ```
12
+
13
+ ### case: trustAsHtml
14
+
15
+ ```js
16
+ $sce.trustAsHtml(html);
17
+ ```
18
+
19
+ ```expect
20
+ 1:1 sec-js/angularjs-sce-disabled
21
+ ```
22
+
23
+ ### case: href whitelist
24
+
25
+ ```js
26
+ $compileProvider.aHrefSanitizationWhitelist(/./);
27
+ ```
28
+
29
+ ```expect
30
+ 1:1 sec-js/angularjs-sce-disabled
31
+ ```
32
+
33
+ ### case: extend: the project function passes
34
+
35
+ ```js options={"sanitizers":[{"name":"cleanHtml","module":"@acme/security"}]}
36
+ import { cleanHtml } from "@acme/security";
37
+ $sce.trustAsHtml(cleanHtml(x));
38
+ ```
39
+
40
+ ```expect
41
+ (none)
42
+ ```
43
+
44
+ ### case: extend: the built-in DOMPurify still passes
45
+
46
+ ```js options={"sanitizers":[{"name":"cleanHtml","module":"@acme/security"}]}
47
+ import DOMPurify from "dompurify";
48
+ $sce.trustAsHtml(DOMPurify.sanitize(x));
49
+ ```
50
+
51
+ ```expect
52
+ (none)
53
+ ```
54
+
55
+ ### case: replace: the project function passes
56
+
57
+ ```js options={"sanitizers":[{"name":"cleanHtml","module":"@acme/security"}],"sanitizers_mode":"replace"}
58
+ import { cleanHtml } from "@acme/security";
59
+ $sce.trustAsHtml(cleanHtml(x));
60
+ ```
61
+
62
+ ```expect
63
+ (none)
64
+ ```
65
+
66
+ ### case: replace: DOMPurify is reported
67
+
68
+ ```js options={"sanitizers":[{"name":"cleanHtml","module":"@acme/security"}],"sanitizers_mode":"replace"}
69
+ import DOMPurify from "dompurify";
70
+ $sce.trustAsHtml(DOMPurify.sanitize(x));
71
+ ```
72
+
73
+ ```expect
74
+ 2:1 sec-js/angularjs-sce-disabled
75
+ ```
76
+
77
+ ### case: an aliased import passes
78
+
79
+ ```js options={"sanitizers":[{"name":"cleanHtml","module":"@acme/security"}]}
80
+ import { cleanHtml as clean } from "@acme/security";
81
+ $sce.trustAsHtml(clean(x));
82
+ ```
83
+
84
+ ```expect
85
+ (none)
86
+ ```
87
+
88
+ ### case: a same-named local function is reported
89
+
90
+ ```js
91
+ function sanitizeHtml(x) { return x; }
92
+ $sce.trustAsHtml(sanitizeHtml(x));
93
+ ```
94
+
95
+ ```expect
96
+ 2:1 sec-js/angularjs-sce-disabled
97
+ ```
98
+
99
+ ### case: a function of the same name from another module is reported
100
+
101
+ ```js options={"sanitizers":[{"name":"cleanHtml","module":"@acme/security"}]}
102
+ import { cleanHtml } from "left-pad";
103
+ $sce.trustAsHtml(cleanHtml(x));
104
+ ```
105
+
106
+ ```expect
107
+ 2:1 sec-js/angularjs-sce-disabled
108
+ ```
109
+
110
+ ### case: the global DOMPurify passes
111
+
112
+ ```js
113
+ $sce.trustAsHtml(DOMPurify.sanitize(x));
114
+ ```
115
+
116
+ ```expect
117
+ (none)
118
+ ```
119
+
120
+ ### case: the built-in sanitize-html import passes
121
+
122
+ ```js
123
+ import sanitizeHtml from "sanitize-html";
124
+ $sce.trustAsHtml(sanitizeHtml(x));
125
+ ```
126
+
127
+ ```expect
128
+ (none)
129
+ ```