Authorization vulnerabilities are the most common critical finding in our API penetration tests. We find them on nearly every engagement: a user changes an ID in the URL and gets back another user’s data. Broken Object Level Authorization (BOLA) has been the #1 risk on the OWASP API Security Top 10 since the list was created. It’s simple to understand, simple to exploit, and tedious to test comprehensively.
The problem isn’t knowing what to look for. It’s doing it at scale. An API with 50 authenticated endpoints and four user roles produces hundreds of attacker-victim permutations, each requiring the right auth token, the right resource ID, and careful evaluation of the response. We kept doing this manually, and it didn’t scale. So we built Hadrian.
Hadrian is an open-source API authorization testing framework for REST, GraphQL, and gRPC APIs. Give it an API spec, define your roles and auth tokens, and it systematically tests every endpoint for authorization bypass, broken authentication, excessive data exposure, and more. It ships with 30 built-in security templates, supports three-phase mutation testing to prove write/delete vulnerabilities, and includes optional LLM-powered triage. Get it at github.com/praetorian-inc/hadrian.
Why Existing Tools Don’t Solve This
The tools security engineers currently rely on for API authorization testing work at the wrong level of abstraction.
Autorize, the most popular Burp Suite extension for this problem, passively monitors your traffic and replays requests with a lower-privileged token. It’s useful, but it only tests what you click on. If you browse 30 of those 50 endpoints during your session, Autorize tests 30. The other 20 are untested. It also has no concept of role hierarchy. It swaps one cookie for another and compares response lengths, which produces false positives on any API that returns different-sized payloads per user.
AuthMatrix improves on this by letting you define roles and mark which endpoints each role should access. But you still manually add every request, configure regex-based detection rules, and maintain the matrix as the API evolves. For a 50-endpoint API with four roles, that’s 200 cells to configure by hand.
Neither tool reads an API specification. They don’t generate role-pair permutations automatically. GraphQL and gRPC support is also missing. And critically, neither can prove that a write or delete operation actually succeeded. They only compare responses.
Hadrian approaches the problem differently. It reads the API spec, loads role definitions with explicit privilege levels, and generates every attacker-victim permutation automatically. The permutation engine is the core of the tool: given an OpenAPI file with 50 endpoints and a roles file with four privilege levels, Hadrian generates and executes every relevant API authorization test without manual configuration.
How It Works
Hadrian takes three inputs: an API specification, a roles definition, and authentication credentials. You can also provide custom test templates for application-specific logic beyond the 30 built-in checks.
hadrian test rest \
--api api.yaml \
--roles roles.yaml \
--auth auth.yaml \
--category all
[INFO] Loaded 8 templates
[INFO] Testing 44 operations against 4 roles
[HIGH] BOLA - Cross-User Resource Access (API1:2023)
Endpoint: GET /api/users/{id}
[CRITICAL] BFLA - Unauthorized Admin Function Access (API5:2023)
Endpoint: DELETE /api/users/{id}
============================================================
HADRIAN SCAN SUMMARY
============================================================
Operations: 44
Templates: 8
Total Findings: 2
Findings by Severity:
CRITICAL 1
HIGH 1
The roles file defines privilege levels and permissions using an action:object:scope format. The level field establishes explicit ordering—Hadrian uses it to automatically generate attacker/victim pairs where lower-privileged roles test access to higher-privileged roles’ resources:
roles:
- name: admin
level: 100
permissions:
- "read:users:all"
- "write:users:all"
- "delete:users:all"
- name: user
level: 10
permissions:
- "read:users:own"
- "write:posts:own"
- name: guest
level: 0
permissions: []
Security tests are defined as YAML templates. Each template specifies which endpoints to target (based on HTTP method, path parameters, auth requirements), which role pairs to test, and what response patterns indicate a vulnerability. Hadrian ships with 30 templates covering all the authorization vulnerabilities in OWASP Top 10 for APIs and more.
Proving Write Vulnerabilities with Mutation Testing
Reading another user’s data is one thing. Deleting their resources is another. The problem with testing write and delete operations is that a 200 OK response doesn’t prove the action was actually performed. We’ve encountered APIs that return success codes regardless of whether the authorization check passed, APIs that queue operations asynchronously, and APIs that silently swallow unauthorized requests.
Hadrian addresses this with three-phase mutation testing:
- Setup (as victim): Create a resource, store its ID
- Attack (as attacker): Attempt to modify or delete the victim’s resource
- Verify (as victim): Confirm whether the resource was actually changed
Phase 1: SETUP → Victim creates resource → {"user_id": "abc-456"}
Phase 2: ATTACK → Attacker deletes /users/abc-456 → Status 200
Phase 3: VERIFY → Victim reads /users/abc-456 → Status 404
✓ VULNERABILITY: Attacker deleted victim's resource
Three API Protocols, One Tool
Most API security testing tools focus exclusively on REST. But we regularly encounter applications running REST for their public API, GraphQL for their frontend, and gRPC for internal service-to-service communication. Testing each protocol currently means different tools, different expertise, and for gRPC, usually no automated tooling at all.
Hadrian supports all three under a unified framework:
# REST (via OpenAPI spec)
hadrian test rest --api api.yaml --roles roles.yaml --auth auth.yaml --category all
# GraphQL (via introspection or SDL schema)
hadrian test graphql --target https://api.example.com --auth auth.yaml --roles roles.yaml --template-dir templates/graphql
# gRPC (via proto file)
hadrian test grpc --target localhost:50051 --proto service.proto --auth auth.yaml --roles roles.yaml
Each protocol gets tests designed for its specific attack surface. GraphQL templates cover introspection disclosure, query depth attacks, alias-based DoS, batching attacks, circular fragment abuse, and directive overloading. These vulnerability classes don’t exist in REST. gRPC templates handle status code-based detection, metadata injection, and deadline manipulation.
Assessment Workflow Integration
Hadrian was designed to bring scalable API authorization testing into the offensive security projects that Praetorian conducts every day. It can be run either from your command line, or imported programmatically as a Go module in your tool or system of choice.
All traffic routes through Burp Suite or any HTTP proxy with --proxy, so you can verify findings manually and capture request/response pairs for your report. Adaptive rate limiting (default 5 req/sec) with reactive backoff on 429/503 responses means you won’t get yourself blocked during a client assessment. --dry-run shows exactly what Hadrian would test without sending a single request, which is useful for scoping conversations with clients.
For finding triage, Hadrian optionally sends results to a local Ollama instance for LLM-powered analysis. It redacts credentials before sending data to the model, so client tokens never leave the machine. Using the LLM-powered analysis is useful for quickly sorting true-positives from edge cases on large APIs:
hadrian test rest --api api.yaml --roles roles.yaml \
--llm-host http://localhost:11434 --llm-model llama3.2:latest \
--llm-context "This API handles financial data with PCI DSS requirements"
One thing worth noting: Hadrian requires an API specification (OpenAPI, GraphQL schema, or proto file) and valid auth tokens for each role. It doesn’t discover APIs or generate credentials. On engagements where we don’t have a spec, we typically build one from Burp traffic or use API documentation, then point Hadrian at it.
The Praetorian Offensive Toolkit
Hadrian joins our open-source security toolkit. In a typical external assessment, Nerva identifies services on discovered ports, including API endpoints. Hadrian tests those APIs for authorization flaws. Findings from both feed into the final report. For cloud-focused engagements, Aurelian maps the cloud environment and discovers API Gateways, then the APIs behind them get tested with Hadrian. Each tool handles a distinct phase of security work: Pius for asset discovery, Nerva for service fingerprinting, Brutus for credential testing, Trajan for CI/CD pipeline security, Aurelian for cloud reconnaissance, and Hadrian for API authorization testing. If you’re interested in using Hadrian to help secure your company’s APIs, you can learn more about our Praetorian Guard Platform at praetorian.com.
Getting Started
Start running API authorization testing today. Hadrian is available now at github.com/praetorian-inc/hadrian. Install from source or grab a prebuilt binary from the releases page.
go install github.com/praetorian-inc/hadrian/cmd/hadrian@latest
The repository includes intentionally vulnerable test applications for REST (crAPI), GraphQL (DVGA), and gRPC (built-in vulnerable server) so you can see Hadrian in action before pointing it at a real target.
If you find bugs, want to contribute templates, or have feature requests, open an issue. We’re actively developing Hadrian and want to hear how you’re using it.
Frequently Asked Questions
What is Hadrian?
Hadrian is an open-source API authorization testing framework built by Praetorian. It automates the detection of authorization vulnerabilities like BOLA (Broken Object Level Authorization) and BFLA (Broken Function Level Authorization) across REST, GraphQL, and gRPC APIs using role-based permutation testing and YAML-driven security templates.
What types of API vulnerabilities does Hadrian detect?
Hadrian ships with 30 built-in security templates covering the OWASP API Security Top 10, including Broken Object Level Authorization (API1:2023), Broken Authentication (API2:2023), Broken Object Property Level Authorization (API3:2023), Broken Function Level Authorization (API5:2023), and excessive data exposure. Custom templates can be added for application-specific logic.
How is Hadrian different from Autorize or AuthMatrix?
Autorize and AuthMatrix are Burp Suite extensions that require manual browsing or configuration. Autorize only tests endpoints you visit during your session, and AuthMatrix requires manually configuring a matrix of roles and endpoints. Hadrian reads the API specification directly, generates every attacker-victim role permutation automatically, and supports GraphQL and gRPC in addition to REST. It also uses three-phase mutation testing to prove write/delete vulnerabilities actually succeeded.
Does Hadrian support GraphQL and gRPC APIs?
Yes. Hadrian supports REST (via OpenAPI specs), GraphQL (via introspection or SDL schema), and gRPC (via proto files) under a unified testing framework. Each protocol gets vulnerability templates designed for its specific attack surface, including GraphQL-specific checks like query depth attacks, batching abuse, and circular fragment exploitation.
What is three-phase mutation testing?
Mutation testing is Hadrian’s method for proving that write and delete vulnerabilities actually succeeded. Phase 1 (Setup) creates a resource as the victim. Phase 2 (Attack) attempts to modify or delete that resource as the attacker. Phase 3 (Verify) checks whether the resource was actually changed. This eliminates false positives from APIs that return 200 OK without actually performing the unauthorized action.
Can Hadrian be integrated into CI/CD pipelines?
Hadrian can be imported as a Go module and run programmatically, making it suitable for CI/CD integration. It also supports --dry-run for scoping, --proxy for routing through Burp Suite, and adaptive rate limiting to avoid triggering WAF blocks during automated testing. All output is structured for easy parsing and integration with existing security workflows.
