jwt-hack, one Rust binary for decoding, checking and stress testing a token
JSON Web Token Hack Toolkit
At a glance
- What is it?
- jwt-hack is a Rust command line toolkit for working with JSON Web Tokens, with separate modes to encode, decode, verify, crack, generate attack payloads, scan for known weaknesses, and expose the whole thing over a local REST API or an MCP server. It is built for testing your own token handling, and the scan mode is the part most teams would actually run.
- Who is it for?
- jwt-hack suits a developer or security engineer who has a token and wants to know whether the implementation around it is safe, since the scan mode checks algorithm handling, secret strength, expiry claims and header injection points in one command, and it suits anyone building JWT support who needs to generate the awkward cases on purpose.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Eight modes, one binary
jwt-hack is described as a high-performance toolkit for testing, analyzing and attacking JSON Web Tokens, and the mode table in the README is the fastest way to see its scope.
Encode is a JWT and JWE encoder covering secret based and key based signing, algorithm selection, custom headers, DEFLATE compression and JWE. Decode handles algorithm, issued at checking, DEFLATE decompression and JWE structure. Verify is a signature verifier for both secret based and key based algorithms. Crack is a secret cracker with dictionary attack, brute force and DEFLATE support. Payload is a JWT attack payload generator offering none, jku and x5u, algorithm confusion signed via a public key, kid and claim injection, claims tampering, signature malleability, JWE probes, x5c and cty. Scan is a vulnerability scanner. Server is an API server on http://localhost:3000, and MCP is a Model Context Protocol server for AI model integration.
That last row is the newest thing in the table and it changes what the tool is for. The MCP mode lets an AI model drive JWT functionality over a standardized protocol, and the README describes the server as communicating via stdio with jwt-hack mcp. In other words, the same operations a person runs from a shell become tool calls an agent can make. That is convenient for an assistant that is helping you audit an authentication implementation, and it is also the reason the mode deserves thought before you point an agent at a production token.
The Rust implementation is what makes the mode set plausible in one binary. The Cargo.toml shows jsonwebtoken 11.0.0 with the aws_lc_rs feature for signature work, josekit 0.10.3 for the JWE side, flate2 for DEFLATE, openssl with the vendored feature, rsa for PEM keys, aes-gcm, and rayon for parallel work on the cracking path. The release profile is tuned hard, with opt-level 3, lto, a single codegen unit, strip and panic set to abort.
The project is MIT licensed, the version in Cargo.toml is 2.6.0, the minimum Rust version is 1.87.0, and the release tags are v2.6.0 from 2026-06-05, v2.5.0 from 2026-03-02 and v2.4.0 from 2025-10-26, with the last push on 2026-10-15.
Installing it, and what the crack mode actually needs
The distribution channels are unusually thorough for a small security tool. Cargo install jwt-hack is the direct route, and there is a Homebrew formula, a Snapcraft package for Ubuntu, and a Chocolatey package for Windows. The Snap install needs sudo, and the Chocolatey one is a single command:
cargo install jwt-hack
brew install jwt-hack
sudo snap install jwt-hack
choco install jwt-hackBuilding from source is the standard git clone and cargo install --path, and there are container images on GHCR and Docker Hub, with the Docker Hub tag pinned to the release version rather than latest.
The crack mode is the part that deserves a clear description rather than a command. It performs dictionary attacks and brute force attacks against the signing secret of a token, and the README shows both forms:
# Dictionary attack
jwt-hack crack -w wordlist.txt JWT_TOKEN
# Bruteforce attack
jwt-hack crack -m brute JWT_TOKEN --max=4The brute force mode tries short secrets, with --max setting the length ceiling, and the dictionary mode takes a wordlist file. Both forms also work on DEFLATE compressed tokens, so a compressed token does not hide a weak secret. The wordlist in the repository at samples/wordlist.txt and a token in samples/jwt.txt are there for trying the feature out.
The legitimate use is checking your own secret. A signing secret of four characters passes every functional test and fails every security review, and a token signed with it is forgeable by anyone who guesses. Running the cracker against a token from your own test environment tells you whether your secret is guessable, and the answer is almost always that it should be replaced with a long random value and rotated.
The illegitimate use is guessing someone else's, and the tool's payload mode exists for that direction too, which is why the scope of use matters more here than for a general purpose JSON tool. The repository itself carries a SECURITY.md and a CODE_OF_CONDUCT.md, and the topics list includes bugbounty.
The scan mode is the part a development team will use most
Scan is the mode that makes this a testing tool rather than a cracking tool, and it is the one to reach for when you are reviewing your own authentication code.
A full scan runs weak secret detection and payload generation, and the flags let you narrow it. --skip-crack skips the secret cracking for faster results, --skip-payloads skips payload generation, -w takes a custom wordlist for weak secret detection, and --max-crack-attempts limits the number of secret testing attempts.
The checks it performs are listed in the README and they map directly onto the ways JWT implementations go wrong. The none algorithm vulnerability check detects if the token accepts unsigned tokens. Weak secrets are tested against common passwords with a customisable wordlist. Algorithm confusion identifies tokens vulnerable to RS256 to HS256 attacks. Token expiration issues are checked for a missing or improper expiration claim, and missing security claims verifies the presence of recommended JWT claims. Kid header injection detects potential SQL or path injection vulnerabilities, and JKU and X5U header attacks identify URL spoofing attack vectors.
Several of those checks are more than signature verification. A server that accepts a token with alg set to none is the classic JWT failure, and a server that will treat an RS256 public key as an HMAC secret is the next one. The kid header check matters because implementations often use the kid value to look up a key, and a value that reaches a file path or a database query is an injection point. The JKU and X5U checks matter because a server that fetches a key from a URL in the token header will fetch from wherever the token says, which is a token forgery primitive if the attacker controls that URL.
The README does not document the exact check identifiers or the output format, so expect to read the source or the documentation site at jwt-hack.hahwul.com to map the findings to your own checklist.
Encoding, decoding and verifying the awkward cases
The remaining modes are the plumbing you need to test against, and their value is in covering cases that are tedious to produce by hand.
Encoding a token takes a JSON payload and a secret, and --compress applies DEFLATE compression to the payload. Private key signing works with an RSA key and an explicit algorithm:
jwt-hack encode '{"a":"z"}' --private-key RS256.key --algorithm=RS256JWE encoding produces encrypted tokens with --jwe, which the README notes can only be decrypted with the proper key. Decoding handles both regular and DEFLATE compressed JWTs, detecting and decompressing compressed tokens automatically, and JWE tokens are detected by their five part structure with the header, encrypted key, IV, ciphertext and authentication tag shown.
Verification is the mode that decides whether a token is actually valid, and it distinguishes the two families of algorithm. With a secret it covers the HMAC algorithms HS256, HS384 and HS512, and with a private key it covers the asymmetric ones like RS256, ES256 and EdDSA.
The payload mode is where a token gets turned into a set of deliberately malformed variants, and the example given uses the jwk attack:
jwt-hack payload JWT_TOKEN --jwk-attack evil.com --jwk-trust trusted.comThe options listed in the table cover none, jku and x5u, algorithm confusion signed via a public key, kid and claim injection, claims tampering, signature malleability, JWE probes, x5c and cty. The value of this mode is not that the attacks work, it is that you can hand a specific variant to a test and see what your server does with it, which is a far better question than whether you think your server is safe.
The repository also holds a fuzz/ directory, and the justfile defines a fuzz task for a jwt_decode target, so the decoder itself is being fuzzed.
A REST API and an MCP server, and what that means for exposure
Two of the modes turn the toolkit into a service, and both need care.
The server mode starts a local REST API for automation and integrations on http://localhost:3000. It can be protected with --api-key, and requests then include an X-API-KEY header, as in the health check example:
# Start on localhost:3000 with API key protection
jwt-hack server --api-key your-api-key
# Example request (must include X-API-KEY when --api-key is set)
curl -s http://127.0.0.1:3000/health -H 'X-API-KEY: your-api-key'The API key exists for a reason, because a service that can crack secrets and generate attack payloads is a dangerous thing to expose on a network interface. The README says the server runs on localhost, which is the safe default, but the mode is aimed at automation, and automation tends to want to reach it from another container or host. If you do that, put the API key on it and keep it off anything routable.
The MCP mode is the newer surface. Running jwt-hack mcp starts a server that communicates over stdio, which is the standard transport for local MCP servers, and the point is that an AI model can call the JWT operations as tools. The reasonable use is an agent that is helping you audit an authentication implementation, and the risk is the same as with any tool that gives a model a cracking primitive: the model decides which calls to make, so the guardrail is the token you hand it, not the tool.
Underneath the modes, the project is a well-organised Rust repository. There are benches/ with a criterion benchmark named jwt_benchmarks, a tests/ directory, a snap/ directory and an aur/ directory for Arch packaging, packaging/ for the other package formats, a scripts/ directory, and a justfile whose test recipe runs cargo test, clippy with warnings denied for both the crate and the tests, cargo fmt --check and cargo doc across the workspace with all features. The justfile also carries version-check and version-update recipes that run Crystal scripts to keep the version in lockstep across Cargo.toml, Cargo.lock, snap, aur, docs and README, which is the kind of detail that shows a maintainer who ships many packages.
Editorial conclusion
jwt-hack suits a developer or security engineer who has a token and wants to know whether the implementation around it is safe, since the scan mode checks algorithm handling, secret strength, expiry claims and header injection points in one command, and it suits anyone building JWT support who needs to generate the awkward cases on purpose. It is the wrong tool if you want a JWT library, since it is a testing utility rather than an implementation, and it is the wrong tool for anything involving a token you do not own or have permission to test, since the crack and payload modes exist to break authentication. Before running it on your own service, use scan with a token you generated yourself, and treat any finding about a weak secret as a prompt to rotate the secret rather than as a way to keep the old one.
Frequently asked questions
How do I install jwt-hack?
Run cargo install jwt-hack, or use brew install jwt-hack, sudo snap install jwt-hack on Ubuntu, or choco install jwt-hack on Windows. Container images are published on GHCR and Docker Hub, and building from source means cloning the repository and running cargo install --path .
What does jwt-hack scan check for?
The scan mode checks for the none algorithm vulnerability, weak secrets against a common password list, algorithm confusion such as RS256 to HS256, missing or improper token expiration, missing recommended security claims, kid header injection that could reach SQL or a file path, and JKU or X5U header URL spoofing vectors.
How do I crack a weak JWT secret?
The crack mode does dictionary attacks with jwt-hack crack -w wordlist.txt JWT_TOKEN and brute force with jwt-hack crack -m brute JWT_TOKEN --max=4. Both forms also work on DEFLATE compressed tokens. The intended use is checking a secret you control.
Can jwt-hack run as a local API or for an AI model?
Yes. The server mode starts a REST API on http://localhost:3000 that can be protected with --api-key and the X-API-KEY header, and the MCP mode starts a Model Context Protocol server over stdio so an AI model can call the JWT functionality directly.
Which algorithms does jwt-hack verify?
Verification with a secret covers the HMAC algorithms HS256, HS384 and HS512, and verification with a private key covers asymmetric algorithms such as RS256, ES256 and EdDSA. Encoding supports secret based and key based signing with an explicit algorithm selection.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/hahwul-jwt-hack)Was this useful?