Detect insecure JWT (JSON Web Token) implementations in a codebase using a two-phase approach: first map all JWT issuance and verification sites to understand the token lifecycle and signing…
Install the "sast-jwt" agent skill from https://github.com/utkusen/sast-skills/tree/main/sast-files/.agents/skills/sast-jwt into .claude/skills/sast-jwt/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sast-jwt", then confirm the skill loads.
Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
skills CLI
$ npx skills add utkusen/sast-skills --skill sast-jwt -a codex
Project install goes to .agents/skills/; add -g for ~/.codex/skills/.
Install the "sast-jwt" agent skill from https://github.com/utkusen/sast-skills/tree/main/sast-files/.agents/skills/sast-jwt into .agents/skills/sast-jwt/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sast-jwt", then confirm the skill loads.
Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add utkusen/sast-skills --skill sast-jwt -a cursor
Project install goes to .agents/skills/; add -g for ~/.cursor/skills/.
Install the "sast-jwt" agent skill from https://github.com/utkusen/sast-skills/tree/main/sast-files/.agents/skills/sast-jwt into .cursor/skills/sast-jwt/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sast-jwt", then confirm the skill loads.
Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
skills CLI
$ npx skills add utkusen/sast-skills --skill sast-jwt -a gemini-cli
Project install goes to .agents/skills/; add -g for ~/.gemini/skills/.
Install the "sast-jwt" agent skill from https://github.com/utkusen/sast-skills/tree/main/sast-files/.agents/skills/sast-jwt into .gemini/skills/sast-jwt/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sast-jwt", then confirm the skill loads.
Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
GitHub CLI
$ gh skill install utkusen/sast-skills sast-jwt
Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
skills CLI
$ npx skills add utkusen/sast-skills --skill sast-jwt -a github-copilot
Project install goes to .agents/skills/; add -g for ~/.copilot/skills/.
Install the "sast-jwt" agent skill from https://github.com/utkusen/sast-skills/tree/main/sast-files/.agents/skills/sast-jwt into .github/skills/sast-jwt/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sast-jwt", then confirm the skill loads.
GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add utkusen/sast-skills --skill sast-jwt -a opencode
OpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
Install the "sast-jwt" agent skill from https://github.com/utkusen/sast-skills/tree/main/sast-files/.agents/skills/sast-jwt into .opencode/skills/sast-jwt/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sast-jwt", then confirm the skill loads.
OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Facts
Skill name
sast-jwt
GitHub stars
1.3k
Token cost
~6k tokens
SKILL.md length
2,376 words
Files
1
Skills in repo
16
Repo updated
First seen
Licence
MIT
At a glance
Detect insecure JWT (JSON Web Token) implementations in a codebase using a two-phase approach: first map all JWT issuance and verification sites to understand the token lifecycle and signing…
Works in 2 steps: Map the JWT Lifecycle → Analyze JWT Verification Sites for…
Asked to find JWT
SKILL.md covers What is an Insecure JWT…, Vulnerable vs. Secure Examples, Execution and Important Reminders
Reaches accounts.google.com; needs SECRET_KEY and JWT_SECRET
What it does
Sast JWT is an agent skill from utkusen/sast-skills. Detect insecure JWT (JSON Web Token) implementations in a codebase using a two-phase approach: first map all JWT issuance and verification sites to understand the token lifecycle and signing configuration, then check each verification site for exploitable weaknesses such as algorithm confusion, missing signature verification, weak secrets, header injection, and missing claim validation. Requires sast/architecture.md (run sast-analysis first). Outputs findings to sast/jwt-results.md. If no JWT usage is found in…
Its SKILL.md is about 6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Authentication and Static analysis and SAST. The repository describes itself as: Collection of agent skills to find vulnerabilities inside your web/mobile apps. The licence is MIT.
When your agent uses it
Asked to find JWT
Authentication bypass bugs
Example prompts
“/sast-jwt”
Requirements
Python 3
Node.js
A credential in SECRET_KEY
A credential in JWT_SECRET
Workflow steps
2 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit db52227. It shows what the files ask for, not the result of running them.
Tool permissions
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Runs code
No scripts in the folder and no shell commands in SKILL.md (its code samples are python, javascript, java, go and markdown).
From the folder's file list and the shell code blocks in SKILL.md.
Network
Hosts in commands or code, which the agent is likely to contact:
accounts.google.com
From URLs in SKILL.md, links to its own repository left out.
Credentials
Names these keys or tokens, usually read from environment variables:
SECRET_KEY
JWT_SECRET
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Context cost
Sast JWT loads about 6k tokens when it runs. Until then it costs about 157 tokens; SKILL.md has 2,376 words of instructions outside code blocks.
Always· name and description, kept in context so the agent knows when to use it
~157
When it runs· the whole SKILL.md, loaded when a task matches
~6k
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
Safety
Auto-check passed
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
Download SKILL.mdSave it as .claude/skills/sast-jwt/SKILL.md (or your agent's skills folder).
name
sast-jwt
description
Detect insecure JWT (JSON Web Token) implementations in a codebase using a two-phase approach: first map all JWT issuance and verification sites to understand the token lifecycle and signing configuration, then check each verification site for exploitable weaknesses such as algorithm confusion, missing signature verification, weak secrets, header injection, and missing claim validation. Requires sast/architecture.md (run sast-analysis first). Outputs findings to sast/jwt-results.md. If no JWT usage is found in Phase 1, Phase 2 is skipped. Use when asked to find JWT, token forgery, or authentication bypass bugs.
JWT Vulnerability Detection
You are performing a focused security assessment to find insecure JSON Web Token (JWT) implementations. This skill uses a two-phase approach with subagents: recon (map the full JWT lifecycle — issuance, verification, and configuration) then analysis (identify every exploitable weakness in those verification sites).
Prerequisites: sast/architecture.md must exist. Run the analysis skill first if it doesn't.
What is an Insecure JWT Implementation
JWTs consist of three Base64URL-encoded parts: header.payload.signature. The header declares the signing algorithm (alg), the payload carries claims (e.g., sub, role, exp), and the signature is a cryptographic proof of integrity. Vulnerabilities arise when the server trusts the token's own claims about how it was signed, fails to verify the signature at all, uses a guessable secret, or trusts attacker-controlled key material embedded in the token itself.
The core pattern: the server does not fully verify the JWT's authenticity and integrity before trusting its claims.
What JWT Vulnerabilities ARE
1. Algorithm confusion — alg: none
The server accepts a JWT whose header declares "alg": "none", bypassing signature verification entirely. An attacker crafts an arbitrary payload, sets alg to none, and omits the signature. If the library processes it, the forged token is accepted.
2. Algorithm confusion — RS256 → HS256
A server configured for RS256 (asymmetric: sign with private key, verify with public key) can be tricked into HS256 mode if the library allows the algorithm to be specified by the token. Since the public key is often retrievable, the attacker signs a forged token with HS256 using the server's public key as the HMAC secret. The server verifies the HMAC using the same public key and accepts the token.
3. Missing or disabled signature verification
The server decodes the JWT payload without actually verifying the signature. Common patterns:
Node.js (jsonwebtoken): jwt.decode(token) instead of jwt.verify(token, secret)
Manual base64 decode of the payload with no signature check
algorithms=["none"] accepted in the decode call
4. Weak or hardcoded HMAC secret
The server signs tokens with a short, guessable, or hardcoded secret (e.g., "secret", "password", "changeme", "jwt-secret-key"). An attacker who captures a valid token can brute-force the secret offline with tools like hashcat or jwt_tool, then forge arbitrary tokens.
5. Embedded JWK (jwk header injection)
The token header contains an embedded JSON Web Key (jwk parameter). If the verification code trusts the embedded key to verify the token's own signature, an attacker generates their own key pair, signs a forged token with their private key, and embeds their public key in the header. The server verifies the signature using the attacker's embedded public key and accepts the token.
6. JKU / X5U header injection
The jku (JWK Set URL) or x5u (X.509 certificate URL) header value is used to fetch the verification key from a URL. If the server does not validate the URL against an allowlist, the attacker can point it to their own server hosting a crafted key set.
7. Key ID (kid) header injection
The kid header is used to look up the signing key, often from a database or the filesystem. If the kid value is interpolated into a SQL query without sanitization, it becomes an SQL injection vector. If it is concatenated into a file path, it becomes a path traversal vector.
8. Missing claim validation
exp not checked → expired tokens remain valid forever
iss (issuer) not checked → tokens issued by other services are accepted
aud (audience) not checked → tokens intended for other services are accepted
nbf (not-before) not checked → tokens used before their valid window
9. No token revocation
There is no token blacklist or revocation mechanism. Stolen or logged-out tokens remain valid until they expire. This matters most when token lifetimes are long.
What JWT Vulnerabilities are NOT
Do not flag these as JWT vulnerabilities:
IDOR: Changing a user_id claim to access another user's data is an authorization flaw, not a JWT forgery — only flag if the token itself can be forged
XSS via JWT payload: Injecting <script> into a claim that is later rendered unescaped — that's XSS, not a JWT bug
CSRF: JWT in cookies without SameSite — that's a CSRF concern, not a JWT integrity issue
Properly restricted verification: jwt.verify(token, secret, { algorithms: ['HS256'] }) with a strong secret — not vulnerable
Patterns That Prevent JWT Vulnerabilities
1. Algorithm allowlist in verification call
python
# Python — PyJWT: explicitly specify allowed algorithms
payload = jwt.decode(token, secret, algorithms=["HS256"])
# Node.js — jsonwebtoken: restrict algorithms
jwt.verify(token, secret, { algorithms: ['HS256'] })
# Java — jjwt: specify expected algorithm
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token)
# (jjwt does not use the header's alg; it uses the key type)
2. Strong, randomly generated secret
python
# Strong secret: at least 256 bits of entropy, not hardcoded
import secrets
SECRET_KEY = secrets.token_hex(32) # load from env in production
// Use RS256 with public key for verification; never accept HS256 on the same endpoint
jwt.verify(token, publicKey, { algorithms: ['RS256'] })
5. JWK/JKU URL allowlist
python
# Only fetch keys from a known, trusted JWKS endpoint
ALLOWED_JWKS_URLS = {"https://accounts.google.com/.well-known/jwks.json"}
if jku not in ALLOWED_JWKS_URLS:
raise ValueError("Untrusted JWK URL")
// VULNERABLE: jwt.decode() — no signature verification
function getUser(token) {
const payload = jwt.decode(token); // decode only, never verify
return payload.userId;
}
// VULNERABLE: algorithms not restricted — susceptible to alg:none or RS256→HS256
function getUser(token) {
const payload = jwt.verify(token, SECRET); // no algorithms option
return payload.userId;
}
// VULNERABLE: weak hardcoded secret
const SECRET = "password123";
jwt.verify(token, SECRET, { algorithms: ['HS256'] });
// SECURE: algorithm restricted, strong secret from env
const SECRET = process.env.JWT_SECRET;
function getUser(token) {
const payload = jwt.verify(token, SECRET, { algorithms: ['HS256'] });
return payload.userId;
}
Java — jjwt
java
// VULNERABLE: deprecated parser (accepts alg from header)
Jwts.parser().setSigningKey(key).parseClaimsJws(token);
// VULNERABLE: no expiry check — the library default may not enforce exp
Claims claims = Jwts.parserBuilder()
.setSigningKey(key).build()
.parseClaimsJws(token).getBody();
// claims.getExpiration() never checked
// SECURE: parserBuilder (does not trust header alg; uses key type)
Claims claims = Jwts.parserBuilder()
.requireIssuer("myapp")
.requireAudience("myapp-api")
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
Go — golang-jwt / dgrijalva/jwt-go
go
// VULNERABLE: accepts any algorithm including "none"
token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(secret), nil // no algorithm check
})
// VULNERABLE: weak secret
var jwtKey = []byte("secret")
// SECURE: validate signing method before returning key
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return jwtKey, nil
})
kid header SQL injection
python
# VULNERABLE: kid used in SQL query without sanitization
def get_signing_key(kid):
result = db.execute(f"SELECT key FROM jwt_keys WHERE id = '{kid}'")
return result.fetchone()[0]
token_header = jwt.get_unverified_header(token)
key = get_signing_key(token_header["kid"]) # attacker controls kid
jwt.decode(token, key, algorithms=["HS256"])
# SECURE: kid validated against allowlist or parameterized lookup
def get_signing_key(kid):
result = db.execute("SELECT key FROM jwt_keys WHERE id = %s", (kid,))
row = result.fetchone()
if not row:
raise ValueError("Unknown key id")
return row[0]
Embedded JWK injection
javascript
// VULNERABLE: trusts the jwk embedded in the token header
const { publicKey } = getPublicKeyFromHeader(decoded.header); // attacker-supplied
jwt.verify(token, publicKey);
// SECURE: only use keys from a pre-configured, trusted source
const trustedKey = loadKeyFromConfig();
jwt.verify(token, trustedKey, { algorithms: ['RS256'] });
Execution
This skill runs in two phases using subagents. Pass the contents of sast/architecture.md to both subagents as context.
Phase 1: Map the JWT Lifecycle
Launch a subagent with the following instructions:
Goal: Map how the application creates, transmits, and verifies JWTs. Identify every JWT issuance and verification site, the library used, the signing algorithm and key/secret configuration, and the claims that are used for authorization. Write results to sast/jwt-recon.md.
Context: You will be given the project's architecture summary. Use it to understand the tech stack, authentication layer, and middleware patterns.
What to search for:
1. JWT library imports — identify which JWT library is in use:
Python: import jwt, from jose import, from authlib import, import python_jose
Node.js: require('jsonwebtoken'), import jwt from 'jsonwebtoken', jose, @nestjs/jwt
Note which routes are protected and which are unprotected
6. Signing secret / key configuration:
Where the HMAC secret or RSA/EC key is defined and loaded (env var, config file, hardcoded string)
Whether it looks strong (long random string) or weak (short, common word)
7. Claim usage:
Which claims are extracted and used for authorization (user_id, role, permissions, sub)
Whether exp, iss, aud, nbf are checked
Output format — write to sast/jwt-recon.md:
markdown
# JWT Recon: [Project Name]
## Summary
JWT is [used / not used] in this codebase.
Library: [library name and version if visible]
Algorithm(s): [HS256 / RS256 / etc.]
## Issuance Sites
### 1. [Descriptive name — e.g., "Token generation in login endpoint"]
- **File**: `path/to/file.ext` (lines X-Y)
- **Function / endpoint**: [function name or route]
- **Algorithm**: [e.g., HS256]
- **Secret/key source**: [env var name / hardcoded string / config key]
- **Claims set**: [list of claims added to the payload]
- **Code snippet**:
## Authorization Middleware Coverage
- **Protected routes**: [list or description]
- **Unprotected routes**: [list or "none observed"]
After Phase 1: Check for JWT Usage Before Proceeding
After Phase 1 completes, read sast/jwt-recon.md. If the summary states JWT is not used (no issuance or verification sites were found), skip Phase 2 entirely. Instead, write the following content to sast/jwt-results.md and stop:
markdown
# JWT Analysis Results
No JWT usage detected in this codebase.
Only proceed to Phase 2 if Phase 1 found at least one JWT verification site.
Show full SKILL.md (1,077 more words)Show less
Phase 2: Analyze JWT Verification Sites for Vulnerabilities
Launch a second subagent after Phase 1 completes with the following instructions:
Goal: For each JWT verification site in sast/jwt-recon.md, determine whether it is exploitable. Check for algorithm confusion, missing signature verification, weak secrets, header injection attacks, and missing claim validation. Write final results to sast/jwt-results.md.
Context: You will be given the project's architecture summary and the Phase 1 recon output. Use both to understand the full token lifecycle before analyzing each site.
For each verification site, check the following:
Check 1 — Algorithm restriction
Is the allowed algorithm explicitly specified in the verification call?
If no algorithm restriction is present, can the token's alg header be set to none to skip signature verification?
If the server uses an asymmetric algorithm (RS256, ES256), does the verification code also accept HMAC algorithms (HS256)? If so, the server may be vulnerable to the RS256→HS256 confusion attack.
Check 2 — Signature verification enabled
Is the token passed through a verify/parse call that actually checks the signature, or only through a decode-only call?
Look for options like verify_signature: False, complete=False, or the use of jwt.decode() (Node.js) instead of jwt.verify()
Manual base64-decode of the payload without any signature check is always vulnerable
Check 3 — HMAC secret strength
Is the secret hardcoded in source code? If so, is it a common word or short string?
Is the secret loaded from an environment variable or config? Even then, note if the default or example value is weak
A secret shorter than 32 characters or composed of dictionary words is likely brute-forceable
Does the verification code read the jwk field from the token header and use it to verify the same token?
Does the code fetch a key from a URL specified in the jku or x5u header without validating the URL against an allowlist?
If either is true, the verification is fully bypassable
Check 5 — kid header injection
Is the kid header value extracted from the token before verification and used to look up a key?
Is the kid value interpolated into a SQL query without parameterization? → SQL injection
Is the kid value used to construct a file path without sanitization? → path traversal / key substitution
Check 6 — Claim validation
Is exp (expiry) checked? If not, expired tokens are valid forever
Is iss (issuer) checked? If not, tokens from other issuers are accepted
Is aud (audience) checked? If not, tokens for other services are accepted
Are security-sensitive claims like role or permissions present but not validated against a server-side source?
Check 7 — Token revocation
Is there a token blacklist, revocation endpoint, or short-lived token + refresh-token pattern?
If tokens are long-lived (hours or more) with no revocation mechanism, stolen tokens remain valid
Classification:
Vulnerable: The weakness is clearly present with no effective mitigation — the attack path is directly exploitable.
Likely Vulnerable: The weakness is probably present but requires confirming a secondary condition (e.g., library version behavior, default option value).
Not Vulnerable: The implementation correctly addresses this check.
Needs Manual Review: Cannot determine the vulnerability status with confidence from static analysis alone.
Output format — write to sast/jwt-results.md:
markdown
# JWT Analysis Results: [Project Name]
## Executive Summary
- Verification sites analyzed: [N]
- Vulnerable: [N]
- Likely Vulnerable: [N]
- Not Vulnerable: [N]
- Needs Manual Review: [N]
## Findings
### [VULNERABLE] Descriptive name
- **File**: `path/to/file.ext` (lines X-Y)
- **Endpoint / function**: [route or function name]
- **Vulnerability class**: [e.g., "Missing signature verification" / "alg:none accepted" / "Weak HMAC secret" / "JWK header injection" / "kid SQL injection" / "Missing exp validation"]
- **Issue**: [Clear description of what is wrong]
- **Attack scenario**: [Step-by-step: what the attacker does, what token they craft or modify, what access they gain]
- **Impact**: [What an attacker can achieve — forge arbitrary identity, escalate privileges, access other users' data, etc.]
- **Remediation**: [Specific fix — add algorithms restriction, enable verify_signature, load secret from env, pin JWKS URL, parameterize kid lookup, add exp validation, etc.]
- **Dynamic Test**:
[Proof-of-concept using jwt_tool, hashcat, or curl.
Show the exact command to reproduce the issue.
Examples:
jwt_tool <token> -X a (test alg:none)
jwt_tool <token> -X s (test RS256→HS256 confusion)
hashcat -a 0 -m 16500 <token> wordlist.txt (brute-force HMAC secret)
Manual: modify payload, set alg:none, send to endpoint]
### [LIKELY VULNERABLE] Descriptive name
- **File**: `path/to/file.ext` (lines X-Y)
- **Endpoint / function**: [route or function name]
- **Vulnerability class**: [class]
- **Issue**: [What appears to be wrong]
- **Uncertainty**: [What needs to be confirmed — e.g., "Library version determines default behavior"]
- **Remediation**: [Fix]
- **Dynamic Test**:
[payload or command to attempt exploitation]
### [NOT VULNERABLE] Descriptive name
- **File**: `path/to/file.ext` (lines X-Y)
- **Endpoint / function**: [route or function name]
- **Reason**: [e.g., "Algorithm restricted to HS256 with strong env-loaded secret; exp validated"]
### [NEEDS MANUAL REVIEW] Descriptive name
- **File**: `path/to/file.ext` (lines X-Y)
- **Endpoint / function**: [route or function name]
- **Uncertainty**: [Why the vulnerability status cannot be determined statically]
- **Suggestion**: [What to inspect manually — e.g., "Confirm what JWT library version is installed; older versions of PyJWT accept alg:none by default"]
Important Reminders
Read sast/architecture.md and pass its content to both subagents as context.
Phase 2 must run AFTER Phase 1 completes — it depends on the recon output.
Phase 1 is purely discovery: locate every JWT issuance, verification, and configuration site. Do not attempt to assess security in Phase 1 — that is Phase 2's job.
Phase 2 is purely analysis: for each verification site found in Phase 1, systematically check every vulnerability class. Do not search for new sites in Phase 2 — focus on what Phase 1 found.
If no JWT usage is found in Phase 1, skip Phase 2 entirely and write a "No JWT usage detected" result file.
The most critical checks are: signature verification disabled, algorithm not restricted (alg:none / RS256→HS256 confusion), and weak or hardcoded HMAC secret. These lead directly to full authentication bypass.
jwt.decode() in Node.js's jsonwebtoken library is a decode-only function — it never verifies the signature. Only jwt.verify() validates the signature. Confusing the two is a common and critical mistake.
In Python's PyJWT, versions before 2.0 accepted alg: none by default and did not require an algorithms parameter. If the codebase does not pin the version or restrict algorithms, flag it.
Algorithm confusion (RS256→HS256) requires: (a) the server uses RS256 with a key pair, (b) the public key is accessible, and (c) the verification code does not restrict the algorithm. All three must be present.
kid injection is often overlooked: always check how the key lookup is implemented when kid is present in the token header.
When in doubt, classify as "Needs Manual Review" rather than "Not Vulnerable". False negatives are worse than false positives in security assessment.
Sast JWT next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
Enriches an existing CycloneDX BOM with occurrence, callstack, reachability, data-flow, and crypto-flow evidence using cdxgen evinse, including Go analysis via Golem and Rust analysis via Rusi, and…
Detect GraphQL injection vulnerabilities in a codebase using a three-phase approach: recon (confirm GraphQL usage and find unsafe operation document assembly sites), batched verify (trace user input…
Detect Insecure Direct Object Reference (IDOR) vulnerabilities in a codebase using a three-phase approach: recon (find candidates), batched verify (check authorization in parallel subagents, 3…
Detect business logic vulnerabilities in a codebase using a three-phase approach: threat modeling (domain analysis and attack scenarios), batched verify (check exploitable gaps in parallel…
Detect insecure file upload vulnerabilities in a codebase using a three-phase approach: discovery (find all upload sites), batched verify (check extension bypass and related issues in parallel…
Detect insecure JWT (JSON Web Token) implementations in a codebase using a two-phase approach: first map all JWT issuance and verification sites to understand the token lifecycle and signing…. Sast JWT is an agent skill from utkusen/sast-skills. Detect insecure JWT (JSON Web Token) implementations in a codebase using a two-phase approach: first map all JWT issuance and verification sites to understand the token lifecycle and signing configuration, then check each verification site for exploitable weaknesses such as algorithm confusion, missing signature verification, weak secrets, header injection, and missing claim validation.
Run `npx skills add utkusen/sast-skills --skill sast-jwt -a claude-code`. Or copy the skill folder (sast-files/.agents/skills/sast-jwt in utkusen/sast-skills) into .claude/skills/sast-jwt in your project. Claude Code loads it when a task matches its description.
How do I install Sast JWT in Codex?
Run `npx skills add utkusen/sast-skills --skill sast-jwt -a codex`. Or copy the skill folder (sast-files/.agents/skills/sast-jwt in utkusen/sast-skills) into .agents/skills/sast-jwt in your project. Codex loads it when a task matches its description.
Can I use Sast JWT in Cursor, Gemini CLI or GitHub Copilot?
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add utkusen/sast-skills --skill sast-jwt -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sast-jwt, .gemini/skills/sast-jwt, .github/skills/sast-jwt and .opencode/skills/sast-jwt in your project.
What does Sast JWT need to run?
Going by SKILL.md and its folder, Sast JWT needs credentials named SECRET_KEY and JWT_SECRET. Our summary lists: Python 3; Node.js; A credential in SECRET_KEY; A credential in JWT_SECRET.
Does Sast JWT access the network?
SKILL.md names 1 domain. In commands or code: accounts.google.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Is Sast JWT safe to install?
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
What licence does Sast JWT use?
Sast JWT is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
How many tokens does Sast JWT use?
About 6k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
What are the alternatives to Sast JWT?
Skills that share tags, products or a category with Sast JWT: Security Review (doorkeeper-gem/doorkeeper, 5.5k stars), Svc Mobile Android (s0ld13rr/pentestcode, 828 stars), Hunt Session (sickn33/agentic-awesome-skills, 47k stars) and Security Devsecops (Mindrally/skills, 269 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Who maintains Sast JWT?
utkusen (a GitHub user) maintains it in utkusen/sast-skills, which has 1,329 GitHub stars. The repository holds 16 skills in this directory. The repository was last updated on April 8, 2026.
Source: utkusen/sast-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.