@critiq/rules 0.0.1 → 0.1.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 (204) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +256 -140
  3. package/catalog.yaml +985 -19
  4. package/package.json +7 -1
  5. package/rules/go/go.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  6. package/rules/go/go.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  7. package/rules/go/go.performance.no-unbounded-concurrency.rule.yaml +33 -0
  8. package/rules/go/go.security.echo-sensitive-binding-without-validation.rule.yaml +46 -0
  9. package/rules/go/go.security.echo-unsafe-multipart-upload.rule.yaml +45 -0
  10. package/rules/go/go.security.fiber-sensitive-binding-without-validation.rule.yaml +45 -0
  11. package/rules/go/go.security.fiber-unsafe-multipart-upload.rule.yaml +45 -0
  12. package/rules/go/go.security.gin-sensitive-binding-without-validation.rule.yaml +45 -0
  13. package/rules/go/go.security.gin-trust-all-proxies.rule.yaml +45 -0
  14. package/rules/go/go.security.gin-wildcard-cors-with-credentials.rule.yaml +47 -0
  15. package/rules/go/go.security.net-http-missing-timeouts.rule.yaml +45 -0
  16. package/rules/go/go.security.sensitive-data-egress.rule.yaml +46 -0
  17. package/rules/go/go.security.tar-path-traversal.rule.yaml +45 -0
  18. package/rules/go/go.security.template-unescaped-request-value.rule.yaml +45 -0
  19. package/rules/go/go.testing.real-network-in-unit-test.rule.yaml +33 -0
  20. package/rules/go/go.testing.t-skip-without-ticket-reference.rule.yaml +33 -0
  21. package/rules/go/go.testing.time-sleep-in-unit-test.rule.yaml +33 -0
  22. package/rules/java/java.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  23. package/rules/java/java.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  24. package/rules/java/java.performance.no-unbounded-concurrency.rule.yaml +33 -0
  25. package/rules/java/java.security.android-screenshot-exposure.rule.yaml +35 -0
  26. package/rules/java/java.security.android-world-readable-mode.rule.yaml +35 -0
  27. package/rules/java/java.security.jpa-concatenated-query.rule.yaml +47 -0
  28. package/rules/java/java.security.reflected-output-from-request.rule.yaml +35 -0
  29. package/rules/java/java.security.servlet-insecure-cookie.rule.yaml +35 -0
  30. package/rules/java/java.security.spring-actuator-health-details-always.rule.yaml +40 -0
  31. package/rules/java/java.security.spring-actuator-sensitive-exposure.rule.yaml +40 -0
  32. package/rules/java/java.security.spring-csrf-globally-disabled.rule.yaml +49 -0
  33. package/rules/java/java.security.spring-debug-exposure.rule.yaml +35 -0
  34. package/rules/java/java.security.spring-permit-all-default.rule.yaml +47 -0
  35. package/rules/java/java.security.spring-webmvc-unrestricted-data-binding.rule.yaml +47 -0
  36. package/rules/java/java.security.template-unescaped-user-output.rule.yaml +49 -0
  37. package/rules/java/java.testing.disabled-without-ticket-reference.rule.yaml +33 -0
  38. package/rules/java/java.testing.http-client-in-unit-test.rule.yaml +33 -0
  39. package/rules/java/java.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
  40. package/rules/php/php.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  41. package/rules/php/php.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  42. package/rules/php/php.performance.no-unbounded-concurrency.rule.yaml +33 -0
  43. package/rules/php/php.security.insecure-cors-wildcard-with-credentials.rule.yaml +41 -0
  44. package/rules/php/php.security.insecure-mail-or-file-transport.rule.yaml +41 -0
  45. package/rules/php/php.security.insecure-session-or-cookie-config.rule.yaml +42 -0
  46. package/rules/php/php.security.laravel-sensitive-csrf-exclusion.rule.yaml +42 -0
  47. package/rules/php/php.security.laravel-unsafe-blade-output.rule.yaml +42 -0
  48. package/rules/php/php.security.laravel-unsafe-mass-assignment.rule.yaml +45 -0
  49. package/rules/php/php.security.sensitive-data-egress.rule.yaml +42 -0
  50. package/rules/php/php.security.symfony-csrf-disabled.rule.yaml +42 -0
  51. package/rules/php/php.security.symfony-debug-exposure.rule.yaml +44 -0
  52. package/rules/php/php.security.unsafe-file-upload-handling.rule.yaml +41 -0
  53. package/rules/php/php.security.wordpress-missing-nonce-or-capability.rule.yaml +42 -0
  54. package/rules/php/php.security.wordpress-unprepared-sql.rule.yaml +42 -0
  55. package/rules/php/php.testing.curl-in-unit-test.rule.yaml +33 -0
  56. package/rules/php/php.testing.mark-test-skipped-without-ticket-reference.rule.yaml +33 -0
  57. package/rules/php/php.testing.sleep-in-unit-test.rule.yaml +33 -0
  58. package/rules/python/py.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  59. package/rules/python/py.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  60. package/rules/python/py.performance.no-unbounded-concurrency.rule.yaml +33 -0
  61. package/rules/python/py.security.django-csrf-exempt-state-changing.rule.yaml +46 -0
  62. package/rules/python/py.security.django-missing-csrf-middleware.rule.yaml +47 -0
  63. package/rules/python/py.security.django-unsafe-production-settings.rule.yaml +47 -0
  64. package/rules/python/py.security.drf-allow-any-default.rule.yaml +46 -0
  65. package/rules/python/py.security.drf-allow-any-unsafe-method.rule.yaml +46 -0
  66. package/rules/python/py.security.fastapi-insecure-cors.rule.yaml +43 -0
  67. package/rules/python/py.security.flask-missing-upload-body-limit.rule.yaml +44 -0
  68. package/rules/python/py.security.flask-unsafe-html-output.rule.yaml +44 -0
  69. package/rules/python/py.security.flask-unsafe-upload-filename.rule.yaml +44 -0
  70. package/rules/python/py.testing.pytest-skip-without-ticket-reference.rule.yaml +33 -0
  71. package/rules/python/py.testing.real-network-in-unit-test.rule.yaml +33 -0
  72. package/rules/python/py.testing.time-sleep-in-unit-test.rule.yaml +33 -0
  73. package/rules/ruby/ruby.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  74. package/rules/ruby/ruby.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  75. package/rules/ruby/ruby.performance.no-unbounded-concurrency.rule.yaml +33 -0
  76. package/rules/ruby/ruby.security.rails-csrf-disabled.rule.yaml +45 -0
  77. package/rules/ruby/ruby.security.rails-detailed-exceptions-enabled.rule.yaml +44 -0
  78. package/rules/ruby/ruby.security.rails-open-redirect.rule.yaml +45 -0
  79. package/rules/ruby/ruby.security.rails-unsafe-html-output.rule.yaml +46 -0
  80. package/rules/ruby/ruby.security.rails-unsafe-render.rule.yaml +45 -0
  81. package/rules/ruby/ruby.security.rails-unsafe-session-or-cookie-store.rule.yaml +45 -0
  82. package/rules/ruby/ruby.security.rails-unsafe-strong-parameters.rule.yaml +46 -0
  83. package/rules/ruby/ruby.security.sensitive-data-egress.rule.yaml +45 -0
  84. package/rules/ruby/ruby.security.sidekiq-web-unauthenticated-mount.rule.yaml +45 -0
  85. package/rules/ruby/ruby.testing.focused-example.rule.yaml +33 -0
  86. package/rules/ruby/ruby.testing.pending-without-ticket-reference.rule.yaml +33 -0
  87. package/rules/ruby/ruby.testing.real-network-in-unit-test.rule.yaml +33 -0
  88. package/rules/ruby/ruby.testing.skip-without-ticket-reference.rule.yaml +33 -0
  89. package/rules/ruby/ruby.testing.sleep-in-unit-test.rule.yaml +33 -0
  90. package/rules/rust/rust.performance.no-regex-construction-in-loop.rule.yaml +33 -0
  91. package/rules/rust/rust.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
  92. package/rules/rust/rust.performance.no-unbounded-concurrency.rule.yaml +33 -0
  93. package/rules/rust/rust.security.actix-wildcard-cors-with-credentials.rule.yaml +47 -0
  94. package/rules/rust/rust.security.axum-body-limit-disabled.rule.yaml +45 -0
  95. package/rules/rust/rust.security.axum-insecure-cors-with-credentials.rule.yaml +47 -0
  96. package/rules/rust/rust.security.rocket-panic-prone-request-handler.rule.yaml +45 -0
  97. package/rules/rust/rust.security.rocket-unsafe-template-output.rule.yaml +47 -0
  98. package/rules/rust/rust.security.sqlx-diesel-raw-interpolated-query.rule.yaml +47 -0
  99. package/rules/rust/rust.security.template-unescaped-request-value.rule.yaml +47 -0
  100. package/rules/rust/rust.security.warp-blocking-or-panic-in-async-handler.rule.yaml +45 -0
  101. package/rules/rust/rust.testing.ignore-without-ticket-reference.rule.yaml +33 -0
  102. package/rules/rust/rust.testing.real-network-in-unit-test.rule.yaml +33 -0
  103. package/rules/rust/rust.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
  104. package/rules/shared/security.archive-path-traversal.rule.yaml +41 -0
  105. package/rules/shared/security.external-file-upload.rule.yaml +40 -0
  106. package/rules/shared/security.permissive-file-permissions.rule.yaml +40 -0
  107. package/rules/shared/security.sensitive-data-egress.rule.yaml +36 -0
  108. package/rules/typescript/ts.correctness.assignment-in-condition.rule.yaml +36 -0
  109. package/rules/typescript/ts.correctness.assignment-to-import-binding.rule.yaml +36 -0
  110. package/rules/typescript/ts.correctness.async-promise-executor.rule.yaml +36 -0
  111. package/rules/typescript/ts.correctness.duplicate-function-parameter.rule.yaml +36 -0
  112. package/rules/typescript/ts.correctness.duplicate-import-source.rule.yaml +36 -0
  113. package/rules/typescript/ts.correctness.duplicate-object-key.rule.yaml +36 -0
  114. package/rules/typescript/ts.correctness.duplicate-switch-case.rule.yaml +36 -0
  115. package/rules/typescript/ts.correctness.empty-block-statement.rule.yaml +35 -0
  116. package/rules/typescript/ts.correctness.identical-comparison-operands.rule.yaml +36 -0
  117. package/rules/typescript/ts.correctness.reassign-catch-binding.rule.yaml +35 -0
  118. package/rules/typescript/ts.correctness.regexp-pattern-unusual-control-character.rule.yaml +35 -0
  119. package/rules/typescript/ts.correctness.self-assignment.rule.yaml +36 -0
  120. package/rules/typescript/ts.next.server-action-missing-local-auth.rule.yaml +35 -0
  121. package/rules/typescript/ts.performance.no-array-spread-in-hot-loop.rule.yaml +32 -0
  122. package/rules/typescript/ts.performance.no-cache-miss-from-unstable-key.rule.yaml +32 -0
  123. package/rules/typescript/ts.performance.no-expensive-sort-in-render-path.rule.yaml +32 -0
  124. package/rules/typescript/ts.performance.no-json-parse-stringify-clone.rule.yaml +32 -0
  125. package/rules/typescript/ts.performance.no-large-object-spread-in-loop.rule.yaml +32 -0
  126. package/rules/typescript/ts.performance.no-n-plus-one-await-in-map.rule.yaml +32 -0
  127. package/rules/typescript/ts.performance.no-redundant-network-fetch.rule.yaml +32 -0
  128. package/rules/typescript/ts.performance.no-regex-construction-in-loop.rule.yaml +32 -0
  129. package/rules/typescript/ts.performance.no-sync-fs-in-request-path.rule.yaml +32 -0
  130. package/rules/typescript/ts.performance.no-unbounded-concurrency.rule.yaml +32 -0
  131. package/rules/typescript/ts.quality.no-ambiguous-abbreviations.rule.yaml +27 -0
  132. package/rules/typescript/ts.quality.no-barrel-file-cycle.rule.yaml +27 -0
  133. package/rules/typescript/ts.quality.no-boolean-parameter-trap.rule.yaml +27 -0
  134. package/rules/typescript/ts.quality.no-dead-export.rule.yaml +27 -0
  135. package/rules/typescript/ts.quality.no-hidden-side-effect-import.rule.yaml +27 -0
  136. package/rules/typescript/ts.quality.no-inconsistent-error-shape.rule.yaml +27 -0
  137. package/rules/typescript/ts.quality.no-mixed-abstraction-level.rule.yaml +27 -0
  138. package/rules/typescript/ts.quality.no-primitive-obsession-in-domain-model.rule.yaml +27 -0
  139. package/rules/typescript/ts.quality.no-temporal-coupling.rule.yaml +27 -0
  140. package/rules/typescript/ts.quality.no-wide-public-surface.rule.yaml +27 -0
  141. package/rules/typescript/ts.react.no-accessibility-label-missing.rule.yaml +36 -0
  142. package/rules/typescript/ts.react.no-activedescendant-on-non-focusable-host.rule.yaml +36 -0
  143. package/rules/typescript/ts.react.no-click-without-keyboard-handler.rule.yaml +36 -0
  144. package/rules/typescript/ts.react.no-deprecated-create-factory.rule.yaml +34 -0
  145. package/rules/typescript/ts.react.no-deprecated-react-dom-root-api.rule.yaml +34 -0
  146. package/rules/typescript/ts.react.no-derived-state-from-props.rule.yaml +34 -0
  147. package/rules/typescript/ts.react.no-effect-fetch-without-cancellation.rule.yaml +35 -0
  148. package/rules/typescript/ts.react.no-find-dom-node.rule.yaml +34 -0
  149. package/rules/typescript/ts.react.no-img-missing-alt-text.rule.yaml +36 -0
  150. package/rules/typescript/ts.react.no-index-as-key-in-dynamic-list.rule.yaml +34 -0
  151. package/rules/typescript/ts.react.no-interactive-role-on-static-semantics.rule.yaml +36 -0
  152. package/rules/typescript/ts.react.no-invalid-anchor-href.rule.yaml +36 -0
  153. package/rules/typescript/ts.react.no-keyboard-interaction-without-widget-role.rule.yaml +36 -0
  154. package/rules/typescript/ts.react.no-legacy-lifecycle.rule.yaml +34 -0
  155. package/rules/typescript/ts.react.no-missing-error-boundary.rule.yaml +36 -0
  156. package/rules/typescript/ts.react.no-positive-tabindex.rule.yaml +36 -0
  157. package/rules/typescript/ts.react.no-static-element-with-synthetic-handlers.rule.yaml +36 -0
  158. package/rules/typescript/ts.react.no-string-ref.rule.yaml +34 -0
  159. package/rules/typescript/ts.react.no-uncontrolled-to-controlled-input.rule.yaml +34 -0
  160. package/rules/typescript/ts.react.no-widget-role-without-tabindex.rule.yaml +36 -0
  161. package/rules/typescript/ts.security.ajv-insecure-configuration.rule.yaml +34 -0
  162. package/rules/typescript/ts.security.angular-dom-sanitizer-bypass-untrusted-input.rule.yaml +35 -0
  163. package/rules/typescript/ts.security.apollo-server-csrf-disabled.rule.yaml +36 -0
  164. package/rules/typescript/ts.security.apollo-server-graphql-dev-tooling-exposure.rule.yaml +36 -0
  165. package/rules/typescript/ts.security.apollo-server-introspection-exposure.rule.yaml +35 -0
  166. package/rules/typescript/ts.security.apollo-server-missing-query-limits.rule.yaml +35 -0
  167. package/rules/typescript/ts.security.astro-vite-public-secret-define.rule.yaml +39 -0
  168. package/rules/typescript/ts.security.debug-statement-in-source.rule.yaml +36 -0
  169. package/rules/typescript/ts.security.electron-dangerous-webpreferences.rule.yaml +35 -0
  170. package/rules/typescript/ts.security.electron-insecure-local-state.rule.yaml +35 -0
  171. package/rules/typescript/ts.security.electron-missing-ipc-origin-check.rule.yaml +35 -0
  172. package/rules/typescript/ts.security.electron-shell-open-external-unvalidated.rule.yaml +35 -0
  173. package/rules/typescript/ts.security.express-error-handler-information-disclosure.rule.yaml +35 -0
  174. package/rules/typescript/ts.security.express-static-dotfiles-allow.rule.yaml +35 -0
  175. package/rules/typescript/ts.security.express-unbounded-body-parser.rule.yaml +34 -0
  176. package/rules/typescript/ts.security.express-user-controlled-static-mount.rule.yaml +35 -0
  177. package/rules/typescript/ts.security.fastify-excessive-body-limit.rule.yaml +34 -0
  178. package/rules/typescript/ts.security.fastify-public-bind-without-trust-proxy.rule.yaml +38 -0
  179. package/rules/typescript/ts.security.graphql-upload-without-csrf-guard.rule.yaml +36 -0
  180. package/rules/typescript/ts.security.iframe-missing-sandbox-attribute.rule.yaml +35 -0
  181. package/rules/typescript/ts.security.insecure-content-security-policy-literal.rule.yaml +35 -0
  182. package/rules/typescript/ts.security.insecure-helmet-hardening-options.rule.yaml +36 -0
  183. package/rules/typescript/ts.security.jwt-insecure-signing-algorithm.rule.yaml +35 -0
  184. package/rules/typescript/ts.security.legacy-buffer-constructor.rule.yaml +35 -0
  185. package/rules/typescript/ts.security.log-injection.rule.yaml +36 -0
  186. package/rules/typescript/ts.security.nestjs-helmet-after-route-mount.rule.yaml +34 -0
  187. package/rules/typescript/ts.security.nestjs-missing-global-validation-pipe.rule.yaml +35 -0
  188. package/rules/typescript/ts.security.nestjs-skip-throttle-sensitive-route.rule.yaml +35 -0
  189. package/rules/typescript/ts.security.nestjs-validation-pipe-without-whitelist.rule.yaml +36 -0
  190. package/rules/typescript/ts.security.nuxt-public-runtime-secret.rule.yaml +38 -0
  191. package/rules/typescript/ts.security.open-redirect.rule.yaml +2 -0
  192. package/rules/typescript/ts.security.request-driven-array-index-access.rule.yaml +33 -0
  193. package/rules/typescript/ts.security.sensitive-data-egress.rule.yaml +1 -0
  194. package/rules/typescript/ts.security.ssrf.rule.yaml +1 -0
  195. package/rules/typescript/ts.security.unsafe-dompurify-version.rule.yaml +36 -0
  196. package/rules/typescript/ts.security.unsafe-marked-version.rule.yaml +36 -0
  197. package/rules/typescript/ts.security.xml-parse-string-with-untrusted-input.rule.yaml +35 -0
  198. package/rules/typescript/ts.testing.no-flaky-timer-test.rule.yaml +38 -0
  199. package/rules/typescript/ts.testing.no-focused-test.rule.yaml +34 -0
  200. package/rules/typescript/ts.testing.no-missing-edge-case-tests.rule.yaml +35 -0
  201. package/rules/typescript/ts.testing.no-network-call-in-unit-test.rule.yaml +38 -0
  202. package/rules/typescript/ts.testing.no-skipped-test-without-ticket.rule.yaml +34 -0
  203. package/rules/typescript/ts.testing.no-snapshot-without-intent.rule.yaml +34 -0
  204. package/rules/typescript/ts.testing.no-test-only-code-in-production.rule.yaml +38 -0
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.insecure-content-security-policy-literal
5
+ title: Avoid unsafe Content-Security-Policy literals
6
+ summary: Static CSP header values should not rely on unsafe-inline, unsafe-eval, or unsafe-hashes without nonces.
7
+ rationale: Permissive CSP keywords weaken XSS defenses for every response that carries the header.
8
+ tags:
9
+ - security
10
+ - csp
11
+ - headers
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.insecure-content-security-policy-literal
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: medium
27
+ confidence: 0.8
28
+ tags:
29
+ - security
30
+ - csp
31
+ message:
32
+ title: "Tighten Content-Security-Policy in ${captures.issue.text}"
33
+ summary: "${captures.issue.text} sets a CSP that includes unsafe directives without a nonce-based escape hatch."
34
+ remediation:
35
+ summary: Prefer nonces or hashes, remove unsafe-inline and unsafe-eval, and scope directives to the smallest required surface.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.insecure-helmet-hardening-options
5
+ title: Avoid disabling core Helmet protections
6
+ summary: Helmet should keep nosniff, HSTS, DNS prefetch control, Expect-CT, and referrer policy enabled unless another gateway enforces them.
7
+ rationale: Turning off individual Helmet middlewares removes baseline HTTP hardening that is a high-signal misconfiguration risk.
8
+ tags:
9
+ - security
10
+ - express
11
+ - headers
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.insecure-helmet-hardening-options
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: medium
27
+ confidence: 0.86
28
+ tags:
29
+ - security
30
+ - express
31
+ - headers
32
+ message:
33
+ title: "Review disabled Helmet option in ${captures.issue.text}"
34
+ summary: "${captures.issue.text} disables a Helmet protection that should usually remain enabled."
35
+ remediation:
36
+ summary: Remove false overrides for nosniff, HSTS, DNS prefetch control, Expect-CT, and referrer policy unless a documented compensating control applies.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.jwt-insecure-signing-algorithm
5
+ title: Do not sign JWTs with the none algorithm
6
+ summary: JSON Web Token signing options must not enable the none algorithm.
7
+ rationale: The none algorithm allows tokens to be accepted without verification, defeating authentication.
8
+ tags:
9
+ - security
10
+ - jwt
11
+ - authentication
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: ts.security.jwt-insecure-signing-algorithm
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.authentication
26
+ severity: critical
27
+ confidence: 0.95
28
+ tags:
29
+ - security
30
+ - jwt
31
+ message:
32
+ title: "Remove insecure JWT algorithm from ${captures.issue.text}"
33
+ summary: "${captures.issue.text} is configured with the none algorithm or algorithm list."
34
+ remediation:
35
+ summary: Require asymmetric or HMAC algorithms explicitly and reject none at signing and verification layers.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.legacy-buffer-constructor
5
+ title: Replace legacy Buffer constructors
6
+ summary: Use Buffer.from, Buffer.alloc, or Buffer.allocUnsafe instead of the deprecated Buffer constructor.
7
+ rationale: Legacy constructors behave differently across Node versions and are harder to audit for safe allocation.
8
+ tags:
9
+ - security
10
+ - node
11
+ - memory
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.legacy-buffer-constructor
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: medium
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - node
31
+ message:
32
+ title: "Replace ${captures.issue.text}"
33
+ summary: "${captures.issue.text} uses the deprecated Buffer constructor API."
34
+ remediation:
35
+ summary: Prefer Buffer.from for encoded data and Buffer.alloc for zero-filled buffers sized by trusted logic.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.log-injection
5
+ title: Sanitize user-controlled values before they reach log messages
6
+ summary: Logger calls in pino, winston, bunyan, and consola should not interpolate or concatenate request input directly into the message text.
7
+ rationale: Unsanitized request data in log messages enables CRLF injection, control-character smuggling, and downstream log-parser confusion. Wrapping the value with a structured field, JSON encoder, or CRLF-stripping replace neutralizes the vector.
8
+ tags:
9
+ - security
10
+ - logging
11
+ - input-validation
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.log-injection
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.input-validation
26
+ severity: medium
27
+ confidence: 0.85
28
+ tags:
29
+ - security
30
+ - logging
31
+ - input-validation
32
+ message:
33
+ title: Sanitize user-controlled values before reaching `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` interpolates request data into a log message without an obvious sanitizer."
35
+ remediation:
36
+ summary: Pass request data as a structured field, JSON-encode it, or strip CRLF and control characters before concatenating it into the log message.
@@ -0,0 +1,34 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.nestjs-helmet-after-route-mount
5
+ title: Register Helmet before Nest route mounts
6
+ summary: Nest bootstrap files should apply Helmet before mounting path-bound routers.
7
+ rationale: Middleware order determines whether framed routes inherit Helmet protections; mounting routers too early widens exposure.
8
+ tags:
9
+ - security
10
+ - nestjs
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.nestjs-helmet-after-route-mount
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.misconfiguration
25
+ severity: medium
26
+ confidence: 0.8
27
+ tags:
28
+ - security
29
+ - nestjs
30
+ message:
31
+ title: Move Helmet ahead of routed middleware
32
+ summary: Helmet runs after a route-mounted `app.use` in this Nest bootstrap.
33
+ remediation:
34
+ summary: Call `helmet()` before registering routers bound to external paths unless another gateway applies equivalent protections.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.nestjs-missing-global-validation-pipe
5
+ title: Add a global Nest ValidationPipe
6
+ summary: Nest bootstrap entries should register `ValidationPipe` globally when controllers parse bodies or DTOs.
7
+ rationale: Without a validation pipe unexpected fields can reach controllers and weaken input hygiene.
8
+ tags:
9
+ - security
10
+ - nestjs
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.nestjs-missing-global-validation-pipe
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.misconfiguration
25
+ severity: medium
26
+ confidence: 0.68
27
+ tags:
28
+ - security
29
+ - nestjs
30
+ message:
31
+ title: Register `useGlobalPipes` with ValidationPipe
32
+ summary: Nest bootstrap completes without calling `useGlobalPipes`.
33
+ remediation:
34
+ summary: >-
35
+ Call app.useGlobalPipes with ValidationPipe using whitelist and forbidNonWhitelisted flags near bootstrap completion.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.nestjs-skip-throttle-sensitive-route
5
+ title: Do not skip throttling on credential routes
6
+ summary: Sensitive Nest routes should not disable `@nestjs/throttler` protections without a compensating throttle.
7
+ rationale: Authentication endpoints are brute-force magnets; removing throttling removes basic abuse resistance.
8
+ tags:
9
+ - security
10
+ - nestjs
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.nestjs-skip-throttle-sensitive-route
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.authentication
25
+ severity: medium
26
+ confidence: 0.79
27
+ tags:
28
+ - security
29
+ - nestjs
30
+ - throttling
31
+ message:
32
+ title: Restore throttling for brute-force sensitive handlers
33
+ summary: "`${captures.issue.text}` disables throttling on an authentication-sensitive route."
34
+ remediation:
35
+ summary: Remove `@SkipThrottle()` or pair it with an explicit `@Throttle` policy tuned for the handler.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.nestjs-validation-pipe-without-whitelist
5
+ title: Harden Nest ValidationPipe with whitelist mode
6
+ summary: Global ValidationPipe instances should enable whitelist-style stripping for unexpected fields.
7
+ rationale: Allowing undeclared fields preserves attack surface for mass-assignment style bugs.
8
+ tags:
9
+ - security
10
+ - nestjs
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.nestjs-validation-pipe-without-whitelist
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.misconfiguration
25
+ severity: medium
26
+ confidence: 0.74
27
+ tags:
28
+ - security
29
+ - nestjs
30
+ message:
31
+ title: Enable ValidationPipe whitelist hardening
32
+ summary: >-
33
+ ValidationPipe is configured without literal whitelist true.
34
+ remediation:
35
+ summary: >-
36
+ Enable whitelist true and usually forbidNonWhitelisted true on the global ValidationPipe.
@@ -0,0 +1,38 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.nuxt-public-runtime-secret
5
+ title: Keep secrets out of Nuxt public runtime config
6
+ summary: >-
7
+ Sensitive credentials must not be exposed through runtimeConfig.public, which is visible to client bundles.
8
+ rationale: >-
9
+ Nuxt exposes runtimeConfig.public to the browser; placing secret material there leaks API keys, database passwords, and signing material to every visitor.
10
+ tags:
11
+ - security
12
+ - nuxt
13
+ - rules-catalog
14
+ stability: experimental
15
+ appliesTo: block
16
+ scope:
17
+ languages:
18
+ - typescript
19
+ - javascript
20
+ match:
21
+ fact:
22
+ kind: security.nuxt-public-runtime-secret
23
+ bind: issue
24
+ emit:
25
+ finding:
26
+ category: security.misconfiguration
27
+ severity: high
28
+ confidence: 0.86
29
+ tags:
30
+ - security
31
+ - nuxt
32
+ message:
33
+ title: Move ${captures.issue.text} out of runtimeConfig.public
34
+ summary: >-
35
+ runtimeConfig.public declares ${captures.issue.text}, which looks like a secret or private credential.
36
+ remediation:
37
+ summary: >-
38
+ Keep secrets in the private runtimeConfig tree (non-public) and expose only publishable identifiers to the client after reviewing Nuxt runtime config documentation.
@@ -16,6 +16,8 @@ scope:
16
16
  languages:
