Sec-88
  • 🧑Whoami
  • 🕸️Web-AppSec
    • Features Abuse
      • 2FA
      • Ban Feature
      • CAPTCHA
      • Commenting
      • Contact us
      • File-Upload
      • Inviting Feature
      • Messaging Features
      • Money-Related Features
      • Newsletter
      • Profile - Settings
      • Registration
      • Reset Password
      • Review
      • Rich Editor/Text
      • Social Sharing
      • Billing-Shipping Address Management
      • Integrations - Webhooks
      • API Key Management
    • Reconnaissance
      • Attacking Organizations with big scopes
    • Subdomain Enumeration
    • Fingerprinting
    • Dorking
    • XSS-HTML Injection
    • Improper Authentication
      • JWT Security
    • OAUTH Misconfigurations
      • OAuth 2.0 Basics
      • OAUTH Misconfigurations
    • Auth0 Misconfigurations
    • Broken Access Control
      • Insecure Direct Object References (IDOR)
      • 403 Bypass
    • Broken Link Injection
    • Command Injection
    • CORS
    • CRLF
    • CSRF
    • Host Header Attacks
    • HTTP request smuggling
    • JSON Request Testing
    • LFI
      • LFI to RCE
    • No Rate Limit
    • Parameters Manual Testing
    • Open Redirect
    • Registration & Takeover Bugs
    • Remote Code Execution (RCE)
    • Session Fixation
    • SQL Injection
      • SQL To RCE
    • SSRF
    • SSTI
    • Subdomain Takeover
    • Web Caching Vulnerabilities
    • WebSockets
    • XXE
      • XXE to RCE
    • Cookie Based Attacks
    • CMS
      • AEM [Adobe CMS]
    • XSSI (Cross Site Script Inclusion)
    • NoSQL injection
    • Local VS Remote Session Fixation
    • Protection
      • Security Mechanisms for Websites
      • Cookie Flags
      • SameSite Cookie Restrictions
      • Same-origin policy (SOP)
      • CSP
    • Hacking IIS Applications
    • Dependency Confusion
    • Attacking Secondary Context
    • Hacking Web Sockets
    • IDN Homograph Attack
    • DNS Rebinding Attack
    • LLM Hacking Checklist
    • Bypass URL Filtration
    • Cross-Site Path Traversal (CSPT)
    • PostMessage Security
    • Prototype Pollution
      • Client-Side Prototype Pollution
      • Server-Side prototype pollution
    • Tools-Extensions-Bookmarks
    • WAF Bypassing Techniques
    • SSL/TLS Certificate Lifecycle
    • Serialization in .NET
    • Client-Side Attacks
      • JavaScript Analysis
    • Bug Bounty Platforms/Programs
  • ✉️API-Sec
    • GraphQL API Security Testing
      • The Basics
      • GraphQL Communication
      • Setting Up a Vulnerable GraphQL Server
      • GraphQL Hacking Tools
      • GraphQL Attack Surface
      • RECONNAISSANCE
      • GraphQL DOS
      • Information Disclosure
      • AUTHENTICATION AND AUTHORIZATION BYPASSES
      • Injection Vulnerabilities in GraphQL
      • REQUEST FORGERY AND HIJACKING
      • VULNERABILITIES, REPORTS AND EXPLOITS
      • GraphQL Hacking Checklist
    • API Recon
    • API Token Attacks
    • Broken Object Level Authorization (BOLA)
    • Broken Authentication
    • Evasive Maneuvers
    • Improper Assets Management
    • Mass Assignment Attacks
    • SSRF
    • Injection Vulnerabilities
    • Excessive Data Exposure
    • OWASP API TOP 10 MindMap
    • Scanning APIs with OWASP ZAP
  • 📱Android-AppSec
    • Setup Android App Pentesting environment on Arch
    • Setup Android App Pentesting environment on Mac M4
    • Setup Android Pentesting Environment on Debian Linux
    • Android App Fundamentals
      • Android Architecture
      • Android Security Model
      • Android App Components
        • Intents
        • Pending Intents
    • Android App Components Security Cheatsheet
    • Android App Pentesting Checklist
    • How To Get APK file for application
    • ADB Commands
    • APK structure
    • Android Permissions
    • Exported Activity Hacking
    • BroadcastReceiver Hacking
    • Content Provider Hacking
    • Signing the APK
    • Reverse Engineering APK
    • Deep Links Hacking
    • Drozer Cheat Sheet
    • SMALI
      • SMALI Cheat Sheet
      • Smali Code Patching Guide
    • Intent Redirection Vulnerability
    • Janus Vulnerability (CVE-2017-13156)
    • Task Hijacking
    • Hacking Labs
      • Injured Android
      • Hacking the VulnWebView Lab
      • Hacking InsecureBankv2 App
    • Frida Cheat Sheet
  • 📶Network-Sec
    • Networking Fundamentals
    • Open Ports Security Testing
    • Vulnerability Scanning
    • Client Side Attacks
    • Port Redirection and Tunneling
    • Password Attacks
    • Privilege Escalation [PrevEsc]
      • Linux Privilege Escalation
    • Buffer Overflow (BOF)
      • VulnServer
      • Sync Breez Enterprize
      • Crashed CTF
      • BOF for Linux
    • AV Evasion
    • Post Exploitation
      • File Transfer
      • Maintaining Access
      • Pivoting
      • Clean Up
    • Active Directory
      • Basic AD Pentesting
  • 💻Desktop AppSec
    • Thin Client vs. Thick Client
  • ☁️Cloud Sec
    • Salesforce Hacking
      • Basics
      • Salesforce SAAS Apps Hacking
    • Firebase
    • S3 Buckets Misconfigurations
  • 👨‍💻Programming
    • HTML
    • JavaScript (JS)
      • window.location object
    • Python
      • Python Tips
      • Set
        • SetMethods
    • JAVA
      • Java Essentials
      • Java Essentials Code Notes
      • Java OOP1
      • JAVA OOP Principles
        • Inheritance
        • Method Overriding
        • Abstract Class
        • Interface
        • polymorphism
        • Encapsulation
        • Composition
      • Java OOP Challenges
      • Exception Handling
    • Go
      • Go Syntax Tutorial in one file
      • Methods and Interfaces
      • Go Slices
      • Go Maps
      • Go Functions
      • Concurrency
      • Read Files
      • Write Files
      • Package
        • How to make personal Package
        • regexp Packages
        • Json
        • bufio
        • Time
      • Signals-Exit
      • Unit Testing
  • 🖥️Operating Systems
    • Linux
      • Linux Commands
      • Tools
      • Linux File System
      • Bash Scripting guide
      • tmux
      • Git
      • Install Go tools from private repositories using GitHub PAT
    • VPS
    • Burp Suite
  • ✍️Write-Ups
    • Hunting Methodology
    • API BAC leads to PII Data Disclosure
    • Misconfigured OATUH leads to Pre-Account Takeover
    • Automating Bug Bounty with GitHub Actions
    • From Recon to Reward: My Bug Bounty Methodology when Hunting on Public Bug Bounty Programs
    • Exploring Subdomains: From Enumeration to Takeover Victory
    • 0-Click Account Takeover via Insecure Password Reset Feature
    • How a Simple Click Can Lead to Account Takeover: An OAuth Insecure Implementation Vulnerability
    • The Power Of IDOR even if it is unpredictable IDs
    • Unlocking the Weak Spot: Exploiting Insecure Password Reset Tokens
    • AI Under Siege: Discovering and Exploiting Vulnerabilities
    • Inside the Classroom: How We Hacked Our Way Past Authorization on a Leading EdTech Platform
    • How We Secured Our Client’s Platform Against Interaction-Free Account Thefts
    • Unchecked Privileges: The Hidden Risk of Role Escalation in Collaborative Platforms
    • Decoding Server Behavior: The Key to Mass Account Takeover
    • Exploiting JSON-Based CSRF: The Hidden Threat in Profile Management
    • How We Turned a Medium XSS into a High Bounty by Bypassing HttpOnly Cookie
Powered by GitBook
On this page
  • GraphQL Attack Surface
  • Operation Types:

Was this helpful?

Edit on GitHub
  1. API-Sec
  2. GraphQL API Security Testing

GraphQL Attack Surface

GraphQL Attack Surface

What Is an Attack Surface?

An attack surface refers to all potential entry points an attacker can exploit to compromise a system. GraphQL, like any system, has its own unique vulnerabilities based on its features and configuration. These entry points include queries, mutations, subscriptions, and various other elements of the GraphQL language and type system.

Imagine a building with multiple doors and windows. Each entry point is an opportunity for attackers to exploit vulnerabilities. Similarly, GraphQL’s extensive capabilities create opportunities for misconfigurations, improper validation, and exploitation.


Core Components of the GraphQL Language

#
Component
Description

1

Operation type

Type that defines the method of interaction with the server (query, mutation, or subscription)

2

Operation name

Arbitrary client-created label used to provide a unique name to an operation

3

Top-level field

Function that returns a single unit of information or object requested within an operation (may contain nested fields)

4

Argument (of a top-level field)

Parameter name used to send information to a field to tailor the behavior and results of that field

5

Value

Data related to an argument sent to a field

6

Field

Nested function that returns a single unit of information or object requested within an operation

7

Directive

Feature used to decorate fields to change their validation or executio

GraphQL queries consist of various components, each of which has security implications:

Operation Types:

  • Query: Retrieve data.

  • Mutation: Modify data, such as creating or updating records.

  • Subscription: Facilitate real-time communication between clients and servers.

Example: Mutation Query

mutation {
  editPaste(id: 1, content: "My first mutation!") {
    paste {
       id
       title
       content
    }
  }
}

This mutation modifies the content of a specific paste while also fetching the updated data. The flexibility in mutation operations can be a source of business logic vulnerabilities.

  1. Subscriptions: Subscriptions rely on WebSocket connections for real-time updates. While useful, they are prone to vulnerabilities such as Cross-Site WebSocket Hijacking (CSWSH) and Man-in-the-Middle (MITM) attacks if origin validation or encryption (via TLS) is absent.

Example: WebSocket Handshake Request:

GET /subscriptions HTTP/1.1
Host: 0.0.0.0:5013
Connection: Upgrade
Upgrade: websocket

Response:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade

After the handshake, a subscription might look like this:

subscription {
  paste {
     id
     title
     content
  }
}

Example: Query with Arguments

query {
  users(id: 1) {
    id
    username
  }
}

Key Attack Vectors in GraphQL

  1. Field Suggestions: When a field is misspelled, GraphQL servers often suggest corrections. This helpful feature can inadvertently expose undocumented fields.

Example: Error Message with Suggestions

"Cannot query field \\"titl\\" on type \\"PasteObject\\". Did you mean \\"title\\"?"
  1. Nested Queries: GraphQL allows deep nesting, which can lead to recursive queries and potential server overload.

Example: Circular Field Relationships

{
  id
  title
  content
  owner {
    name
    posts {
      title
      author {
        name
      }
    }
  }
}
  1. Argument Exploitation: Arguments are client-driven and can contain malicious inputs. For example, improperly validated inputs can lead to injection attacks.

Example: Argument Exploitation

query {
  users(id: "1; DROP TABLE users;") {
    id
    username
  }
}

Aliases

Aliases allow renaming fields in GraphQL queries, resolving conflicts when the same field is queried with different arguments. For example:

Without aliases:

query {
  pastes(public: false) {
    title
  }
  pastes(public: true) {
    title
  }
}

Error: Fields conflict due to differing arguments.

With aliases:

query {
  queryOne: pastes(public: false) {
    title
  }
  queryTwo: pastes(public: true) {
    title
  }
}

Response:

{
  "data": {
    "queryOne": [{ "title": "My Title!" }],
    "queryTwo": [{ "title": "Testing Testing" }]
  }
}

Fragments

Fragments allow reusable field sets for improved readability:

fragment CommonFields on PasteObject {
  title
  content
}

query {
  pastes {
    ...CommonFields
  }
}

Security Implications

From a security perspective, fragments can be constructed such that they reference one another, which can create a circular fragment condition that could lead to denial-of-service (DoS) conditions

. This is because a circular dependency among fragments can lead to an infinite loop when the GraphQL server attempts to resolve the query

For example, consider a scenario with two fragments, Start and End:

query {
    pastes {
        ...Start
    }
}

fragment Start on PasteObject {
    title
    content
    ...End
}

fragment End on PasteObject {
   ...Start
}

In this case, the Start fragment includes the End fragment, which includes the Start fragment again, creating a circular reference. This can lead to a DoS condition if the server doesn't handle such circular references correctly


Variables

Variables in GraphQL are a way to pass dynamic values to a query, mutation, or subscription, making operations more flexible and reusable. They are defined using a dollar sign ($) symbol followed by a name and a type

query publicPastes($status: Boolean!) {
  pastes(public: $status) {
    id
    title
    content
  }
}

In this example, $status is a variable of type Boolean that is passed to the public argument of the pastes field. The client would then provide the value for $status as a JSON object, such as {"status": true} or {"status": false}, along with the query

{
  "status": false
}

Directives

Directives modify field behavior dynamically. Common directives:

Name
Description
Location

@skip

Omits a field when the condition is true

Query

@include

Includes a field only when true

Query

@deprecated

Marks a field/type as deprecated

Schema

@specifiedBy

Specifies a scalar type via URL

Schema

Example:

query pasteDetails($pasteOnly: Boolean!) {
  pastes {
    id
    title
    content
    owner @skip(if: $pasteOnly) {
      name
    }
  }
}

Custom directives like @computed can enhance functionality, e.g., merging fields:

type User {
  firstName: String
  lastName: String
  fullName: String @computed(value: "$firstName $lastName")
}

Data Types

GraphQL supports six types: Object, Scalar, Enum, Union, Interface, and Input.

Objects

Custom types with specific fields:

type PasteObject {
  id: ID!
  title: String
  content: String
  public: Boolean
}

Scalars

Core scalar types include ID, Int, Float, String, Boolean. Implementations can also define their own custom scalars.

