@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,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.deep-nesting
5
+ title: Deep nesting reducing readability
6
+ summary: Deeply nested control flow should be flattened where practical.
7
+ rationale: Deep nesting increases cognitive load and makes edge cases harder to reason about during review.
8
+ tags:
9
+ - quality
10
+ - structure
11
+ - rules-catalog
12
+ - crq-qua-042
13
+ stability: stable
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.deep-nesting
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.structure
26
+ severity: low
27
+ confidence: 0.9
28
+ tags:
29
+ - quality
30
+ - structure
31
+ message:
32
+ title: Flatten deeply nested control flow
33
+ summary: Review `${captures.issue.text}` and reduce indentation depth.
34
+ remediation:
35
+ summary: Use guard clauses, helper functions, or early returns to keep the main path shallow.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.duplicate-code-block
5
+ title: Duplicate code block
6
+ summary: Large duplicated function bodies across files make behavior harder to maintain safely.
7
+ rationale: Duplicated logic often diverges over time and increases the cost of fixes, testing, and future changes.
8
+ tags:
9
+ - quality
10
+ - duplication
11
+ - rules-catalog
12
+ - crq-qua-043
13
+ stability: stable
14
+ appliesTo: file
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.duplicate-code-block
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.duplication
26
+ severity: low
27
+ confidence: 0.75
28
+ tags:
29
+ - quality
30
+ - duplication
31
+ message:
32
+ title: Extract duplicated logic into a shared unit
33
+ summary: "`${captures.issue.text}` duplicates a substantial code block already present elsewhere in the project."
34
+ remediation:
35
+ summary: Extract the shared logic into a common helper or module and keep one maintained implementation.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.function-too-large-or-complex
5
+ title: Function too large or too complex
6
+ summary: Oversized or overly complex functions should be split into smaller units.
7
+ rationale: Large functions are harder to test, review, and change safely because behavior and branching accumulate in one place.
8
+ tags:
9
+ - quality
10
+ - structure
11
+ - rules-catalog
12
+ - crq-qua-041
13
+ stability: stable
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.function-too-large-or-complex
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.structure
26
+ severity: low
27
+ confidence: 0.95
28
+ tags:
29
+ - quality
30
+ - structure
31
+ message:
32
+ title: Split large or complex functions
33
+ summary: Review `${captures.issue.text}` and extract smaller units of behavior.
34
+ remediation:
35
+ summary: Break the function into helpers, reduce branching, and isolate independent responsibilities.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.hardcoded-configuration-values
5
+ title: Hardcoded configuration values
6
+ summary: Config-like values should usually come from configuration sources rather than source literals.
7
+ rationale: Hardcoded service URLs, timeouts, and regions make deployments harder to vary and review safely.
8
+ tags:
9
+ - quality
10
+ - configuration
11
+ - rules-catalog
12
+ - crq-qua-044
13
+ stability: stable
14
+ appliesTo: file
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.hardcoded-configuration-values
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.configuration
26
+ severity: low
27
+ confidence: 0.8
28
+ tags:
29
+ - quality
30
+ - configuration
31
+ message:
32
+ title: Externalize config-like literals
33
+ summary: Review `${captures.issue.text}` and move config-like literals behind a configuration source.
34
+ remediation:
35
+ summary: Load the value from env, params, or a dedicated config module instead of hardcoding it in source.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.logic-change-without-test-updates
5
+ title: Logic change without corresponding test updates
6
+ summary: Diffs that change critical logic should usually update the matching tests in the same change.
7
+ rationale: Critical logic changes without test updates are easy to miss in review and increase regression risk.
8
+ tags:
9
+ - quality
10
+ - testing
11
+ - rules-catalog
12
+ - crq-qua-050
13
+ stability: stable
14
+ appliesTo: project
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ changedLinesOnly: true
20
+ match:
21
+ fact:
22
+ kind: quality.logic-change-without-test-updates
23
+ bind: issue
24
+ emit:
25
+ finding:
26
+ category: quality.testing
27
+ severity: medium
28
+ confidence: 0.7
29
+ tags:
30
+ - quality
31
+ - testing
32
+ message:
33
+ title: Update tests alongside critical logic changes
34
+ summary: "`${captures.issue.text}` changed without a corresponding test file change in the same diff."
35
+ remediation:
36
+ summary: Update or add the matching tests in the same change so the new behavior is exercised by the diff.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.magic-numbers-or-strings
5
+ title: Magic numbers or magic strings
6
+ summary: Non-trivial literals in logic should be named to explain their meaning.
7
+ rationale: Bare literals hide domain meaning and make future changes riskier because intent is not captured in code.
8
+ tags:
9
+ - quality
10
+ - readability
11
+ - rules-catalog
12
+ - crq-qua-045
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.magic-numbers-or-strings
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.readability
26
+ severity: low
27
+ confidence: 0.65
28
+ tags:
29
+ - quality
30
+ - readability
31
+ message:
32
+ title: Name magic literals
33
+ summary: Review `${captures.issue.text}` and replace unexplained literals with named constants.
34
+ remediation:
35
+ summary: Extract the literal into a descriptive constant or enum so the intent is explicit.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.missing-error-context
5
+ title: Missing error context or logging
6
+ summary: Catch blocks should include the caught error when they log or rethrow.
7
+ rationale: Logging or rethrowing without the original error strips the context needed to diagnose the failure.
8
+ tags:
9
+ - quality
10
+ - error-handling
11
+ - rules-catalog
12
+ - crq-qua-048
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: error-handling.missing-error-context
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.error-handling
26
+ severity: low
27
+ confidence: 0.8
28
+ tags:
29
+ - quality
30
+ - error-handling
31
+ message:
32
+ title: Preserve the original error context
33
+ summary: "Review `${captures.issue.text}` and include the caught error in the log or rethrow."
34
+ remediation:
35
+ summary: Pass the caught error to the logger or preserve it when constructing the replacement error.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.missing-tests-for-critical-logic
5
+ title: Missing tests for critical logic
6
+ summary: Critical auth, payment, or similar business logic should have a matching test file.
7
+ rationale: Important business and security logic needs direct regression coverage to keep changes safe and reviewable.
8
+ tags:
9
+ - quality
10
+ - testing
11
+ - rules-catalog
12
+ - crq-qua-049
13
+ stability: stable
14
+ appliesTo: project
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.missing-tests-for-critical-logic
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.testing
26
+ severity: medium
27
+ confidence: 0.8
28
+ tags:
29
+ - quality
30
+ - testing
31
+ message:
32
+ title: Add tests for critical logic paths
33
+ summary: "`${captures.issue.text}` looks like critical logic but no matching test file was found."
34
+ remediation:
35
+ summary: Add a focused unit or integration test that covers the critical behavior before future changes land.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.swallowed-error
5
+ title: Errors swallowed silently
6
+ summary: Catch blocks must log, reject, or rethrow failures instead of dropping them silently.
7
+ rationale: Silent catch blocks hide failures and make production diagnosis unnecessarily difficult.
8
+ tags:
9
+ - quality
10
+ - error-handling
11
+ - rules-catalog
12
+ - crq-qua-047
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: error-handling.swallowed-error
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.error-handling
26
+ severity: medium
27
+ confidence: 0.95
28
+ tags:
29
+ - quality
30
+ - error-handling
31
+ message:
32
+ title: Do not swallow caught errors
33
+ summary: "Review `${captures.issue.text}` and propagate or record the failure."
34
+ remediation:
35
+ summary: Rethrow the error, reject the async flow, or log the failure through a recognized error sink.
@@ -0,0 +1,35 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.quality.tight-module-coupling
5
+ title: Tight coupling between modules
6
+ summary: Direct import cycles between modules increase coupling and make change boundaries harder to maintain.
7
+ rationale: Cyclic dependencies complicate initialization order, testing, and architecture boundaries.
8
+ tags:
9
+ - quality
10
+ - architecture
11
+ - rules-catalog
12
+ - crq-qua-046
13
+ stability: stable
14
+ appliesTo: project
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: quality.tight-module-coupling
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: quality.architecture
26
+ severity: medium
27
+ confidence: 0.9
28
+ tags:
29
+ - quality
30
+ - architecture
31
+ message:
32
+ title: Break direct cyclic imports between modules
33
+ summary: "`${captures.issue.text}` participates in a direct module import cycle."
34
+ remediation:
35
+ summary: Extract shared types or helpers into a third module, or invert the dependency so the cycle disappears.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.random.no-math-random-in-core
5
+ title: Avoid `Math.random()` in core code
6
+ summary: Core code should not depend on nondeterministic random generation.
7
+ rationale: Randomness in core logic makes behavior hard to test and reason about.
8
+ tags:
9
+ - determinism
10
+ - rules-catalog
11
+ scope:
12
+ languages:
13
+ - typescript
14
+ paths:
15
+ include:
16
+ - "**/core/**"
17
+ match:
18
+ node:
19
+ kind: CallExpression
20
+ bind: randomCall
21
+ where:
22
+ - path: callee.object.text
23
+ equals: Math
24
+ - path: callee.property.text
25
+ equals: random
26
+ emit:
27
+ finding:
28
+ category: maintainability
29
+ severity: medium
30
+ confidence: high
31
+ tags:
32
+ - determinism
33
+ message:
34
+ title: Avoid `${captures.randomCall.text}`
35
+ summary: Replace `${captures.randomCall.text}` with an injected randomness source.
36
+ remediation:
37
+ summary: Pass a random source into core logic instead of calling `Math.random()` directly.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.react.no-cascaded-effect-fetches
5
+ title: Avoid cascaded fetches inside React effects
6
+ summary: React effects should not serialize independent fetches that can run in parallel or move server-side.
7
+ rationale: Waterfall-style fetches delay rendering and hide data-loading cost inside client effects.
8
+ tags:
9
+ - performance
10
+ - react
11
+ - next
12
+ - rules-catalog
13
+ stability: experimental
14
+ appliesTo: function
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: performance.react-effect-fetch-waterfall
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: performance.ui
26
+ severity: medium
27
+ confidence: 0.82
28
+ tags:
29
+ - performance
30
+ - react
31
+ - next
32
+ message:
33
+ title: Avoid cascaded fetches inside React effects
34
+ summary: "`${captures.issue.text}` serializes fetches inside a React effect."
35
+ remediation:
36
+ summary: Parallelize the requests, move data loading server-side, or cache the first response before issuing the next request.
37
+
@@ -0,0 +1,29 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.runtime.no-debugger-statement
5
+ title: Remove `debugger;`
6
+ summary: Remove debugger statements before committing source files.
7
+ rationale: Debugger statements interrupt runtime execution and should not ship.
8
+ tags:
9
+ - runtime
10
+ - rules-catalog
11
+ scope:
12
+ languages:
13
+ - typescript
14
+ match:
15
+ node:
16
+ kind: DebuggerStatement
17
+ bind: statement
18
+ emit:
19
+ finding:
20
+ category: maintainability
21
+ severity: medium
22
+ confidence: high
23
+ tags:
24
+ - runtime
25
+ message:
26
+ title: Remove `debugger;`
27
+ summary: Remove the debugger statement before committing the file.
28
+ remediation:
29
+ summary: Delete the debugger statement.
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.bind-to-all-interfaces
5
+ title: Avoid binding to all interfaces
6
+ summary: Network-facing services should not explicitly bind to every interface unless public exposure is intentional and protected.
7
+ rationale: Binding to `0.0.0.0` or `::` can expose a service beyond the expected trust boundary and widen the reachable attack surface.
8
+ tags:
9
+ - security
10
+ - network
11
+ - exposure
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.bind-to-all-interfaces
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.network
26
+ severity: medium
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - network
31
+ - exposure
32
+ message:
33
+ title: Restrict interface binding in `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` explicitly binds a network-facing service to every interface."
35
+ remediation:
36
+ summary: Bind to loopback or a specific interface unless public exposure is an intentional deployment requirement with compensating controls.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.browser-token-storage
5
+ title: Avoid browser token storage
6
+ summary: Access and session tokens should not be stored in long-lived browser storage.
7
+ rationale: Long-lived browser storage exposes tokens to script access and increases the impact of XSS or device compromise.
8
+ tags:
9
+ - security
10
+ - authentication
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: ts.security.browser-token-storage
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.authentication
26
+ severity: medium
27
+ confidence: 0.88
28
+ tags:
29
+ - security
30
+ - authentication
31
+ - storage
32
+ message:
33
+ title: Avoid storing tokens in `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` stores an access or session token in browser storage."
35
+ remediation:
36
+ summary: Keep tokens in HttpOnly cookies or in memory, and avoid long-lived cleartext browser storage.
37
+
@@ -0,0 +1,36 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.dangerous-insert-html
5
+ title: Avoid unsafe DOM HTML insertion sinks
6
+ summary: "`outerHTML`, `document.write*`, and `insertAdjacentHTML` should only receive fixed or explicitly sanitized HTML."
7
+ rationale: HTML-capable DOM insertion sinks can execute attacker-controlled markup unless the HTML is fixed or strongly sanitized first.
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.dangerous-insert-html
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: Avoid unsafe HTML insertion in `${captures.issue.text}`
34
+ summary: "`${captures.issue.text}` uses an HTML-capable DOM sink with non-literal, non-sanitized content."
35
+ remediation:
36
+ summary: Insert text with safe DOM APIs, or pass only fixed or explicitly sanitized HTML to the sink.
@@ -0,0 +1,38 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.dangerously-set-inner-html
5
+ title: Avoid unsafe `dangerouslySetInnerHTML`
6
+ summary: React `dangerouslySetInnerHTML` should only render fixed or explicitly sanitized HTML.
7
+ rationale: React bypasses its normal escaping model when `dangerouslySetInnerHTML` is used, which makes unsanitized HTML a direct XSS sink.
8
+ tags:
9
+ - security
10
+ - xss
11
+ - react
12
+ - output-encoding
13
+ - rules-catalog
14
+ stability: stable
15
+ appliesTo: block
16
+ scope:
17
+ languages:
18
+ - typescript
19
+ - javascript
20
+ match:
21
+ fact:
22
+ kind: security.dangerously-set-inner-html
23
+ bind: issue
24
+ emit:
25
+ finding:
26
+ category: security.output-encoding
27
+ severity: high
28
+ confidence: 0.93
29
+ tags:
30
+ - security
31
+ - xss
32
+ - react
33
+ - output-encoding
34
+ message:
35
+ title: Avoid unsafe `dangerouslySetInnerHTML` in `${captures.issue.text}`
36
+ summary: "`${captures.issue.text}` bypasses React escaping with non-literal, non-sanitized HTML."
37
+ remediation:
38
+ summary: Prefer normal React rendering, or pass only fixed or explicitly sanitized HTML to `dangerouslySetInnerHTML`.
@@ -0,0 +1,37 @@
1
+ apiVersion: critiq.dev/v1alpha1
2
+ kind: Rule
3
+ metadata:
4
+ id: ts.security.datadog-browser-track-user-interactions
5
+ title: Review Datadog RUM user interaction capture
6
+ summary: Datadog Browser RUM should not enable broad user interaction capture without a privacy review.
7
+ rationale: Automatic interaction capture can leak sensitive page content or element labels to third-party telemetry.
8
+ tags:
9
+ - security
10
+ - privacy
11
+ - telemetry
12
+ - rules-catalog
13
+ stability: stable
14
+ appliesTo: block
15
+ scope:
16
+ languages:
17
+ - typescript
18
+ - javascript
19
+ match:
20
+ fact:
21
+ kind: security.datadog-browser-track-user-interactions
22
+ bind: issue
23
+ emit:
24
+ finding:
25
+ category: security.privacy
26
+ severity: medium
27
+ confidence: 0.9
28
+ tags:
29
+ - security
30
+ - privacy
31
+ - telemetry
32
+ message:
33
+ title: Review `${captures.issue.text}` before enabling interaction capture
34
+ summary: "`${captures.issue.text}` turns on Datadog RUM user interaction tracking, which can capture sensitive UI context."
35
+ remediation:
36
+ summary: Disable broad interaction capture or add explicit scrubbing and allowlisted action naming before enabling it.
37
+