What are JSON Web Tokens (JWTs)?
JSON Web Tokens, or JWTs, are a popular way to securely transmit information between parties as a JSON object. They are commonly used for authentication and authorization in web applications. Understanding how JWTs are structured and secured is crucial to prevent common security pitfalls.
Understanding JWT Structure
A JWT is composed of three distinct parts, separated by dots:
- Header: This section typically contains metadata about the token, such as the type of token (JWT) and the signing algorithm used (e.g., HMAC SHA256 or RSA).
- Payload: This is where the actual data, or claims, are stored. Claims are statements about an entity (typically, the user) and additional data. Common claims include user ID, roles, and expiration time.
- Signature: This part is used to verify the sender’s identity and to ensure that the message hasn’t been altered since it was sent.
The Critical Security Flaw: Encoding vs. Encryption
The most critical aspect to understand about JWTs is the difference between encoding and encryption. The header and payload sections of a JWT are Base64Url encoded. This encoding is easily reversible, meaning anyone can decode these parts and read the information contained within them. This is not encryption. Encryption is a process that scrambles data, making it unreadable without a decryption key.
Demonstration: Decoding a JWT
Let’s illustrate this with an example. If you have a valid JWT, you can take it to a tool that decodes Base64Url. You will be able to see all the information in the header and the payload in plain text. This includes details like:
- User ID
- Email address
- Expiration time
- Any other custom data included in the payload
Because this information is readily accessible, it’s imperative to treat the payload as public information.
How JWT Security Actually Works: The Signature
The security of a JWT lies solely in its signature. Here’s how it works:
- Creation: The server takes the encoded header and the encoded payload.
- Signing: It then uses a secret key (known only to the server) and the specified algorithm (from the header) to generate a signature. This signature is appended to the token.
- Verification: When the client sends the JWT back to the server (e.g., in an Authorization header), the server performs the same signing process using the same secret key and the received header and payload. It then compares the newly generated signature with the signature provided in the token.
If the signatures match, the server can be confident that the token was issued by it and that the payload has not been tampered with. If the signatures do not match, the token is considered invalid and will be rejected.
The Golden Rule: What NOT to Put in a JWT Payload
Given that the header and payload are easily readable, the cardinal rule of JWT security is: Never put sensitive data in the payload that you wouldn’t want to be publicly visible.
- Passwords: Never store passwords or password hashes in a JWT payload.
- Sensitive Personal Information: Avoid including highly sensitive PII like social security numbers, credit card details, or medical information.
- Secret Keys or API Keys: Do not embed any form of secret keys or API keys that grant access to other systems.
- Confidential Business Data: Refrain from including any proprietary or confidential business information.
What is Acceptable for JWT Payloads?
JWT payloads are perfectly suitable for storing non-sensitive information that helps identify or authorize a user, such as:
- User ID (a unique identifier)
- Username or email address (for identification)
- User roles or permissions
- Expiration timestamps (e.g., `exp`, `iat`, `nbf`)
- Issuer (`iss`) and Audience (`aud`) claims
This information is generally safe to expose because it’s either non-identifiable, already publicly known, or necessary for the application’s functionality.
Experiment with JWTs
To better understand how JWTs work and to experiment with decoding them, you can use online tools. For instance, the website webutills.io provides a platform to decode and manipulate JWTs, allowing you to see firsthand how the header and payload are exposed.
Expert Tip:
Always use strong, unique secret keys for signing your JWTs. The security of your tokens relies heavily on the confidentiality of this secret key. Treat it with the same security as you would a password.
Warning:
Remember, JWTs are signed, not encrypted. If you need to transmit truly sensitive data, consider using a different mechanism, such as encrypting the data before including it in the payload (though this adds complexity) or using a secure server-side session.
Source: JSON Web Tokens – Don't add sensitive data (YouTube)