scalar DateTime
type PasteObject {
		id: ID!
		title: String}
		content: String
		public: Boolean
		userAgent: String
		ipAddr: String
		ownerId: Int
		burn: Boolean
		owner: OwnerObject
		createdAt: DateTime!
	}

Enums

Enums are special types that allow a field to return only one value from a predefined set of possible values⁠. They are useful when you want to restrict a field to specific options.

Here's how they work:

  • You define an enum type by listing all possible values it can have. For example, the UserSortEnum allows sorting users by ID, EMAIL, USERNAME, or DATE_JOINED⁠⁠

  • When using an enum in a query, you can only use one of these predefined values. For instance, in the example query, users are being sorted by ID:⁠

Allow specific values for fields:

enum UserSortEnum {
  ID
  EMAIL
  USERNAME
  DATE_JOINED
}

input UserOrderType {
  sort: UserSortEnum!
}

type UserObject {
  id: Int!
  username: String!
}

type Query {
  users(limit: Int, order: UserOrderType): UserObject!
}

Example Query:

query {
  users(limit: 100, order: { sort: ID })
}

Unions

Return one of multiple object types:

union SearchResults = UserObject | PasteObject
type UserObject {
		id: ID!
		username: String!
}
type PasteObject {
		id: ID!
		title: String
		content: String
		--snip--
}
type Query {
	search(keyword: String): [SearchResults!]
}

Query:

query {
  search(keyword: "p") {
    ... on UserObject { username }
    ... on PasteObject { title content }
  }
}

---------------
// result
{
"data": {
"search": [
{
"title": "This is my first paste",
"content": "What does your room look like?"
},
{
"id": "2",
"username": "operator"
}}
}
]

Interfaces

Define common fields across types:

interface SearchItem {
	keywords: [String!]
}

type UserObject implements SearchItem {
		id: ID!
		username: String!
		keywords: [String!]
}

type PasteObject implements SearchItem {
		id: ID!
		title: String
		content: String
		keywords: [String!]
		--snip--
}

type Query {
		search(keyword: String): [SearchItem!]!
}

Inputs

Simplify passing complex arguments:

input UserInput {
  username: String!
  password: String!
  email: String!
}

Mutation example:

mutation newUser($input: UserInput!) {
  createUser(userData: $input) {
    user {
      username
    }
  }
}

JSON for variables:

{
  "input": {
    "username": "tom",
    "password": "secret",
    "email": "tom@example.com"
  }
}

Apologies for missing the source code earlier. Here's a revised version that includes all relevant queries and responses.


GraphQL Introspection

Introspection type
Usage

__Schema

Provides all information about the schema of a GraphQL service

__Type

Provides all information about a type

__TypeKind

Provides the different kinds of types (scalars, objects, interface, union, enum, and so on)

__Field

Provides all information for each field of an object or interface type

__InputValue

Provides field and directive argument information

__EnumValue

Provides one of the possible values of an enum

__Directive

Provides all information on both custom and built-in directives

  1. Empowering Clients:

    • Introspection allows clients to discover schema information, including:

      • Queries

      • Mutations

      • Subscriptions

      • Types

      • Fields

      • Directives

    • Example query for listing all types:

      query {
        __schema {
          types {
            name
          }
        }
      }
      

      Response:

      {
        "data": {
          "__schema": {
            "types": [
              { "name": "PasteObject" },
              { "name": "ID" },
              { "name": "String" },
              { "name": "OwnerObject" },
              { "name": "UserObject" }
            ]
          }
        }
      }
      
  2. Deep Dive into Custom Types:

    • Investigate specific types to uncover fields and relationships:

      query {
        __type(name: "PasteObject") {
          name
          kind
          fields {
            name
            type {
              name
              kind
            }
          }
        }
      }
      

      Response:

      {
        "__type": {
          "name": "PasteObject",
          "kind": "OBJECT",
          "fields": [
            { "name": "id", "type": { "name": null, "kind": "NON_NULL" } },
            { "name": "title", "type": { "name": "String", "kind": "SCALAR" } },
            { "name": "content", "type": { "name": "String", "kind": "SCALAR" } },
            { "name": "owner", "type": { "name": "OwnerObject", "kind": "OBJECT" } }
          ]
        }
      }
      

Validation and Execution

  1. Validation Process:

    • GraphQL queries are checked against the schema for:

      • Field existence

      • Argument correctness

      • Directive support

  2. GraphQL Threat Matrix:

  • A framework for comparing GraphQL implementations based on:

    • Security maturity

    • Default configurations

    • Known vulnerabilities

  1. Execution Stage:

    • Resolvers process valid queries, but weak implementations can lead to exploits.

PreviousGraphQL Hacking ToolsNextRECONNAISSANCE

Last updated 4 months ago

Was this helpful?

✉️