E11084: hardcoded JWT token detected

Category: E11xxx Code quality and IR analysis · Reported in phase: PRE_IR_CHECKS · Classification: HARDCODED_SECRET_JWT_TOKEN · All error codes

What went wrong

A string literal matching the JWT (JSON Web Token) three-part structure (header.payload.signature) was found in source code. JWTs always begin with "eyJ" (base64url-encoded JSON object starting with "{") and contain two dots separating the three segments.

Hardcoded JWT tokens in source code are a security vulnerability because they typically contain authentication claims, session data, or API access grants that should remain confidential and short-lived.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 704 (How does EK9 detect hardcoded secrets at compile time?)

Rationale

JWTs are designed to be ephemeral — they carry expiration claims and are meant to be generated per-session or per-request. A hardcoded JWT in source code is always wrong: either it's expired (useless dead code) or it's still valid (leaked credential).

Even expired JWTs reveal information: the issuer, audience, claims structure, and signing algorithm. Attackers use this to forge new tokens or identify the authentication infrastructure.

How to fix it

Generate JWTs dynamically at runtime (from your authentication service, for the claims of the user) rather than hardcoding them. If you need a token for development, load it from an environment variable:

secret <- EnvVars().sensitiveGet("SESSION_TOKEN")
if secret?
  configureService(secret)

For integration tests, use a local token-issuing service or generate tokens in your test setup code.

See also

  • E11080: hardcoded cloud provider credential detected
  • E11081: hardcoded platform token detected
  • E11082: hardcoded private key material detected
  • E11083: hardcoded database credential detected
  • E11086: hardcoded API key detected

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E11084: hardcoded JWT token detected

#!ek9
defines module error.e11084.bad

  defines function

    <?-
      Standard JWT token detected — eyJ header.payload.signature format.
    -?>
    testStandardJwt()
      token <- "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"

      stdout <- Stdout()
      stdout.println(token)

    <?-
      Another JWT with different claims.
    -?>
    testAnotherJwt()
      authHeader <- "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXVkIjoiYXBwIn0.signature_part_here"

      stdout <- Stdout()
      stdout.println(authHeader)

Fixed: Obtain the token at run time as a Sensitive

#!ek9
defines module error.e11084.good

  defines function

    configureService()
      -> token as Sensitive
      stdout <- Stdout()
      stdout.println($(token?))

    demo()
      secret <- EnvVars().sensitiveGet("SESSION_TOKEN")
      if secret?
        configureService(secret)

Questions and answers

These Q&A entries show E11084 and its fix: