GraphQl API Security - Part 2: GraphQL Attack Surface
GraphQL Attack Surface ๐ณ๏ธ๐
What Is an Attack Surface?
An attack surface is the set of all points where an unauthorized user can try to access or affect the system. Think of it like the doors, windows, and vents in a building that an intruder might exploit.
In GraphQL:
- ๐งฌ Every field, argument, type, and directive increases the attack surface.
- ๐ฅ The complexity and flexibility of GraphQL = greater potential for abuse.
๐ง The GraphQL Language: From Client to Server
The GraphQL spec is divided into two parts:
- Language โ what clients write (queries, mutations, etc.)
- Type System โ what the server defines and validates against
Anatomy of a GraphQL Query
1query Anatomy {
2pastes(filter: "some title", public: true) {
3 title
4 content
5 ipAdrr @show_network(style: "cidr")
6}
7users {
8 username(capitalize: true)
9}
10}| # | Component | Description |
|---|---|---|
| 1 | Operation type | query, mutation, or subscription |
| 2 | Operation name | Arbitrary label like getPastes, can mislead logs |
| 3 | Top-level field | Function returning object/data |
| 4 | Argument | Parameter passed to field (e.g., filter) |
| 5 | Value | Value assigned to argument |
| 6 | Field | Nested information requests |
| 7 | Directive | Executes conditionally or alters behavior (e.g., @skip) |
| 8 | Arg of Directive | Argument passed to the directive |
| 9 | Arg of Field | Field-specific parameters |
๐ Operation Types
1. query
- Basic data retrieval. Often abused to extract sensitive fields.
2. mutation
- Allows data modification. Risk: tampering with logic/data.
1mutation {
2editPaste(id: 1, content: "Hacked!") {
3 paste { id title content }
4}
5}3. subscription
- Real-time data over WebSocket. Vulnerable to:
- CSWSH (Cross-Site WebSocket Hijacking)
- MITM attacks if not using TLS
๐ญ Operation Names: Masking Malicious Intents
Operation names are arbitrary:
1query getPastes { pastes { title } }
2query deleteAll { pastes { content } }A malicious actor can name destructive queries with innocent names to mislead defenders.
Dangerous: These names might be stored in logs or third-party tools, making them a vector for injection or confusion.
๐งฉ Fields and Arguments
Fields = what we request. Arguments = how we control that request.
1query {
2users(active: true) {
3 email
4}
5}- Arguments are often user-controlled โค susceptible to injection, type confusion, or validation bypasses.
- Strong typing does not replace input validation.
๐งช Aliases: Double the Trouble
Aliases rename fields to avoid conflicts, but they also:
- Allow response key manipulation
- Obfuscate request intent
- Enable DoS tricks (like overloading or duplication)
1query {
2publicPastes: pastes(public: true) { title }
3privatePastes: pastes(public: false) { title }
4}๐ Fragments: Circular DoS Landmines
Fragments group reusable fields:
1fragment CommonFields on Paste {
2title
3content
4}
5
6query {
7pastes {
8 ...CommonFields
9}
10}๐ฃ Fragments referencing each other (circular) = DoS potential.
๐ผ Variables
Variables help optimize query reuse and reduce dynamic string building:
1query getPastes($public: Boolean!) {
2pastes(public: $public) {
3 title
4}
5}Like arguments, they are user-input vectors.
๐งฌ Directives
1query {
2user @include(if: true) {
3 username
4}
5}Used for conditional logic. Custom directives = powerful but risky if poorly validated.
| Directive | Description | Level |
|---|---|---|
| @skip | Conditionally skip field | Query |
| @include | Conditionally include field | Query |
| @deprecated | Marks schema elements as deprecated | Schema |
โ ๏ธ Vulnerable or unvalidated custom directives can introduce RCE or logic flaws.
๐งฑ The Type System: Objects, Scalars, Enums, Unions
- Object Types โ app-specific data structures (e.g., User, Paste)
- Scalars โ built-in types like String, ID, Boolean
- Custom Scalars โ IP, DateTime, etc. Beware of insecure libraries (e.g., CVE-2021-29921 in Python ipaddress lib).
- Unions / Interfaces / Inputs โ Add flexibility, but more edge cases to abuse
๐ Introspection
The __schema and __type fields let clients see the entire schema.
1{
2__schema {
3 types {
4 name
5 }
6}
7}- Great for devs and pentesters
- ๐ฅ Horrible if left enabled in production
๐ Validation & Execution
GraphQL servers have different validation implementations, leading to:
- ๐ Fingerprinting
- ๐ Bug discovery
Use tools like:
- GraphQL Threat Matrix
- Graphw00f
โ ๏ธ Common Weaknesses Summary
| Vulnerability Type | Explanation |
|---|---|
| DoS | Aliases, circular fragments, deep nesting |
| Information Disclosure | Introspection, debug mode, schema leaks |
| Authn/Authz Bypass | Broken logic, batch queries |
| Injection | Unescaped input in arguments, variables |