rules:
  - id: auth.session.hardcoded-secret
    languages:
      - javascript
      - typescript
    severity: ERROR
    message: |
      An `express-session` / `cookie-session` `secret` is a hard-coded string
      literal. The infamous `secret: 'keyboard cat'` is the canonical
      AI-generated example. This key signs the session cookie: anyone who
      reads it from your source or git history can forge arbitrary session
      cookies and impersonate any user.

      Load the secret from the environment (`process.env.SESSION_SECRET`) or a
      secret manager, and rotate it out of source control. Add a placeholder
      to `.env.example` so contributors know it is required.
    # AST patterns target the `secret:` key inside session()/cookieSession()
    # options. The metavariable-pattern requires $S to be a quoted literal, so
    # `process.env.SESSION_SECRET`, `config.sessionSecret`, and `loadSecret()`
    # never match (they are not string literals).
    patterns:
      - pattern-either:
          - pattern: 'session({secret: $S, ...})'
          - pattern: 'cookieSession({secret: $S, ...})'
          - pattern: 'expressSession({secret: $S, ...})'
      - metavariable-pattern:
          metavariable: $S
          patterns:
            - pattern-regex: ^['"].*['"]$
    metadata:
      oauthlint-rule-id: AUTH-SESSION-003
      oauthlint-doc-url: https://oauthlint.dev/rules/session-hardcoded-secret
      category: security
      cwe: CWE-798
      owasp: A07:2021
      llm-prevalence: HIGH
      technology:
        - express-session
        - cookie-session
      references:
        - https://github.com/expressjs/session#secret
        - https://cwe.mitre.org/data/definitions/798.html
