@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,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.apollo-server-csrf-disabled
5
+ title: Keep Apollo Server CSRF protections enabled
6
+ summary: Apollo Server should not explicitly disable CSRF prevention for browser-accessible endpoints.
7
+ rationale: GraphQL POST endpoints are vulnerable to cross-site writes when CSRF defenses are turned off.
8
+ tags:
9
+ - security
10
+ - graphql
11
+ - apollo
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.apollo-server-csrf-disabled
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: high
27
+ confidence: 0.88
28
+ tags:
29
+ - security
30
+ - graphql
31
+ message:
32
+ title: Re-enable Apollo Server CSRF prevention
33
+ summary: Apollo Server sets `csrfPrevention` to false.
34
+ remediation:
35
+ summary: >-
36
+ Remove `csrfPrevention: false` or replace it with an equivalent POST-only plus preflight strategy documented by Apollo.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.apollo-server-graphql-dev-tooling-exposure
5
+ title: Avoid shipping GraphQL dev landing or playground plugins without a production guard
6
+ summary: Apollo Server dev landing pages, sandbox UIs, and GraphQL Playground-style plugins should not load unconditionally in production builds.
7
+ rationale: Interactive GraphQL explorers widen attack surface and often expose schema details beyond what production APIs should advertise by default.
8
+ tags:
9
+ - security
10
+ - graphql
11
+ - apollo
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.apollo-server-graphql-dev-tooling-exposure
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: medium
27
+ confidence: 0.78
28
+ tags:
29
+ - security
30
+ - graphql
31
+ message:
32
+ title: Gate GraphQL dev tooling away from production
33
+ summary: Apollo Server registers dev-oriented landing or playground plugins without an obvious environment guard in the same plugin expression.
34
+ remediation:
35
+ summary: >-
36
+ Load sandbox or local landing plugins only outside production, prefer `ApolloServerPluginLandingPageProductionDefault`, or disable interactive explorers behind authentication at the edge.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.apollo-server-introspection-exposure
5
+ title: Avoid unconditional GraphQL introspection
6
+ summary: Apollo Server should not hard-enable introspection without environment guards.
7
+ rationale: Introspection aids attackers in mapping schemas on production deployments.
8
+ tags:
9
+ - security
10
+ - graphql
11
+ - apollo
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.apollo-server-introspection-exposure
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.information-exposure
26
+ severity: medium
27
+ confidence: 0.84
28
+ tags:
29
+ - security
30
+ - graphql
31
+ message:
32
+ title: Gate GraphQL introspection away from production
33
+ summary: Apollo Server enables introspection with a literal `true` flag.
34
+ remediation:
35
+ summary: Bind introspection to non-production environments or protect the endpoint behind authenticated tooling.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.apollo-server-missing-query-limits
5
+ title: Add GraphQL query depth or complexity controls
6
+ summary: Apollo Server bootstrap should declare validation rules or plugins that bound query cost.
7
+ rationale: Without depth, complexity, persisted operations, or gateway limits, GraphQL endpoints are easier to abuse with expensive queries.
8
+ tags:
9
+ - security
10
+ - graphql
11
+ - apollo
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.apollo-server-missing-query-limits
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: medium
27
+ confidence: 0.72
28
+ tags:
29
+ - security
30
+ - graphql
31
+ message:
32
+ title: Layer defenses against expensive GraphQL queries
33
+ summary: Apollo Server is constructed without recognizable validation rules or protective plugins.
34
+ remediation:
35
+ summary: Add depth limits, query complexity rules, persisted operations, rate limits, or terminate behind a gateway/WAF that enforces GraphQL policies.
@@ -0,0 +1,39 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.astro-vite-public-secret-define
5
+ title: Do not inline secrets into Astro PUBLIC import meta defines
6
+ summary: >-
7
+ Astro and Vite define entries for import.meta.env.PUBLIC_* must not map to high-risk process.env secrets.
8
+ rationale: >-
9
+ PUBLIC_* keys are intended for browser-visible configuration; wiring database passwords or API secrets through vite.define exposes them to client bundles.
10
+ tags:
11
+ - security
12
+ - astro
13
+ - vite
14
+ - rules-catalog
15
+ stability: experimental
16
+ appliesTo: block
17
+ scope:
18
+ languages:
19
+ - typescript
20
+ - javascript
21
+ match:
22
+ fact:
23
+ kind: security.astro-vite-public-secret-define
24
+ bind: issue
25
+ emit:
26
+ finding:
27
+ category: security.misconfiguration
28
+ severity: high
29
+ confidence: 0.83
30
+ tags:
31
+ - security
32
+ - astro
33
+ message:
34
+ title: Remove secret process.env wiring from ${captures.issue.text}
35
+ summary: >-
36
+ vite.define maps ${captures.issue.text} to a process.env value that looks like a secret.
37
+ remediation:
38
+ summary: >-
39
+ Keep secrets on the server, use private server-only env vars, and reserve PUBLIC_* keys for intentionally public identifiers such as analytics IDs.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.debug-statement-in-source
5
+ title: "Remove leftover `console.trace` calls from production paths"
6
+ summary: "`console.trace()` calls should not ship in production code outside an explicit dev-only branch."
7
+ rationale: "`console.trace` dumps a stack trace to stdout/stderr and is almost always leftover developer instrumentation. Stack traces in shipped output disclose internal call structure and inflate logs."
8
+ tags:
9
+ - security
10
+ - logging
11
+ - diagnostics
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.debug-statement-in-source
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.privacy
26
+ severity: low
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - logging
31
+ - diagnostics
32
+ message:
33
+ title: Remove `${captures.issue.text}` before shipping
34
+ summary: "`${captures.issue.text}` is leftover developer instrumentation that ships a stack trace to stdout or stderr."
35
+ remediation:
36
+ summary: Remove the call or guard it behind an explicit dev-only check (`process.env.NODE_ENV !== 'production'`, `import.meta.env.DEV`, or `__DEV__`).
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.electron-dangerous-webpreferences
5
+ title: Harden Electron webPreferences
6
+ summary: Electron renderers should not run with unsafe webPreferences that weaken isolation or transport protection.
7
+ rationale: Options such as nodeIntegration, contextIsolation, and webSecurity directly control whether renderer compromise becomes host compromise.
8
+ tags:
9
+ - security
10
+ - electron
11
+ - desktop
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.electron-dangerous-webpreferences
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: high
27
+ confidence: 0.94
28
+ tags:
29
+ - security
30
+ - electron
31
+ message:
32
+ title: "Harden Electron ${captures.issue.text}"
33
+ summary: "${captures.issue.text} weakens Electron renderer isolation or transport protection."
34
+ remediation:
35
+ summary: Keep contextIsolation and webSecurity enabled, disable nodeIntegration and enableRemoteModule, and prefer sandbox true.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.electron-insecure-local-state
5
+ title: Avoid storing secrets in Electron local stores without hardening
6
+ summary: electron-store writes that look like credentials should use OS-level secret storage instead.
7
+ rationale: Local JSON stores are readable by other processes and backups unless encrypted with platform APIs.
8
+ tags:
9
+ - security
10
+ - electron
11
+ - storage
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.electron-insecure-local-state
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.data-exposure
26
+ severity: medium
27
+ confidence: 0.82
28
+ tags:
29
+ - security
30
+ - electron
31
+ message:
32
+ title: "Harden Electron store usage in ${captures.issue.text}"
33
+ summary: "${captures.issue.text} persists sensitive-looking data through electron-store."
34
+ remediation:
35
+ summary: Prefer OS keychains, encrypted vaults, or short-lived session material instead of long-lived plaintext secrets on disk.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.electron-missing-ipc-origin-check
5
+ title: Validate IPC sender origins in Electron
6
+ summary: Privileged ipcMain handlers should validate event.sender origins before acting.
7
+ rationale: Missing origin checks let any loaded renderer invoke privileged main-process behavior.
8
+ tags:
9
+ - security
10
+ - electron
11
+ - ipc
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.electron-missing-ipc-origin-check
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.authentication
26
+ severity: high
27
+ confidence: 0.86
28
+ tags:
29
+ - security
30
+ - electron
31
+ message:
32
+ title: "Add origin checks to ${captures.issue.text}"
33
+ summary: "${captures.issue.text} handles privileged IPC without validating the sender frame origin."
34
+ remediation:
35
+ summary: Assert trusted origins or channels before running privileged logic and reject unexpected senders early.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.electron-shell-open-external-unvalidated
5
+ title: Do not open external URLs from request data in Electron
6
+ summary: shell.openExternal should not receive request-controlled URLs without validation.
7
+ rationale: Open redirects and SSRF-style flows in the main process can pivot to arbitrary system browsers or handlers.
8
+ tags:
9
+ - security
10
+ - electron
11
+ - open-redirect
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.electron-shell-open-external-unvalidated
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.open-redirect
26
+ severity: high
27
+ confidence: 0.83
28
+ tags:
29
+ - security
30
+ - electron
31
+ message:
32
+ title: "Validate target URL for ${captures.issue.text}"
33
+ summary: "${captures.issue.text} opens a URL derived from request-controlled input."
34
+ remediation:
35
+ summary: Allowlist URL schemes and hosts, normalize targets, and block private IP ranges before calling openExternal.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.express-error-handler-information-disclosure
5
+ title: Avoid returning raw errors from Express error middleware
6
+ summary: Express error handlers should not send the err object directly to clients in production paths.
7
+ rationale: Returning raw errors leaks stack traces, internal identifiers, and implementation details to attackers.
8
+ tags:
9
+ - security
10
+ - express
11
+ - information-disclosure
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.express-error-handler-information-disclosure
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.information-disclosure
26
+ severity: medium
27
+ confidence: 0.8
28
+ tags:
29
+ - security
30
+ - express
31
+ message:
32
+ title: "Sanitize error responses from ${captures.issue.text}"
33
+ summary: "${captures.issue.text} forwards the caught error directly to res.send or res.json."
34
+ remediation:
35
+ summary: Log detailed errors server-side and return stable, generic client responses with correlation identifiers.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.express-static-dotfiles-allow
5
+ title: Do not allow dotfiles in Express static middleware
6
+ summary: express.static should not serve dotfiles from disk unless explicitly required and reviewed.
7
+ rationale: Allowing dotfiles can expose hidden configuration and secrets through the static file middleware.
8
+ tags:
9
+ - security
10
+ - express
11
+ - filesystem
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.express-static-dotfiles-allow
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: medium
27
+ confidence: 0.84
28
+ tags:
29
+ - security
30
+ - express
31
+ message:
32
+ title: "Restrict dotfiles for ${captures.issue.text}"
33
+ summary: "${captures.issue.text} is configured with dotfiles allow, which can leak hidden files."
34
+ remediation:
35
+ summary: Use the default dotfiles ignore behavior or serve dotfiles from a tightly scoped directory with access controls.
@@ -0,0 +1,34 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.express-unbounded-body-parser
5
+ title: Set explicit Express body parser and multer size limits
6
+ summary: Express and Body Parser middleware plus Multer should declare explicit payload limits.
7
+ rationale: Default limits drift across frameworks and deployments; explicit caps reduce oversized-request abuse.
8
+ tags:
9
+ - security
10
+ - express
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.express-unbounded-body-parser
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.misconfiguration
25
+ severity: medium
26
+ confidence: 0.78
27
+ tags:
28
+ - security
29
+ - express
30
+ message:
31
+ title: Declare explicit payload limits for body parsers and uploads
32
+ summary: "`${captures.issue.text}` runs without visible size limits."
33
+ remediation:
34
+ summary: Pass `limit` options to JSON/urlencoded/raw/text parsers and `limits.fileSize` (or equivalent) to Multer.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.express-user-controlled-static-mount
5
+ title: Avoid request-controlled Express static mount paths
6
+ summary: The path prefix for express.static should not be derived directly from request objects.
7
+ rationale: User-controlled mount paths can collapse routing assumptions and expose unintended directories.
8
+ tags:
9
+ - security
10
+ - express
11
+ - path
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.express-user-controlled-static-mount
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.path-traversal
26
+ severity: high
27
+ confidence: 0.8
28
+ tags:
29
+ - security
30
+ - express
31
+ message:
32
+ title: "Fix static mount path in ${captures.issue.text}"
33
+ summary: "${captures.issue.text} mounts express.static under a request-derived URL prefix."
34
+ remediation:
35
+ summary: Use fixed, reviewed path prefixes and map external identifiers to internal paths through an allowlist.
@@ -0,0 +1,34 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.fastify-excessive-body-limit
5
+ title: Avoid excessive Fastify body limits
6
+ summary: Fastify applications should not disable body limits or configure unusually large defaults without compensating controls.
7
+ rationale: Oversized bodies amplify denial-of-service risk on services without upstream buffering limits.
8
+ tags:
9
+ - security
10
+ - fastify
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.fastify-excessive-body-limit
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.misconfiguration
25
+ severity: medium
26
+ confidence: 0.76
27
+ tags:
28
+ - security
29
+ - fastify
30
+ message:
31
+ title: Reduce Fastify bodyLimit or add upstream limiting
32
+ summary: Fastify is configured with an oversized or disabled bodyLimit.
33
+ remediation:
34
+ summary: Lower `bodyLimit`, enforce route-specific caps, or terminate traffic behind an API gateway or proxy that caps body size.
@@ -0,0 +1,38 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.fastify-public-bind-without-trust-proxy
5
+ title: Enable trust proxy for publicly bound Fastify servers
6
+ summary: >-
7
+ Fastify instances listening on all interfaces should enable trustProxy or terminate behind a reverse proxy you register in code.
8
+ rationale: >-
9
+ Without trustProxy, client IP and protocol metadata from an edge proxy are easy to misread, and public binds amplify exposure when the process is not intentionally perimeter-hardened.
10
+ tags:
11
+ - security
12
+ - fastify
13
+ - rules-catalog
14
+ stability: experimental
15
+ appliesTo: block
16
+ scope:
17
+ languages:
18
+ - typescript
19
+ - javascript
20
+ match:
21
+ fact:
22
+ kind: security.fastify-public-bind-without-trust-proxy
23
+ bind: issue
24
+ emit:
25
+ finding:
26
+ category: security.misconfiguration
27
+ severity: medium
28
+ confidence: 0.74
29
+ tags:
30
+ - security
31
+ - fastify
32
+ message:
33
+ title: Set trustProxy or proxy middleware before binding Fastify publicly
34
+ summary: >-
35
+ Fastify listens on a public host without trustProxy enabled and without @fastify/http-proxy or @fastify/proxy in this file.
36
+ remediation:
37
+ summary: >-
38
+ Set trustProxy when running behind a reverse proxy, prefer non-public bind addresses in development, or register an explicit Fastify proxy plugin so client metadata and TLS termination assumptions stay correct.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.graphql-upload-without-csrf-guard
5
+ title: Pair GraphQL multipart uploads with CSRF-safe server posture
6
+ summary: Legacy GraphQL multipart upload helpers should not run alongside Apollo Server configurations that disable CSRF protections.
7
+ rationale: Multipart GraphQL requests complicate browser CSRF defenses; when Apollo CSRF prevention is explicitly disabled, upload middleware is a high-risk combination for cross-site writes.
8
+ tags:
9
+ - security
10
+ - graphql
11
+ - rules-catalog
12
+ stability: experimental
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.graphql-upload-without-csrf-guard
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.misconfiguration
25
+ severity: high
26
+ confidence: 0.8
27
+ tags:
28
+ - security
29
+ - graphql
30
+ message:
31
+ title: Re-enable Apollo CSRF defenses or remove GraphQL upload middleware from this bootstrap
32
+ summary: >-
33
+ GraphQL upload middleware is registered while Apollo Server disables csrfPrevention, or no Apollo bootstrap with safe CSRF defaults is present.
34
+ remediation:
35
+ summary: >-
36
+ Keep Apollo csrfPrevention enabled (default in supported releases), add an explicit preflight header policy, or move uploads behind authenticated, non-browser APIs.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.iframe-missing-sandbox-attribute
5
+ title: Add a sandbox attribute to iframes
6
+ summary: Intrinsic iframe elements should declare a sandbox attribute to reduce blast radius.
7
+ rationale: Sandboxed iframes limit scripts, forms, and top-level navigation when embedded third-party content is compromised.
8
+ tags:
9
+ - security
10
+ - react
11
+ - xss
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.iframe-missing-sandbox-attribute
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: low
27
+ confidence: 0.75
28
+ tags:
29
+ - security
30
+ - react
31
+ message:
32
+ title: "Add sandbox to ${captures.issue.text}"
33
+ summary: "${captures.issue.text} is missing a sandbox attribute."
34
+ remediation:
35
+ summary: Add the most restrictive sandbox token set that still allows required behavior, and combine with a strict CSP.