17
17
  - typescript
18
18
  - javascript
19
+ - java
20
+ - go
19
21
  match:
20
22
  fact:
21
23
  kind: security.open-redirect
@@ -0,0 +1,33 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.request-driven-array-index-access
5
+ title: Avoid request-driven array indexing without bounds checks
6
+ summary: Arrays indexed with request-derived keys can read or write out-of-bounds entries.
7
+ rationale: Attacker-controlled indexes bypass assumptions about array length and element initialization.
8
+ tags:
9
+ - security
10
+ - correctness
11
+ - rules-catalog
12
+ stability: stable
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.request-driven-array-index-access
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.input-validation
25
+ severity: medium
26
+ confidence: 0.72
27
+ tags:
28
+ - security
29
+ message:
30
+ title: "Validate index ${captures.issue.text} before use"
31
+ summary: "Array access uses a computed index derived from ${captures.issue.text}."
32
+ remediation:
33
+ summary: Parse and bound-check indexes, prefer maps keyed by stable identifiers, or avoid indexing arrays with request data.
@@ -16,6 +16,7 @@ scope:
16
16
  languages:
17
17
  - typescript
18
18
  - javascript
19
+ - java
19
20
  match:
20
21
  fact:
21
22
  kind: security.sensitive-data-egress
@@ -14,6 +14,7 @@ scope:
14
14
  languages:
