Skip to content

This Burp Suite extension allows you to configure multiple rules to automatically create issues based on JWT claims and their values.

License

Notifications You must be signed in to change notification settings

castlebbs/BurpJWTChecker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BurpJWTChecker - Burp Suite Extension

Build Status

A powerful and flexible Burp Suite extension for detecting security issues in JWT (JSON Web Tokens). This extension acts as a Swiss Army knife for JWT security testing by allowing you to configure multiple rules to automatically create issues based on JWT claims and their values.

Author

Created by David Robert ([email protected])

Features

  • Configurable Rules: Define multiple rules to check different JWT claims
  • Flexible Matching: Support for various match types (equals, contains, startsWith, endsWith, regex)
  • Custom Issues: Configure issue name, description, background, remediation, and severity for each rule
  • Passive Scanning: Automatically checks JWT tokens in HTTP requests during passive scanning
  • Easy Configuration: Simple JSON-based configuration file
  • Built-in Rules: Ships with example rules:
    • Microsoft Graph API audience detection
    • Weak/no algorithm detection (none, HS256)
    • Custom claim validation

What This Extension Does

The JWT Checker is a passive scanner that:

  1. Monitors HTTP requests for JWT tokens in the Authorization header (Bearer tokens)
  2. Decodes and analyzes the JWT (without validating the signature, validating tokens is NOT the goal of this extension)
  3. Applies configured rules to check various JWT claims (audience, algorithm, issuer, etc.)
  4. Creates Burp Suite issues when rules match, with customizable severity levels
  5. Provides detailed information about detected security concerns

This makes it ideal for:

  • Detecting misconfigured OAuth/OIDC tokens
  • Identifying weak JWT algorithms
  • Finding tokens with unexpected audience, other other claims values for your organization
  • Validating custom security requirements for JWT tokens

Installation

Prerequisites

  • Burp Suite (Professional Edition)
  • Java 17 or higher
  • Maven 3.6 or higher (for building from source)

Building from Source

  1. Clone the repository:

    git clone https://github.com/castlebbs/BurpJWTChecker.git
    cd BurpJWTChecker
  2. Build the extension using Maven:

    mvn clean package
  3. The compiled JAR file will be located at:

    target/jwt-checker-1.0.0-jar-with-dependencies.jar
    

Loading the Extension in Burp Suite

  1. Open Burp Suite
  2. Go to Extensions tab
  3. Click Add
  4. Select Extension type: Java
  5. Click Select file and choose the JAR file from the target directory
  6. Click Next
  7. The extension should load successfully. Check the Output tab for confirmation messages.

Configuration

Configuration File Location

The extension looks for configuration files in the following order:

  1. User configuration: ~/.burp/jwt-checker-config.json (on Linux/Mac) or C:\Users\<username>\.burp\jwt-checker-config.json (on Windows)
  2. Default configuration: Embedded in the JAR file (src/main/resources/config.json)

If a user configuration file exists, it takes precedence over the default configuration.

Configuration File Format

The configuration file is a JSON file with the following structure:

{
  "rules": [
    {
      "name": "rule-identifier",
      "claimName": "claim-to-check",
      "matchType": "matching-strategy",
      "matchValue": "value-to-match",
      "issueName": "Issue Title",
      "issueDetail": "Short description",
      "issueBackground": "Detailed background information",
      "issueRemediation": "How to fix this issue",
      "severity": "CRITICAL|HIGH|MEDIUM|LOW|INFO",
      "enabled": true
    }
  ]
}

Configuration Parameters

Parameter Description Required Values
name Unique identifier for the rule Yes String
claimName JWT claim to check (e.g., "aud", "alg", "iss", "sub") Yes String
matchType How to match the claim value Yes equals, contains, startsWith, endsWith, regex
matchValue Value to match against Yes String
issueName Title of the issue in Burp Suite Yes String
issueDetail Short summary of the issue Yes String
issueBackground Detailed explanation of why this is an issue Yes String
issueRemediation Recommendations for fixing the issue Yes String
severity Issue severity level Yes CRITICAL, HIGH, MEDIUM, LOW, INFO
enabled Whether the rule is active Yes true or false

Note: Burp Suite does not have a separate "CRITICAL" severity level, so CRITICAL is mapped to HIGH severity.

Special Claim Names

  • alg: JWT algorithm (from header) - e.g., "RS256", "HS256", "none"
  • aud: Audience claim - can be a string or array
  • Any other standard or custom JWT claim from the payload

Match Types

  • equals: Exact string match (case-sensitive)
  • contains: Value contains the match string (case-sensitive)
  • startsWith: Value starts with the match string (case-sensitive)
  • endsWith: Value ends with the match string (case-sensitive)
  • regex: Regular expression matching (supports all Java regex patterns including case-insensitive matching)

Example Configuration

Here's an example configuration with multiple rules:

{
  "rules": [
    {
      "name": "graph-api-audience",
      "claimName": "aud",
      "matchType": "contains",
      "matchValue": "00000003-0000-0000-c000-000000000000",
      "issueName": "Graph API Audience Value Detected",
      "issueDetail": "The JWT token contains a Graph API Audience: 00000003-0000-0000-c000-000000000000",
      "issueBackground": "The JWT token in the Authorization header contains a Graph API Audience '00000003-0000-0000-c000-000000000000'. This specific audience value is commonly associated with Microsoft Graph API access tokens. If not intended, this could indicate potential security misconfigurations or token misuse.",
      "issueRemediation": "Verify that the use of this audience value is intended for this application. If not expected, investigate potential token misuse or OAuth misconfiguration.",
      "severity": "HIGH",
      "enabled": true
    },
    {
      "name": "none-algorithm",
      "claimName": "alg",
      "matchType": "regex",
      "matchValue": "(?i)^none$",
      "issueName": "JWT with 'none' Algorithm Detected",
      "issueDetail": "The JWT token uses the 'none' algorithm (case-insensitive), which means it is not signed.",
      "issueBackground": "The JWT token in the Authorization header uses the 'none' algorithm. This means the token is not cryptographically signed and can be easily tampered with. Using the 'none' algorithm in production environments is a critical security vulnerability as it allows attackers to forge tokens. This rule matches 'none', 'NONE', 'None', and any other case variation.",
      "issueRemediation": "Ensure that all JWT tokens are properly signed using a secure algorithm such as RS256, ES256, or HS256. Never accept tokens with the 'none' algorithm in production.",
      "severity": "CRITICAL",
      "enabled": true
    },
    {
      "name": "weak-hmac-algorithm",
      "claimName": "alg",
      "matchType": "equals",
      "matchValue": "HS256",
      "issueName": "JWT with HMAC Algorithm Detected",
      "issueDetail": "The JWT token uses the HS256 (HMAC) algorithm for signing.",
      "issueBackground": "The JWT token in the Authorization header uses the HS256 algorithm. While HMAC algorithms are not inherently insecure, they can be problematic in certain scenarios. HMAC uses a symmetric key, meaning the same key is used for both signing and verification. This can lead to security issues if the key is shared with untrusted parties or if algorithm confusion attacks are possible.",
      "issueRemediation": "Consider using asymmetric algorithms like RS256 or ES256 for better security, especially in scenarios where the token verifier should not have access to the signing key. Ensure proper key management practices are in place if continuing to use HMAC.",
      "severity": "MEDIUM",
      "enabled": true
    },
    {
      "name": "custom-issuer-check",
      "claimName": "iss",
      "matchType": "equals",
      "matchValue": "https://suspicious-issuer.com",
      "issueName": "Suspicious JWT Issuer Detected",
      "issueDetail": "The JWT token was issued by a potentially untrusted issuer.",
      "issueBackground": "The JWT token contains an issuer (iss) claim that matches a known suspicious domain. This could indicate token forgery or misconfiguration.",
      "issueRemediation": "Verify the JWT issuer is the expected authorization server. Implement proper issuer validation in your application.",
      "severity": "HIGH",
      "enabled": false
    }
  ]
}

Customizing Rules

To create your own rules:

  1. Create a configuration file at ~/.burp/jwt-checker-config.json
  2. Add rules following the format described above
  3. Reload the extension in Burp Suite or restart Burp

Example: Checking for Specific Scopes

{
  "rules": [
    {
      "name": "admin-scope-check",
      "claimName": "scope",
      "matchType": "contains",
      "matchValue": "admin",
      "issueName": "JWT with Admin Scope Detected",
      "issueDetail": "Token contains administrative privileges",
      "issueBackground": "The JWT token includes an 'admin' scope, granting elevated privileges.",
      "issueRemediation": "Review whether this level of access is necessary and properly controlled.",
      "severity": "MEDIUM",
      "enabled": true
    }
  ]
}

Regular Expression (Regex) Examples

The regex match type provides powerful pattern matching capabilities using Java's regular expression syntax. Here are common use cases and examples:

Case-Insensitive Matching

Use the (?i) flag to match regardless of case:

{
  "name": "none-algorithm-any-case",
  "claimName": "alg",
  "matchType": "regex",
  "matchValue": "(?i)none",
  "issueName": "JWT with 'none' Algorithm Detected",
  "issueDetail": "The JWT token uses the 'none' algorithm (any case variation)",
  "issueBackground": "Matches 'none', 'NONE', 'None', 'NoNe', etc.",
  "issueRemediation": "Use a secure signing algorithm.",
  "severity": "HIGH",
  "enabled": true
}

Multiple Values (OR Logic)

Match any of several possible values:

{
  "name": "weak-algorithms",
  "claimName": "alg",
  "matchType": "regex",
  "matchValue": "(?i)(none|hs256|hs384|hs512)",
  "issueName": "Weak or No Algorithm Detected",
  "issueDetail": "JWT uses a weak symmetric algorithm or no algorithm",
  "issueBackground": "The token uses HMAC or no algorithm, which may be insecure",
  "issueRemediation": "Use asymmetric algorithms like RS256 or ES256",
  "severity": "HIGH",
  "enabled": true
}

