rules:
  - id: auth.fastify.jwt-hardcoded-secret
    languages:
      - javascript
      - typescript
    severity: ERROR
    message: |
      `@fastify/jwt` is registered with a hard-coded `secret` string literal.
      This key signs and verifies every token: committed to git it is one search
      away from compromise, letting an attacker forge tokens for any user.

      Load it from the environment instead
      (`fastify.register(fastifyJwt, { secret: process.env.JWT_SECRET })`) and add
      the variable to `.env.example` with a placeholder. Rotate the leaked value
      out of source control. For asymmetric signing pass a key pair
      (`{ private, public }`) read from files or a secret manager, not inline.
    # Matches a Fastify plugin registration whose first argument is the JWT
    # plugin (identifier like `fastifyJwt` or `require('@fastify/jwt')`, matched
    # by the case-insensitive `jwt` regex) and whose options carry a string
    # literal `secret`. The literal requirement excludes `process.env.*` and
    # `config.get(...)`; the regex allow-list drops `${ENV}` templates,
    # `<placeholders>`, and obvious stubs. `paths.exclude` keeps it off
    # test/example trees.
    patterns:
      - pattern: '$F.register($PLUGIN, { ..., secret: $S, ... })'
      - metavariable-regex:
          metavariable: $PLUGIN
          regex: (?i).*jwt
      - metavariable-pattern:
          metavariable: $S
          patterns:
            - pattern-regex: ^['"].*['"]$
            - pattern-not-regex: (?i)^['"]\$\{?[A-Za-z_]+\}?['"]$
            - pattern-not-regex: (?i)^['"]<[^'"]*>['"]$
            - pattern-not-regex: (?i)^['"](?:your[-_]|my[-_]|example|placeholder|xxx+|todo|fixme|test|dummy|fake|sample|changeme|change[-_]?me|redacted|replace)
    paths:
      exclude:
        - "**/test/**"
        - "**/__tests__/**"
        - "**/*.test.*"
        - "**/*.spec.*"
        - "**/example/**"
        - "**/examples/**"
        - "**/demo/**"
        - "**/benchmark/**"
        - "**/benchmarks/**"
        - "**/integration/**"
        - "**/*.tst.*"
    metadata:
      oauthlint-rule-id: AUTH-FASTIFY-001
      oauthlint-doc-url: https://oauthlint.dev/rules/fastify-jwt-hardcoded-secret
      category: security
      cwe: CWE-798
      owasp: API2:2023
      llm-prevalence: HIGH
      technology:
        - fastify
        - "@fastify/jwt"
      references:
        - https://github.com/fastify/fastify-jwt#usage
        - https://cwe.mitre.org/data/definitions/798.html