15
15
  - typescript
16
16
  - javascript
17
+ - go
17
18
  match:
18
19
  fact:
19
20
  kind: security.ssrf
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.unsafe-dompurify-version
5
+ title: Upgrade DOM sanitization dependency
6
+ summary: DOM sanitization libraries should stay on patched versions before they are trusted for untrusted HTML.
7
+ rationale: Older sanitizer versions can miss browser parsing edge cases and leave XSS protections incomplete.
8
+ tags:
9
+ - security
10
+ - dependency
11
+ - xss
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: project
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.dependency.dompurify-unsafe-version
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.dependency
26
+ severity: high
27
+ confidence: 0.82
28
+ tags:
29
+ - security
30
+ - dependency
31
+ - xss
32
+ message:
33
+ title: Upgrade `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` is below the minimum sanitizer version Critiq treats as safe for untrusted HTML."
35
+ remediation:
36
+ summary: Upgrade the package, then keep HTML sanitizer usage behind a small reviewed wrapper.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.unsafe-marked-version
5
+ title: Upgrade Markdown rendering dependency
6
+ summary: Markdown renderers should stay on patched versions before rendering untrusted content.
7
+ rationale: Older Markdown renderer versions can expose unsafe HTML handling and parser edge cases.
8
+ tags:
9
+ - security
10
+ - dependency
11
+ - xss
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: project
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.dependency.marked-unsafe-version
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.dependency
26
+ severity: high
27
+ confidence: 0.82
28
+ tags:
29
+ - security
30
+ - dependency
31
+ - xss
32
+ message:
33
+ title: Upgrade `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` is below the minimum Markdown renderer version Critiq treats as safe for untrusted content."
35
+ remediation:
36
+ summary: Upgrade the package and keep untrusted Markdown rendering behind explicit sanitization.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.xml-parse-string-with-untrusted-input
5
+ title: Do not parse untrusted XML with permissive parsers
6
+ summary: parseString and similar XML helpers should not consume request-controlled payloads without hardening.
7
+ rationale: Untrusted XML can enable XXE-style parser abuse depending on the underlying implementation and parser flags.
8
+ tags:
9
+ - security
10
+ - xml
11
+ - deserialization
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.xml-parse-string-with-untrusted-input
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.deserialization
26
+ severity: high
27
+ confidence: 0.78
28
+ tags:
29
+ - security
30
+ - xml
31
+ message:
32
+ title: "Validate XML parsing for ${captures.issue.text}"
33
+ summary: "${captures.issue.text} parses XML that appears request-driven."
34
+ remediation:
35
+ summary: Disable external entities, validate payloads against a strict schema, and parse with a hardened XML configuration.
@@ -0,0 +1,38 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.testing.no-flaky-timer-test
5
+ title: Prefer fake timers in unit tests
6
+ summary: Real timers, sleeps, or wall-clock reads in unit tests are flaky unless fake timers are enabled for the file.
7
+ rationale: Wall-clock based tests race CI load and parallelization; fake timers keep behavior deterministic.
8
+ tags:
9
+ - testing
10
+ - quality
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ paths:
19
+ exclude:
20
+ - "**/e2e/**"
21
+ - "**/*.integration.test.*"
22
+ match:
23
+ fact:
24
+ kind: testing.flaky-timer-in-test
25
+ bind: issue
26
+ emit:
27
+ finding:
28
+ category: quality.testing
29
+ severity: low
30
+ confidence: 0.68
31
+ tags:
32
+ - testing
33
+ - timers
34
+ message:
35
+ title: Stabilize timer usage in `${captures.issue.text}`
36
+ summary: "`${captures.issue.text}` uses real timers or wall-clock reads without `jest.useFakeTimers` / `vi.useFakeTimers` in the same file."
37
+ remediation:
38
+ summary: Enable fake timers for the suite, inject a clock abstraction, or move timing assertions behind a test double.
@@ -0,0 +1,34 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.testing.no-focused-test
5
+ title: Remove focused or exclusive tests before merge
6
+ summary: Focused tests such as it.only or describe.only should not ship because they silence the rest of the suite in CI.
7
+ rationale: Exclusive tests hide failures in sibling cases and are a common accidental merge footgun.
8
+ tags:
9
+ - testing
10
+ - quality
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: testing.focused-only-invocation
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: quality.testing
25
+ severity: medium
26
+ confidence: 0.88
27
+ tags:
28
+ - testing
29
+ - ci
30
+ message:
31
+ title: Remove focused test `${captures.issue.text}`
32
+ summary: "`${captures.issue.text}` runs in exclusive mode so other tests in the file or suite are skipped."
33
+ remediation:
34
+ summary: Remove `.only` / `fit` / `fdescribe` style exclusivity and rely on the full suite in CI.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.testing.no-missing-edge-case-tests
5
+ title: Update tests when branch-heavy service logic changes
6
+ summary: Diffs that touch many branches in critical service paths should update paired tests in the same change.
7
+ rationale: Branch-heavy edits without test updates often miss boundary and failure behavior reviewers expect.
8
+ tags:
9
+ - testing
10
+ - quality
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: project
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ changedLinesOnly: false
19
+ match:
20
+ fact:
21
+ kind: testing.missing-edge-case-tests-for-changes
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.testing
26
+ severity: medium
27
+ confidence: 0.66
28
+ tags:
29
+ - testing
30
+ - diff
31
+ message:
32
+ title: Exercise new branches in `${captures.issue.text}`
33
+ summary: "`${captures.issue.text}` changes branch-heavy logic on a critical path without a corresponding test file change."
34
+ remediation:
35
+ summary: Extend the paired unit test with cases for new branches, guards, and failure paths touched by the diff.
@@ -0,0 +1,38 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.testing.no-network-call-in-unit-test
5
+ title: Avoid real network calls in unit tests
6
+ summary: Unit tests should not open real sockets; prefer doubles, recordings, or local fakes.
7
+ rationale: Real network calls make tests flaky, slow, and unsafe against live systems.
8
+ tags:
9
+ - testing
10
+ - quality
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ paths:
19
+ exclude:
20
+ - "**/e2e/**"
21
+ - "**/*.integration.test.*"
22
+ match:
23
+ fact:
24
+ kind: testing.real-network-in-unit-test
25
+ bind: issue
26
+ emit:
27
+ finding:
28
+ category: quality.testing
29
+ severity: medium
30
+ confidence: 0.74
31
+ tags:
32
+ - testing
33
+ - network
34
+ message:
35
+ title: Replace live network call `${captures.issue.text}`
36
+ summary: "`${captures.issue.text}` performs an outbound HTTP style call inside a unit test path."
37
+ remediation:
38
+ summary: Mock HTTP clients, use an in-memory server, or relocate the scenario to an explicit integration suite.