Base64, hex and URL encoding only change how bytes are written down. Anyone can reverse them with no key. If a value must stay secret, encrypt it. If it must not be altered, sign it or add a MAC. Encoding is for transport, never for protection.
Why this mistake keeps happening
Encoded data looks scrambled. A string like eyJ1c2VyIjoiYWRhIn0 seems opaque to a person, so it feels protected. But decoding it needs no secret and takes one command. The Django signing documentation shows this plainly: its signed values are readable payloads with a signature attached, so anyone who sees one can read it.
The same confusion shows up with HTTP Basic auth headers, stored configuration values, cookies, query parameters and mobile app preferences.
Four operations, four questions
- Encoding: can another system read it? Reversible by anyone.
- Hashing: can I fingerprint it? One-way, no key.
- Signing or MAC: has it been changed, and who made it? Needs a key to create, a key to check.
- Encryption: can only a key holder read it? Needs a key to read.
For a longer comparison see our decision guide for hash, MAC, signature or encryption.
Where to look in a review
- Secrets stored as base64 in config files, charts or repositories. Our post on Kubernetes secrets and base64 is one example.
- Tokens that decode to readable JSON with user data inside.
- Fields called
encryptedthat call an encode function. - Obfuscation with XOR against a constant, or a fixed "key" in the source.
- Mobile apps embedding keys in resources, assuming users cannot decode them.
What to do
- Replace the encoding with real encryption using an AEAD, and keep the key in a secrets manager or KMS.
- If the data never needed to be read back, hash it with the right algorithm instead.
- If only integrity mattered, sign or MAC it and accept that the contents are visible.
- If you find a real secret that was only encoded, treat it as exposed and rotate it. The leaked secret response steps apply.
Quick check
Is a JWT encrypted?
A normal signed JWT is not. Its header and payload are base64url text that anyone can decode. Do not put secrets in it unless it uses a separate encryption format.
Is URL encoding a security control?
No. It stops characters breaking a URL, nothing more. It does not replace output encoding or input validation either.
Sources
Last reviewed: 19 October 2026.