@critiq/rules 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +169 -0
  2. package/catalog.yaml +599 -0
  3. package/package.json +21 -0
  4. package/rules/shared/security.insecure-http-transport.rule.yaml +42 -0
  5. package/rules/shared/security.no-command-execution-with-request-input.rule.yaml +42 -0
  6. package/rules/shared/security.no-hardcoded-credentials.rule.yaml +42 -0
  7. package/rules/shared/security.no-request-path-file-read.rule.yaml +42 -0
  8. package/rules/shared/security.no-sensitive-data-in-logs-and-telemetry.rule.yaml +44 -0
  9. package/rules/shared/security.no-sql-interpolation.rule.yaml +42 -0
  10. package/rules/shared/security.tls-verification-disabled.rule.yaml +42 -0
  11. package/rules/shared/security.unsafe-deserialization.rule.yaml +41 -0
  12. package/rules/shared/security.weak-hash-algorithm.rule.yaml +41 -0
  13. package/rules/typescript/ts.config.no-process-env-outside-config.rule.yaml +37 -0
  14. package/rules/typescript/ts.correctness.blocking-call-in-async-flow.rule.yaml +35 -0
  15. package/rules/typescript/ts.correctness.constant-condition.rule.yaml +35 -0
  16. package/rules/typescript/ts.correctness.implicit-undefined-return.rule.yaml +34 -0
  17. package/rules/typescript/ts.correctness.incorrect-boolean-logic.rule.yaml +35 -0
  18. package/rules/typescript/ts.correctness.missing-await-on-async-call.rule.yaml +35 -0
  19. package/rules/typescript/ts.correctness.missing-default-dispatch.rule.yaml +35 -0
  20. package/rules/typescript/ts.correctness.missing-timeout-on-external-call.rule.yaml +35 -0
  21. package/rules/typescript/ts.correctness.nested-property-access-without-check.rule.yaml +35 -0
  22. package/rules/typescript/ts.correctness.off-by-one-loop-boundary.rule.yaml +35 -0
  23. package/rules/typescript/ts.correctness.optional-value-without-fallback.rule.yaml +35 -0
  24. package/rules/typescript/ts.correctness.possible-null-dereference.rule.yaml +35 -0
  25. package/rules/typescript/ts.correctness.shared-state-race.rule.yaml +35 -0
  26. package/rules/typescript/ts.correctness.unchecked-map-key-access.rule.yaml +35 -0
  27. package/rules/typescript/ts.correctness.unhandled-async-error.rule.yaml +35 -0
  28. package/rules/typescript/ts.correctness.unreachable-statement.rule.yaml +40 -0
  29. package/rules/typescript/ts.logging.no-console-error.rule.yaml +34 -0
  30. package/rules/typescript/ts.logging.no-console-log.rule.yaml +34 -0
  31. package/rules/typescript/ts.next.no-server-client-boundary-leaks.rule.yaml +36 -0
  32. package/rules/typescript/ts.performance.inefficient-data-structure-usage.rule.yaml +35 -0
  33. package/rules/typescript/ts.performance.large-payload-without-streaming.rule.yaml +35 -0
  34. package/rules/typescript/ts.performance.missing-batch-operations.rule.yaml +35 -0
  35. package/rules/typescript/ts.performance.nested-loops-hot-path.rule.yaml +35 -0
  36. package/rules/typescript/ts.performance.repeated-expensive-computation.rule.yaml +35 -0
  37. package/rules/typescript/ts.performance.repeated-io-in-loop.rule.yaml +35 -0
  38. package/rules/typescript/ts.performance.retained-large-object.rule.yaml +35 -0
  39. package/rules/typescript/ts.performance.sequential-async-calls.rule.yaml +35 -0
  40. package/rules/typescript/ts.performance.unbounded-growth-memory-leak.rule.yaml +35 -0
  41. package/rules/typescript/ts.performance.unnecessary-rerenders-from-state-misuse.rule.yaml +35 -0
  42. package/rules/typescript/ts.quality.deep-nesting.rule.yaml +35 -0
  43. package/rules/typescript/ts.quality.duplicate-code-block.rule.yaml +35 -0
  44. package/rules/typescript/ts.quality.function-too-large-or-complex.rule.yaml +35 -0
  45. package/rules/typescript/ts.quality.hardcoded-configuration-values.rule.yaml +35 -0
  46. package/rules/typescript/ts.quality.logic-change-without-test-updates.rule.yaml +36 -0
  47. package/rules/typescript/ts.quality.magic-numbers-or-strings.rule.yaml +35 -0
  48. package/rules/typescript/ts.quality.missing-error-context.rule.yaml +35 -0
  49. package/rules/typescript/ts.quality.missing-tests-for-critical-logic.rule.yaml +35 -0
  50. package/rules/typescript/ts.quality.swallowed-error.rule.yaml +35 -0
  51. package/rules/typescript/ts.quality.tight-module-coupling.rule.yaml +35 -0
  52. package/rules/typescript/ts.random.no-math-random-in-core.rule.yaml +37 -0
  53. package/rules/typescript/ts.react.no-cascaded-effect-fetches.rule.yaml +37 -0
  54. package/rules/typescript/ts.runtime.no-debugger-statement.rule.yaml +29 -0
  55. package/rules/typescript/ts.security.bind-to-all-interfaces.rule.yaml +36 -0
  56. package/rules/typescript/ts.security.browser-token-storage.rule.yaml +37 -0
  57. package/rules/typescript/ts.security.dangerous-insert-html.rule.yaml +36 -0
  58. package/rules/typescript/ts.security.dangerously-set-inner-html.rule.yaml +38 -0
  59. package/rules/typescript/ts.security.datadog-browser-track-user-interactions.rule.yaml +37 -0
  60. package/rules/typescript/ts.security.debug-mode-enabled.rule.yaml +38 -0
  61. package/rules/typescript/ts.security.dynamodb-query-injection.rule.yaml +36 -0
  62. package/rules/typescript/ts.security.exposed-directory-listing.rule.yaml +37 -0
  63. package/rules/typescript/ts.security.express-cookie-missing-http-only.rule.yaml +36 -0
  64. package/rules/typescript/ts.security.express-default-cookie-config.rule.yaml +39 -0
  65. package/rules/typescript/ts.security.express-default-session-config.rule.yaml +37 -0
  66. package/rules/typescript/ts.security.express-insecure-cookie.rule.yaml +36 -0
  67. package/rules/typescript/ts.security.express-missing-helmet.rule.yaml +37 -0
  68. package/rules/typescript/ts.security.express-nosql-injection.rule.yaml +36 -0
  69. package/rules/typescript/ts.security.express-permissive-cookie-config.rule.yaml +38 -0
  70. package/rules/typescript/ts.security.express-reduce-fingerprint.rule.yaml +37 -0
  71. package/rules/typescript/ts.security.express-static-assets-after-session.rule.yaml +37 -0
  72. package/rules/typescript/ts.security.external-file-upload.rule.yaml +36 -0
  73. package/rules/typescript/ts.security.file-generation.rule.yaml +36 -0
  74. package/rules/typescript/ts.security.format-string-using-user-input.rule.yaml +36 -0
  75. package/rules/typescript/ts.security.frontend-only-authorization.rule.yaml +35 -0
  76. package/rules/typescript/ts.security.handlebars-no-escape.rule.yaml +38 -0
  77. package/rules/typescript/ts.security.hardcoded-auth-secret.rule.yaml +37 -0
  78. package/rules/typescript/ts.security.import-using-user-input.rule.yaml +36 -0
  79. package/rules/typescript/ts.security.information-leakage.rule.yaml +38 -0
  80. package/rules/typescript/ts.security.insecure-allow-origin.rule.yaml +36 -0
  81. package/rules/typescript/ts.security.insecure-auth-cookie-flags.rule.yaml +37 -0
  82. package/rules/typescript/ts.security.insecure-password-hash-configuration.rule.yaml +37 -0
  83. package/rules/typescript/ts.security.insecure-websocket-transport.rule.yaml +37 -0
  84. package/rules/typescript/ts.security.insufficiently-random-values.rule.yaml +36 -0
  85. package/rules/typescript/ts.security.jwt-not-revoked.rule.yaml +37 -0
  86. package/rules/typescript/ts.security.jwt-sensitive-claims.rule.yaml +37 -0
  87. package/rules/typescript/ts.security.manual-html-sanitization.rule.yaml +37 -0
  88. package/rules/typescript/ts.security.missing-authorization-before-sensitive-action.rule.yaml +35 -0
  89. package/rules/typescript/ts.security.missing-integrity-check.rule.yaml +36 -0
  90. package/rules/typescript/ts.security.missing-message-origin-check.rule.yaml +36 -0
  91. package/rules/typescript/ts.security.missing-ownership-validation.rule.yaml +35 -0
  92. package/rules/typescript/ts.security.missing-request-timeout-or-retry.rule.yaml +35 -0
  93. package/rules/typescript/ts.security.no-dynamic-execution.rule.yaml +34 -0
  94. package/rules/typescript/ts.security.no-innerhtml-assignment.rule.yaml +36 -0
  95. package/rules/typescript/ts.security.non-literal-fs-filename.rule.yaml +36 -0
  96. package/rules/typescript/ts.security.observable-timing-discrepancy.rule.yaml +37 -0
  97. package/rules/typescript/ts.security.open-redirect.rule.yaml +37 -0
  98. package/rules/typescript/ts.security.permissive-allow-origin.rule.yaml +36 -0
  99. package/rules/typescript/ts.security.permissive-file-permissions.rule.yaml +37 -0
  100. package/rules/typescript/ts.security.postmessage-wildcard-origin.rule.yaml +36 -0
  101. package/rules/typescript/ts.security.predictable-token-generation.rule.yaml +36 -0
  102. package/rules/typescript/ts.security.raw-html-using-user-input.rule.yaml +37 -0
  103. package/rules/typescript/ts.security.sensitive-data-egress.rule.yaml +36 -0
  104. package/rules/typescript/ts.security.sensitive-data-in-exception.rule.yaml +37 -0
  105. package/rules/typescript/ts.security.sensitive-data-written-to-file.rule.yaml +37 -0
  106. package/rules/typescript/ts.security.ssrf.rule.yaml +34 -0
  107. package/rules/typescript/ts.security.token-or-session-not-validated.rule.yaml +35 -0
  108. package/rules/typescript/ts.security.ui-redress.rule.yaml +37 -0
  109. package/rules/typescript/ts.security.unsanitized-http-response.rule.yaml +36 -0
  110. package/rules/typescript/ts.security.unvalidated-external-input.rule.yaml +35 -0
  111. package/rules/typescript/ts.security.user-controlled-sendfile.rule.yaml +36 -0
  112. package/rules/typescript/ts.security.user-controlled-view-render.rule.yaml +36 -0
  113. package/rules/typescript/ts.security.weak-cipher-or-mode.rule.yaml +35 -0
  114. package/rules/typescript/ts.security.weak-key-strength.rule.yaml +36 -0
  115. package/rules/typescript/ts.security.weak-tls-version.rule.yaml +36 -0
  116. package/src/index.d.ts +1 -0
  117. package/src/index.js +5 -0
  118. package/src/index.js.map +1 -0
  119. package/src/lib/rules-package.d.ts +3 -0
  120. package/src/lib/rules-package.js +16 -0
  121. package/src/lib/rules-package.js.map +1 -0
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.observable-timing-discrepancy
5
+ title: Use constant-time secret comparison
6
+ summary: Secrets and tokens should not be compared with ordinary equality operators.
7
+ rationale: Ordinary string comparison can leak timing differences that help attackers guess secret material.
8
+ tags:
9
+ - security
10
+ - cryptography
11
+ - timing
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.observable-timing-discrepancy
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.cryptography
26
+ severity: high
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - cryptography
31
+ - timing
32
+ message:
33
+ title: Replace `${captures.issue.text}` with a constant-time comparison
34
+ summary: "`${captures.issue.text}` compares a likely secret value with ordinary equality."
35
+ remediation:
36
+ summary: Use a constant-time comparison helper such as `crypto.timingSafeEqual` for secrets, tokens, and password hashes.
37
+
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.open-redirect
5
+ title: Open redirect via request-controlled target
6
+ summary: Redirect and navigation sinks should not use request-controlled destinations without validation.
7
+ rationale: Redirect targets that are derived from user input can send authenticated users to attacker-controlled destinations.
8
+ tags:
9
+ - security
10
+ - input-validation
11
+ - 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.open-redirect
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.input-validation
26
+ severity: high
27
+ confidence: 0.85
28
+ tags:
29
+ - security
30
+ - redirect
31
+ - input-validation
32
+ message:
33
+ title: Validate redirect target before using `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` redirects to a request-controlled destination without a strict allowlist or internal-path check."
35
+ remediation:
36
+ summary: Normalize the target to an internal path or validate it against a trusted origin allowlist before redirecting.
37
+
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.permissive-allow-origin
5
+ title: Do not allow every origin in CORS policy
6
+ summary: CORS should not fall back to wildcard or implicit allow-all origin settings.
7
+ rationale: Wildcard or implicit allow-all CORS policies expose authenticated browser responses across origins.
8
+ tags:
9
+ - security
10
+ - cors
11
+ - misconfiguration
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.permissive-allow-origin
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: high
27
+ confidence: 0.92
28
+ tags:
29
+ - security
30
+ - cors
31
+ - misconfiguration
32
+ message:
33
+ title: Restrict `${captures.issue.text}` to trusted origins
34
+ summary: "`${captures.issue.text}` allows any origin through wildcard or implicit CORS policy."
35
+ remediation:
36
+ summary: Configure an explicit allowlist or validated origin callback instead of allowing all origins.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.permissive-file-permissions
5
+ title: Avoid permissive file modes
6
+ summary: Files that can carry user or security data should not be created with world-accessible modes.
7
+ rationale: Broad file permissions expose application data to local users or processes that should not read or modify it.
8
+ tags:
9
+ - security
10
+ - filesystem
11
+ - permissions
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.permissive-file-permissions
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.filesystem
26
+ severity: high
27
+ confidence: 0.95
28
+ tags:
29
+ - security
30
+ - filesystem
31
+ - permissions
32
+ message:
33
+ title: Tighten the mode used by `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` sets a file mode that grants world access."
35
+ remediation:
36
+ summary: Use the minimum required file mode and remove world-readable or world-writable bits.
37
+
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.postmessage-wildcard-origin
5
+ title: Avoid wildcard `postMessage` targets
6
+ summary: "`postMessage` calls should not use `*` as the target origin when they carry application data."
7
+ rationale: Wildcard targets allow the browser to deliver the message to any origin that receives the window reference.
8
+ tags:
9
+ - security
10
+ - browser
11
+ - messaging
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.postmessage-wildcard-origin
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.browser
26
+ severity: high
27
+ confidence: 0.95
28
+ tags:
29
+ - security
30
+ - browser
31
+ - messaging
32
+ message:
33
+ title: Replace the wildcard target in `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` uses `*` as the `postMessage` target origin."
35
+ remediation:
36
+ summary: Set the target origin to a strict expected origin instead of `*`.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.predictable-token-generation
5
+ title: Avoid predictable token generation
6
+ summary: Tokens, reset links, and session secrets should be generated from cryptographically strong randomness.
7
+ rationale: Predictable token material makes it easier to guess reset links, invite codes, and session secrets.
8
+ tags:
9
+ - security
10
+ - authentication
11
+ - crypto
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.predictable-token-generation
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.authentication
26
+ severity: high
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - authentication
31
+ - crypto
32
+ message:
33
+ title: Avoid predictable token generation
34
+ summary: "`${captures.issue.text}` builds a token-like value from predictable inputs."
35
+ remediation:
36
+ summary: Generate the value with `crypto.randomBytes`, `crypto.randomUUID`, or an approved secure token source.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.raw-html-using-user-input
5
+ title: Avoid raw HTML with request input
6
+ summary: Request-derived values should not be interpolated into raw HTML strings.
7
+ rationale: Raw HTML construction with request data is a common path to reflected and stored XSS.
8
+ tags:
9
+ - security
10
+ - xss
11
+ - output-encoding
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.raw-html-using-user-input
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.output-encoding
26
+ severity: high
27
+ confidence: 0.92
28
+ tags:
29
+ - security
30
+ - xss
31
+ - output-encoding
32
+ message:
33
+ title: Remove request input from `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` interpolates request-derived content into raw HTML."
35
+ remediation:
36
+ summary: Use framework escaping, a trusted sanitizer, or safe DOM APIs instead of raw HTML interpolation.
37
+
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.sensitive-data-egress
5
+ title: Sensitive data egress to third-party processors
6
+ summary: Sensitive values should not be sent to external processors or outbound SDKs without minimization or redaction.
7
+ rationale: Sending regulated or secret data to third-party services increases privacy exposure and creates downstream processor risk.
8
+ tags:
9
+ - security
10
+ - privacy
11
+ - data-exposure
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.sensitive-data-egress
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.privacy
26
+ severity: high
27
+ confidence: 0.82
28
+ tags:
29
+ - security
30
+ - privacy
31
+ - data-exposure
32
+ message:
33
+ title: Avoid sending sensitive data through `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` sends normalized sensitive datatypes to an outbound processor or external service."
35
+ remediation:
36
+ summary: Minimize the payload, redact the sensitive fields, or route the data only to approved processors.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.sensitive-data-in-exception
5
+ title: Avoid sensitive data in thrown errors
6
+ summary: Exceptions and rejection payloads should not include raw secrets or personal data.
7
+ rationale: Exception payloads often reach logs, APM tools, and client responses with less review than normal business data.
8
+ tags:
9
+ - security
10
+ - privacy
11
+ - errors
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.sensitive-data-in-exception
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.privacy
26
+ severity: high
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - privacy
31
+ - errors
32
+ message:
33
+ title: Remove sensitive data from `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` includes sensitive values in an exception or rejection payload."
35
+ remediation:
36
+ summary: Replace raw secrets and personal data with opaque identifiers or redacted summaries before throwing or rejecting.
37
+
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.sensitive-data-written-to-file
5
+ title: Avoid writing sensitive data to files
6
+ summary: Data exports and local file writes should not persist raw secrets or personal fields.
7
+ rationale: Static files, exports, and backups are easy to copy or retain beyond their intended lifetime.
8
+ tags:
9
+ - security
10
+ - privacy
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.sensitive-data-written-to-file
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.privacy
26
+ severity: high
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - privacy
31
+ - filesystem
32
+ message:
33
+ title: Remove sensitive fields before `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` writes sensitive data into a local file sink."
35
+ remediation:
36
+ summary: Redact, hash, or exclude the sensitive fields before writing the file.
37
+
@@ -0,0 +1,34 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.ssrf
5
+ title: Server-side request forgery
6
+ summary: Outbound requests should not use attacker-controlled targets or private hosts.
7
+ rationale: Request-controlled targets can force the server to call internal services, metadata endpoints, or attacker-controlled infrastructure.
8
+ tags:
9
+ - security
10
+ - network
11
+ - ssrf
12
+ - rules-catalog
13
+ scope:
14
+ languages:
15
+ - typescript
16
+ - javascript
17
+ match:
18
+ fact:
19
+ kind: security.ssrf
20
+ bind: ssrfCall
21
+ emit:
22
+ finding:
23
+ category: security.transport
24
+ severity: high
25
+ confidence: 0.85
26
+ tags:
27
+ - security
28
+ - network
29
+ - ssrf
30
+ message:
31
+ title: Avoid SSRF in `${captures.ssrfCall.text}`
32
+ summary: "`${captures.ssrfCall.text}` sends an outbound request to a request-controlled or private target."
33
+ remediation:
34
+ summary: Resolve URLs against a trusted allowlist, reject private hosts, and proxy outbound requests through a vetted server-side helper.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.token-or-session-not-validated
5
+ title: Token or session not validated
6
+ summary: Session and token values from external input should be verified before authentication or identity use.
7
+ rationale: Parsing or loading session state without verification allows forged or stale credentials to influence authorization paths.
8
+ tags:
9
+ - security
10
+ - authentication
11
+ - rules-catalog
12
+ - crq-sec-023
13
+ stability: stable
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.token-or-session-not-validated
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.authentication
26
+ severity: high
27
+ confidence: 0.85
28
+ tags:
29
+ - security
30
+ - authentication
31
+ message:
32
+ title: Validate tokens and sessions before use
33
+ summary: "`${captures.issue.text}` uses token or session input without any preceding validation step."
34
+ remediation:
35
+ summary: Verify or authenticate the token or session value before decoding, loading, or deriving identity from it.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.ui-redress
5
+ title: Do not derive anti-framing headers from request input
6
+ summary: Framing and CSP headers should not be set from request-controlled values.
7
+ rationale: Request-controlled anti-framing headers weaken protections against clickjacking and UI redress attacks.
8
+ tags:
9
+ - security
10
+ - clickjacking
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.ui-redress
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.misconfiguration
26
+ severity: high
27
+ confidence: 0.88
28
+ tags:
29
+ - security
30
+ - clickjacking
31
+ - headers
32
+ message:
33
+ title: Set `${captures.issue.text}` from trusted policy only
34
+ summary: "`${captures.issue.text}` derives anti-framing or CSP header values from request input."
35
+ remediation:
36
+ summary: Set framing and CSP headers from fixed server policy instead of request data.
37
+
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.unsanitized-http-response
5
+ title: Avoid unsafe raw HTTP response output
6
+ summary: Raw response writers should not echo request data into HTML-capable responses without trusted escaping or sanitization.
7
+ rationale: Directly reflecting request data into HTML-capable response sinks creates reflected XSS and content injection risk.
8
+ tags:
9
+ - security
10
+ - xss
11
+ - express
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.unsanitized-http-response
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.output-encoding
26
+ severity: high
27
+ confidence: 0.88
28
+ tags:
29
+ - security
30
+ - xss
31
+ - express
32
+ message:
33
+ title: Remove request data from `${captures.issue.text}` or escape it first
34
+ summary: "`${captures.issue.text}` writes request-controlled data into a raw HTTP response sink without a trusted HTML escaping model."
35
+ remediation:
36
+ summary: Escape or sanitize the data with a trusted helper, or switch to a response format that does not treat it as executable markup.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.unvalidated-external-input
5
+ title: Validate untrusted input before parser construction
6
+ summary: Untrusted input should be validated before it is used to construct sensitive parsers or runtime objects.
7
+ rationale: Passing untrusted text across regex or URL construction boundaries increases the risk of parser abuse, denial of service, and downstream policy bypass.
8
+ tags:
9
+ - security
10
+ - input-validation
11
+ - rules-catalog
12
+ - crq-sec-027
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.unvalidated-external-input
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.input-validation
26
+ severity: medium
27
+ confidence: 0.8
28
+ tags:
29
+ - security
30
+ - input-validation
31
+ message:
32
+ title: Validate the trust boundary before `${captures.issue.text}`
33
+ summary: "`${captures.issue.text}` constructs a sensitive parser or runtime object from untrusted input without a trust-boundary check."
34
+ remediation:
35
+ summary: Validate, sanitize, or normalize the untrusted value before passing it into URL, RegExp, or similarly sensitive constructors.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.user-controlled-sendfile
5
+ title: Constrain `res.sendFile` to a trusted root
6
+ summary: "`res.sendFile()` should not resolve filenames or options from request input without a trusted root."
7
+ rationale: Request-controlled file responses are a common path to path traversal and unintended local file disclosure.
8
+ tags:
9
+ - security
10
+ - filesystem
11
+ - express
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.user-controlled-sendfile
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.filesystem
26
+ severity: high
27
+ confidence: 0.92
28
+ tags:
29
+ - security
30
+ - filesystem
31
+ - express
32
+ message:
33
+ title: Validate the file path used by `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` serves a request-controlled file path or options object without a trusted root."
35
+ remediation:
36
+ summary: Resolve files from an allowlisted directory and validate request input before it reaches `res.sendFile()`.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.user-controlled-view-render
5
+ title: Constrain `res.render()` trust boundaries
6
+ summary: Express view names should not cross into server-side rendering from untrusted input.
7
+ rationale: Untrusted template names can expose internal views, bypass intended route behavior, or widen a server-side template boundary.
8
+ tags:
9
+ - security
10
+ - express
11
+ - rendering
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.user-controlled-view-render
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.output-encoding
26
+ severity: medium
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - express
31
+ - rendering
32
+ message:
33
+ title: Resolve the view for `${captures.issue.text}` from a trusted route map
34
+ summary: "`${captures.issue.text}` selects a server-side template across a trust boundary using untrusted input."
35
+ remediation:
36
+ summary: Resolve the template from an allowlist or fixed route mapping before calling `res.render()`.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.weak-cipher-or-mode
5
+ title: Avoid weak cipher algorithms and modes
6
+ summary: Cryptographic ciphers should use modern authenticated modes and approved algorithms.
7
+ rationale: Weak modes such as ECB and legacy ciphers such as DES or RC4 do not provide adequate confidentiality.
8
+ tags:
9
+ - security
10
+ - crypto
11
+ - rules-catalog
12
+ stability: stable
13
+ appliesTo: block
14
+ scope:
15
+ languages:
16
+ - typescript
17
+ - javascript
18
+ match:
19
+ fact:
20
+ kind: security.weak-cipher-or-mode
21
+ bind: issue
22
+ emit:
23
+ finding:
24
+ category: security.secrets
25
+ severity: high
26
+ confidence: 0.9
27
+ tags:
28
+ - security
29
+ - crypto
30
+ - cipher
31
+ message:
32
+ title: Avoid weak cipher algorithms and modes
33
+ summary: "`${captures.issue.text}` uses a weak cipher algorithm or mode."
34
+ remediation:
35
+ summary: Use modern authenticated encryption such as AES-GCM with approved key sizes and IV handling.