rules:
  - id: auth.kotlin.jwt.missing-issuer-audience
    languages:
      - kotlin
    severity: WARNING
    message: |
      This JWT verifier checks the signature but never asserts the token's
      intended recipient: the Auth0 `JWT.require(alg)...build()` chain pins no
      `.withIssuer(...)` and no `.withAudience(...)`. A valid signature only proves
      the token was minted by whoever holds the key, not that it was issued by the
      expected authority or meant for THIS service. A token your provider issued
      for a different audience, or one minted by any party that shares the key,
      will still verify, enabling token replay across services (CWE-345). This is a
      common AI-generated mistake in Ktor `jwt { verifier(...) }` setups: the
      sample verifies the signature and stops there.

      Pin the recipient before `.build()`: chain
      `.withIssuer("https://your-idp")` and `.withAudience("your-api")` on the
      `JWT.require(...)` builder.
    # Tempered-greedy regex over the whole builder chain (structural chain matching
    # breaks the moment an intermediate call like `.acceptLeeway(3)` sits between
    # require(...) and build()). Fire on a `JWT.require(...)....build()` chain that
    # reaches `.build()` WITHOUT passing `.withIssuer(`/`.withAudience(`/
    # `.withAnyOfAudience(`; if either is pinned the negative lookahead stops the
    # match, so the safe (issuer+audience) chain never fires. Order-independent.
    pattern-regex: 'JWT\.require\((?:(?!\.build\(\)|\.withIssuer\(|\.withAudience\(|\.withAnyOfAudience\()[\s\S])*?\.build\(\)'
    metadata:
      oauthlint-rule-id: AUTH-KOTLIN-JWT-003
      oauthlint-doc-url: https://oauthlint.dev/rules/kotlin-jwt-missing-issuer-audience
      category: security
      cwe: CWE-345
      owasp: API2:2023
      llm-prevalence: MEDIUM
      technology:
        - java-jwt
        - ktor
      references:
        - https://ktor.io/docs/server-jwt.html
        - https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3
        - https://cwe.mitre.org/data/definitions/345.html