Pattern Matching with Wildcards

Match patterns with variable content:

{
  "name": "test-environment-issuer",
  "claimName": "iss",
  "matchType": "regex",
  "matchValue": "https?://.*\\.(test|dev|staging)\\..*",
  "issueName": "Test Environment Issuer in Production",
  "issueDetail": "JWT issued by a test/dev/staging environment",
  "issueBackground": "The issuer URL contains test, dev, or staging subdomain",
  "issueRemediation": "Ensure production uses production issuers only",
  "severity": "MEDIUM",
  "enabled": true
}

Email Domain Validation

Validate that email claims belong to specific domains:

{
  "name": "external-email-domain",
  "claimName": "email",
  "matchType": "regex",
  "matchValue": ".*@(?!yourcompany\\.com$).*",
  "issueName": "External Email Domain Detected",
  "issueDetail": "JWT contains email from external domain",
  "issueBackground": "The email claim is not from yourcompany.com",
  "issueRemediation": "Verify external users have appropriate access",
  "severity": "LOW",
  "enabled": true
}

UUID or GUID Pattern Matching

Match specific formats like UUIDs:

{
  "name": "azure-ad-audience",
  "claimName": "aud",
  "matchType": "regex",
  "matchValue": "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}",
  "issueName": "Azure AD Audience Format Detected",
  "issueDetail": "JWT audience uses UUID format typical of Azure AD",
  "issueBackground": "The audience claim matches UUID pattern used by Azure AD",
  "issueRemediation": "Verify the audience is the expected Azure AD resource",
  "severity": "INFO",
  "enabled": true
}

Starts With (Regex Alternative)

Case-insensitive prefix matching:

{
  "name": "internal-scope-prefix",
  "claimName": "scope",
  "matchType": "regex",
  "matchValue": "(?i)^internal\\..*",
  "issueName": "Internal Scope Detected",
  "issueDetail": "JWT contains scope starting with 'internal.'",
  "issueBackground": "Scopes with internal prefix may grant elevated access",
  "issueRemediation": "Review internal scope usage and permissions",
  "severity": "MEDIUM",
  "enabled": true
}

Complex Patterns with Character Classes

Match specific character patterns:

{
  "name": "short-subject-id",
  "claimName": "sub",
  "matchType": "regex",
  "matchValue": "^[0-9]{1,5}$",
  "issueName": "Short Numeric Subject ID",
  "issueDetail": "JWT subject is a short numeric value",
  "issueBackground": "Short numeric IDs may be predictable or enumerable",
  "issueRemediation": "Consider using longer, non-sequential identifiers",
  "severity": "LOW",
  "enabled": true
}

Regex Tips

  • Escaping: Remember to escape special characters with double backslashes in JSON (e.g., \\. for a literal dot)
  • Anchors: Use ^ for start of string and $ for end of string
  • Flags: Use (?i) for case-insensitive, (?m) for multiline
  • Testing: Test your regex patterns with tools like regex101.com before deployment
  • Performance: Complex regex patterns may impact scanning performance; keep patterns as simple as possible

Troubleshooting

Extension Not Loading

  • Verify Java version (must be 17 or higher)
  • Check Burp's extension output tab for error messages
  • Ensure the JAR file is the -jar-with-dependencies version

Rules Not Triggering

  • Check that rules are enabled ("enabled": true)
  • Verify the claim name matches exactly (case-sensitive)
  • Ensure the match type and value are correct
  • Check Burp's extension output tab for debugging information

Configuration Not Loading

  • Verify the configuration file path
  • Ensure the JSON is valid (use a JSON validator)
  • Check file permissions
  • Review Burp's extension error log

Development

Project Structure

.
├── src/
│   └── main/
│       ├── java/
│       │   └── burp/
│       │       ├── JWTChecker.java                # Main extension class
│       │       ├── ConfigLoader.java              # Configuration loader
│       │       └── model/
│       │           ├── CheckConfig.java           # Configuration model
│       │           └── Rule.java                  # Rule model
│       └── resources/
│           └── config.json                        # Default configuration
├── pom.xml                                        # Maven configuration
└── README.md                                      # This file

Dependencies

Runtime Dependencies

  • Burp Montoya API (2025.8): Burp Suite extension API
  • java-jwt (Auth0) (4.5.0): JWT decoding library
  • Gson (2.13.2): JSON parsing library

Testing Dependencies

  • JUnit Jupiter (5.14.0): Testing framework for writing and running tests
  • Mockito Core (5.20.0): Mocking framework for unit tests
  • Mockito JUnit Jupiter (5.20.0): Integration between Mockito and JUnit 5
  • AssertJ (3.26.3): Fluent assertions library for more readable test assertions

Building for Development

# Clean and compile
mvn clean compile

# Run tests (when available)
mvn test

# Package the extension
mvn package

# Clean build artifacts
mvn clean

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For issues, questions, or feature requests, please open an issue on GitHub.

About

This Burp Suite extension allows you to configure multiple rules to automatically create issues based on JWT claims and their values.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages