@critiq/rules 0.0.2 → 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.
- package/README.md +52 -4
- package/catalog.yaml +985 -19
- package/package.json +6 -1
- package/rules/go/go.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/go/go.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/go/go.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/go/go.security.echo-sensitive-binding-without-validation.rule.yaml +46 -0
- package/rules/go/go.security.echo-unsafe-multipart-upload.rule.yaml +45 -0
- package/rules/go/go.security.fiber-sensitive-binding-without-validation.rule.yaml +45 -0
- package/rules/go/go.security.fiber-unsafe-multipart-upload.rule.yaml +45 -0
- package/rules/go/go.security.gin-sensitive-binding-without-validation.rule.yaml +45 -0
- package/rules/go/go.security.gin-trust-all-proxies.rule.yaml +45 -0
- package/rules/go/go.security.gin-wildcard-cors-with-credentials.rule.yaml +47 -0
- package/rules/go/go.security.net-http-missing-timeouts.rule.yaml +45 -0
- package/rules/go/go.security.sensitive-data-egress.rule.yaml +46 -0
- package/rules/go/go.security.tar-path-traversal.rule.yaml +45 -0
- package/rules/go/go.security.template-unescaped-request-value.rule.yaml +45 -0
- package/rules/go/go.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/go/go.testing.t-skip-without-ticket-reference.rule.yaml +33 -0
- package/rules/go/go.testing.time-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/java/java.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/java/java.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/java/java.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/java/java.security.android-screenshot-exposure.rule.yaml +35 -0
- package/rules/java/java.security.android-world-readable-mode.rule.yaml +35 -0
- package/rules/java/java.security.jpa-concatenated-query.rule.yaml +47 -0
- package/rules/java/java.security.reflected-output-from-request.rule.yaml +35 -0
- package/rules/java/java.security.servlet-insecure-cookie.rule.yaml +35 -0
- package/rules/java/java.security.spring-actuator-health-details-always.rule.yaml +40 -0
- package/rules/java/java.security.spring-actuator-sensitive-exposure.rule.yaml +40 -0
- package/rules/java/java.security.spring-csrf-globally-disabled.rule.yaml +49 -0
- package/rules/java/java.security.spring-debug-exposure.rule.yaml +35 -0
- package/rules/java/java.security.spring-permit-all-default.rule.yaml +47 -0
- package/rules/java/java.security.spring-webmvc-unrestricted-data-binding.rule.yaml +47 -0
- package/rules/java/java.security.template-unescaped-user-output.rule.yaml +49 -0
- package/rules/java/java.testing.disabled-without-ticket-reference.rule.yaml +33 -0
- package/rules/java/java.testing.http-client-in-unit-test.rule.yaml +33 -0
- package/rules/java/java.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/php/php.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/php/php.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/php/php.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/php/php.security.insecure-cors-wildcard-with-credentials.rule.yaml +41 -0
- package/rules/php/php.security.insecure-mail-or-file-transport.rule.yaml +41 -0
- package/rules/php/php.security.insecure-session-or-cookie-config.rule.yaml +42 -0
- package/rules/php/php.security.laravel-sensitive-csrf-exclusion.rule.yaml +42 -0
- package/rules/php/php.security.laravel-unsafe-blade-output.rule.yaml +42 -0
- package/rules/php/php.security.laravel-unsafe-mass-assignment.rule.yaml +45 -0
- package/rules/php/php.security.sensitive-data-egress.rule.yaml +42 -0
- package/rules/php/php.security.symfony-csrf-disabled.rule.yaml +42 -0
- package/rules/php/php.security.symfony-debug-exposure.rule.yaml +44 -0
- package/rules/php/php.security.unsafe-file-upload-handling.rule.yaml +41 -0
- package/rules/php/php.security.wordpress-missing-nonce-or-capability.rule.yaml +42 -0
- package/rules/php/php.security.wordpress-unprepared-sql.rule.yaml +42 -0
- package/rules/php/php.testing.curl-in-unit-test.rule.yaml +33 -0
- package/rules/php/php.testing.mark-test-skipped-without-ticket-reference.rule.yaml +33 -0
- package/rules/php/php.testing.sleep-in-unit-test.rule.yaml +33 -0
- package/rules/python/py.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/python/py.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/python/py.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/python/py.security.django-csrf-exempt-state-changing.rule.yaml +46 -0
- package/rules/python/py.security.django-missing-csrf-middleware.rule.yaml +47 -0
- package/rules/python/py.security.django-unsafe-production-settings.rule.yaml +47 -0
- package/rules/python/py.security.drf-allow-any-default.rule.yaml +46 -0
- package/rules/python/py.security.drf-allow-any-unsafe-method.rule.yaml +46 -0
- package/rules/python/py.security.fastapi-insecure-cors.rule.yaml +43 -0
- package/rules/python/py.security.flask-missing-upload-body-limit.rule.yaml +44 -0
- package/rules/python/py.security.flask-unsafe-html-output.rule.yaml +44 -0
- package/rules/python/py.security.flask-unsafe-upload-filename.rule.yaml +44 -0
- package/rules/python/py.testing.pytest-skip-without-ticket-reference.rule.yaml +33 -0
- package/rules/python/py.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/python/py.testing.time-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/ruby/ruby.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/ruby/ruby.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/ruby/ruby.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/ruby/ruby.security.rails-csrf-disabled.rule.yaml +45 -0
- package/rules/ruby/ruby.security.rails-detailed-exceptions-enabled.rule.yaml +44 -0
- package/rules/ruby/ruby.security.rails-open-redirect.rule.yaml +45 -0
- package/rules/ruby/ruby.security.rails-unsafe-html-output.rule.yaml +46 -0
- package/rules/ruby/ruby.security.rails-unsafe-render.rule.yaml +45 -0
- package/rules/ruby/ruby.security.rails-unsafe-session-or-cookie-store.rule.yaml +45 -0
- package/rules/ruby/ruby.security.rails-unsafe-strong-parameters.rule.yaml +46 -0
- package/rules/ruby/ruby.security.sensitive-data-egress.rule.yaml +45 -0
- package/rules/ruby/ruby.security.sidekiq-web-unauthenticated-mount.rule.yaml +45 -0
- package/rules/ruby/ruby.testing.focused-example.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.pending-without-ticket-reference.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.skip-without-ticket-reference.rule.yaml +33 -0
- package/rules/ruby/ruby.testing.sleep-in-unit-test.rule.yaml +33 -0
- package/rules/rust/rust.performance.no-regex-construction-in-loop.rule.yaml +33 -0
- package/rules/rust/rust.performance.no-sync-fs-in-request-path.rule.yaml +33 -0
- package/rules/rust/rust.performance.no-unbounded-concurrency.rule.yaml +33 -0
- package/rules/rust/rust.security.actix-wildcard-cors-with-credentials.rule.yaml +47 -0
- package/rules/rust/rust.security.axum-body-limit-disabled.rule.yaml +45 -0
- package/rules/rust/rust.security.axum-insecure-cors-with-credentials.rule.yaml +47 -0
- package/rules/rust/rust.security.rocket-panic-prone-request-handler.rule.yaml +45 -0
- package/rules/rust/rust.security.rocket-unsafe-template-output.rule.yaml +47 -0
- package/rules/rust/rust.security.sqlx-diesel-raw-interpolated-query.rule.yaml +47 -0
- package/rules/rust/rust.security.template-unescaped-request-value.rule.yaml +47 -0
- package/rules/rust/rust.security.warp-blocking-or-panic-in-async-handler.rule.yaml +45 -0
- package/rules/rust/rust.testing.ignore-without-ticket-reference.rule.yaml +33 -0
- package/rules/rust/rust.testing.real-network-in-unit-test.rule.yaml +33 -0
- package/rules/rust/rust.testing.thread-sleep-in-unit-test.rule.yaml +33 -0
- package/rules/shared/security.archive-path-traversal.rule.yaml +41 -0
- package/rules/shared/security.external-file-upload.rule.yaml +40 -0
- package/rules/shared/security.permissive-file-permissions.rule.yaml +40 -0
- package/rules/shared/security.sensitive-data-egress.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.assignment-in-condition.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.assignment-to-import-binding.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.async-promise-executor.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-function-parameter.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-import-source.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-object-key.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.duplicate-switch-case.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.empty-block-statement.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.identical-comparison-operands.rule.yaml +36 -0
- package/rules/typescript/ts.correctness.reassign-catch-binding.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.regexp-pattern-unusual-control-character.rule.yaml +35 -0
- package/rules/typescript/ts.correctness.self-assignment.rule.yaml +36 -0
- package/rules/typescript/ts.next.server-action-missing-local-auth.rule.yaml +35 -0
- package/rules/typescript/ts.performance.no-array-spread-in-hot-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-cache-miss-from-unstable-key.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-expensive-sort-in-render-path.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-json-parse-stringify-clone.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-large-object-spread-in-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-n-plus-one-await-in-map.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-redundant-network-fetch.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-regex-construction-in-loop.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-sync-fs-in-request-path.rule.yaml +32 -0
- package/rules/typescript/ts.performance.no-unbounded-concurrency.rule.yaml +32 -0
- package/rules/typescript/ts.quality.no-ambiguous-abbreviations.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-barrel-file-cycle.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-boolean-parameter-trap.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-dead-export.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-hidden-side-effect-import.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-inconsistent-error-shape.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-mixed-abstraction-level.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-primitive-obsession-in-domain-model.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-temporal-coupling.rule.yaml +27 -0
- package/rules/typescript/ts.quality.no-wide-public-surface.rule.yaml +27 -0
- package/rules/typescript/ts.react.no-accessibility-label-missing.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-activedescendant-on-non-focusable-host.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-click-without-keyboard-handler.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-deprecated-create-factory.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-deprecated-react-dom-root-api.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-derived-state-from-props.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-effect-fetch-without-cancellation.rule.yaml +35 -0
- package/rules/typescript/ts.react.no-find-dom-node.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-img-missing-alt-text.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-index-as-key-in-dynamic-list.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-interactive-role-on-static-semantics.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-invalid-anchor-href.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-keyboard-interaction-without-widget-role.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-legacy-lifecycle.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-missing-error-boundary.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-positive-tabindex.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-static-element-with-synthetic-handlers.rule.yaml +36 -0
- package/rules/typescript/ts.react.no-string-ref.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-uncontrolled-to-controlled-input.rule.yaml +34 -0
- package/rules/typescript/ts.react.no-widget-role-without-tabindex.rule.yaml +36 -0
- package/rules/typescript/ts.security.ajv-insecure-configuration.rule.yaml +34 -0
- package/rules/typescript/ts.security.angular-dom-sanitizer-bypass-untrusted-input.rule.yaml +35 -0
- package/rules/typescript/ts.security.apollo-server-csrf-disabled.rule.yaml +36 -0
- package/rules/typescript/ts.security.apollo-server-graphql-dev-tooling-exposure.rule.yaml +36 -0
- package/rules/typescript/ts.security.apollo-server-introspection-exposure.rule.yaml +35 -0
- package/rules/typescript/ts.security.apollo-server-missing-query-limits.rule.yaml +35 -0
- package/rules/typescript/ts.security.astro-vite-public-secret-define.rule.yaml +39 -0
- package/rules/typescript/ts.security.debug-statement-in-source.rule.yaml +36 -0
- package/rules/typescript/ts.security.electron-dangerous-webpreferences.rule.yaml +35 -0
- package/rules/typescript/ts.security.electron-insecure-local-state.rule.yaml +35 -0
- package/rules/typescript/ts.security.electron-missing-ipc-origin-check.rule.yaml +35 -0
- package/rules/typescript/ts.security.electron-shell-open-external-unvalidated.rule.yaml +35 -0
- package/rules/typescript/ts.security.express-error-handler-information-disclosure.rule.yaml +35 -0
- package/rules/typescript/ts.security.express-static-dotfiles-allow.rule.yaml +35 -0
- package/rules/typescript/ts.security.express-unbounded-body-parser.rule.yaml +34 -0
- package/rules/typescript/ts.security.express-user-controlled-static-mount.rule.yaml +35 -0
- package/rules/typescript/ts.security.fastify-excessive-body-limit.rule.yaml +34 -0
- package/rules/typescript/ts.security.fastify-public-bind-without-trust-proxy.rule.yaml +38 -0
- package/rules/typescript/ts.security.graphql-upload-without-csrf-guard.rule.yaml +36 -0
- package/rules/typescript/ts.security.iframe-missing-sandbox-attribute.rule.yaml +35 -0
- package/rules/typescript/ts.security.insecure-content-security-policy-literal.rule.yaml +35 -0
- package/rules/typescript/ts.security.insecure-helmet-hardening-options.rule.yaml +36 -0
- package/rules/typescript/ts.security.jwt-insecure-signing-algorithm.rule.yaml +35 -0
- package/rules/typescript/ts.security.legacy-buffer-constructor.rule.yaml +35 -0
- package/rules/typescript/ts.security.log-injection.rule.yaml +36 -0
- package/rules/typescript/ts.security.nestjs-helmet-after-route-mount.rule.yaml +34 -0
- package/rules/typescript/ts.security.nestjs-missing-global-validation-pipe.rule.yaml +35 -0
- package/rules/typescript/ts.security.nestjs-skip-throttle-sensitive-route.rule.yaml +35 -0
- package/rules/typescript/ts.security.nestjs-validation-pipe-without-whitelist.rule.yaml +36 -0
- package/rules/typescript/ts.security.nuxt-public-runtime-secret.rule.yaml +38 -0
- package/rules/typescript/ts.security.open-redirect.rule.yaml +2 -0
- package/rules/typescript/ts.security.request-driven-array-index-access.rule.yaml +33 -0
- package/rules/typescript/ts.security.sensitive-data-egress.rule.yaml +1 -0
- package/rules/typescript/ts.security.ssrf.rule.yaml +1 -0
- package/rules/typescript/ts.security.unsafe-dompurify-version.rule.yaml +36 -0
- package/rules/typescript/ts.security.unsafe-marked-version.rule.yaml +36 -0
- package/rules/typescript/ts.security.xml-parse-string-with-untrusted-input.rule.yaml +35 -0
- package/rules/typescript/ts.testing.no-flaky-timer-test.rule.yaml +38 -0
- package/rules/typescript/ts.testing.no-focused-test.rule.yaml +34 -0
- package/rules/typescript/ts.testing.no-missing-edge-case-tests.rule.yaml +35 -0
- package/rules/typescript/ts.testing.no-network-call-in-unit-test.rule.yaml +38 -0
- package/rules/typescript/ts.testing.no-skipped-test-without-ticket.rule.yaml +34 -0
- package/rules/typescript/ts.testing.no-snapshot-without-intent.rule.yaml +34 -0
- 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.
|