GraphQL + HPP

This commit is contained in:
Swissky 2024-11-29 13:49:54 +01:00
parent e6466b4cf9
commit 801aecb2ba
3 changed files with 114 additions and 62 deletions

View file

@ -7,23 +7,23 @@
- [Tools](#tools)
- [Enumeration](#enumeration)
- [Common GraphQL endpoints](#common-graphql-endpoints)
- [Identify an injection point](#identify-an-injection-point)
- [Common GraphQL Endpoints](#common-graphql-endpoints)
- [Identify An Injection Point](#identify-an-injection-point)
- [Enumerate Database Schema via Introspection](#enumerate-database-schema-via-introspection)
- [Enumerate Database Schema via Suggestions](#enumerate-database-schema-via-suggestions)
- [Enumerate the types' definition](#enumerate-the-types-definition)
- [List path to reach a type](#list-path-to-reach-a-type)
- [Enumerate Types Definition](#enumerate-types-definition)
- [List Path To Reach A Type](#list-path-to-reach-a-type)
- [Methodology](#methodology)
- [Extract data](#extract-data)
- [Extract data using edges/nodes](#extract-data-using-edgesnodes)
- [Extract data using projections](#extract-data-using-projections)
- [Use mutations](#use-mutations)
- [Extract Data](#extract-data)
- [Extract Data Using Edges/Nodes](#extract-data-using-edgesnodes)
- [Extract Data Using Projections](#extract-data-using-projections)
- [Mutations](#mutations)
- [GraphQL Batching Attacks](#graphql-batching-attacks)
- [JSON list based batching](#json-list-based-batching)
- [Query name based batching](#query-name-based-batching)
- [JSON List Based Batching](#json-list-based-batching)
- [Query Name Based Batching](#query-name-based-batching)
- [Injections](#injections)
- [NOSQL injection](#nosql-injection)
- [SQL injection](#sql-injection)
- [NOSQL Injection](#nosql-injection)
- [SQL Injection](#sql-injection)
- [Labs](#labs)
- [References](#references)
@ -46,9 +46,9 @@
## Enumeration
### Common GraphQL endpoints
### Common GraphQL Endpoints
Most of the time the graphql is located on the `/graphql` or `/graphiql` endpoint.
Most of the time GraphQL is located at the `/graphql` or `/graphiql` endpoint.
A more complete list is available at [danielmiessler/SecLists/graphql.txt](https://github.com/danielmiessler/SecLists/blob/fe2aa9e7b04b98d94432320d09b5987f39a17de8/Discovery/Web-Content/graphql.txt).
```ps1
@ -63,7 +63,7 @@ A more complete list is available at [danielmiessler/SecLists/graphql.txt](https
```
### Identify an injection point
### Identify An Injection Point
```js
example.com/graphql?query={__schema{types{name}}}
@ -211,7 +211,7 @@ You can also try to bruteforce known keywords, field and type names using wordli
### Enumerate the types' definition
### Enumerate Types Definition
Enumerate the definition of interesting types using the following GraphQL query, replacing "User" with the chosen type
@ -220,7 +220,7 @@ Enumerate the definition of interesting types using the following GraphQL query,
```
### List path to reach a type
### List Path To Reach A Type
```php
$ git clone https://gitlab.com/dee-see/graphql-path-enum
@ -246,7 +246,7 @@ Found 27 ways to reach the "Skill" node from the "Query" node:
## Methodology
### Extract data
### Extract Data
```js
example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
@ -256,7 +256,7 @@ example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
### Extract data using edges/nodes
### Extract Data Using Edges/Nodes
```json
{
@ -272,7 +272,7 @@ example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
}
```
### Extract data using projections
### Extract Data Using Projections
:warning: Dont forget to escape the " inside the **options**.
@ -281,7 +281,7 @@ example.com/graphql?query={TYPE_1{FIELD_1,FIELD_2}}
```
### Use mutations
### Mutations
Mutations work like function, you can use them to interact with the GraphQL.
@ -299,7 +299,7 @@ Common scenario:
* 2FA bypassing
#### JSON list based batching
#### JSON List Based Batching
> Query batching is a feature of GraphQL that allows multiple queries to be sent to the server in a single HTTP request. Instead of sending each query in a separate request, the client can send an array of queries in a single POST request to the GraphQL server. This reduces the number of HTTP requests and can improve the performance of the application.
@ -323,7 +323,7 @@ Query batching works by defining an array of operations in the request body. Eac
```
#### Query name based batching
#### Query Name Based Batching
```json
{
@ -348,7 +348,7 @@ mutation {
> SQL and NoSQL Injections are still possible since GraphQL is just a layer between the client and the database.
### NOSQL injection
### NOSQL Injection
Use `$regex`, `$ne` from []() inside a `search` parameter.
@ -364,7 +364,7 @@ Use `$regex`, `$ne` from []() inside a `search` parameter.
```
### SQL injection
### SQL Injection
Send a single quote `'` inside a graphql parameter to trigger the SQL injection

View file

@ -5,50 +5,93 @@
## Summary
* [Tools](#tools)
* [How to test](#how-to-test)
* [Table of reference](#table-of-reference)
* [Methodology](#methodology)
* [Parameter Pollution Table](#parameter-pollution-table)
* [Parameter Pollution Payloads](#parameter-pollution-payloads)
* [References](#references)
## Tools
No tools needed. Maybe Burp or OWASP ZAP.
* **Burp Suite**: Manually modify requests to test duplicate parameters.
* **OWASP ZAP**: Intercept and manipulate HTTP parameters.
## How to test
HPP allows an attacker to bypass pattern based/black list proxies or Web Application Firewall detection mechanisms. This can be done with or without the knowledge of the web technology behind the proxy, and can be achieved through simple trial and error.
## Methodology
```
Example scenario.
WAF - Reads first param
Origin Service - Reads second param. In this scenario, developer trusted WAF and did not implement sanity checks.
HTTP Parameter Pollution (HPP) is a web security vulnerability where an attacker injects multiple instances of the same HTTP parameter into a request. The server's behavior when processing duplicate parameters can vary, potentially leading to unexpected or exploitable behavior.
Attacker -- http://example.com?search=Beth&search=' OR 1=1;## --> WAF (reads first 'search' param, looks innocent. passes on) --> Origin Service (reads second 'search' param, injection happens if no checks are done here.)
HPP can target two levels:
* Client-Side HPP: Exploits JavaScript code running on the client (browser).
* Server-Side HPP: Exploits how the server processes multiple parameters with the same name.
**Examples**:
```ps1
/app?debug=false&debug=true
/transfer?amount=1&amount=5000
```
### Table of reference
### Parameter Pollution Table
When ?par1=a&par1=b
| Technology | Parsing Result |outcome (par1=)|
| ------------------ |--------------- |:-------------:|
| ASP.NET/IIS |All occurrences |a,b |
| ASP/IIS |All occurrences |a,b |
| PHP/Apache |Last occurrence |b |
| PHP/Zues |Last occurrence |b |
| JSP,Servlet/Tomcat |First occurrence |a |
| Perl CGI/Apache |First occurrence |a |
| Python Flask |First occurrence |a |
| Python Django |Last occurrence |b |
| Nodejs |All occurrences |a,b |
| Golang net/http - `r.URL.Query().Get("param")` |First occurrence |a |
| Golang net/http - `r.URL.Query()["param"]` |All occurrences in array |['a','b'] |
| IBM Lotus Domino |First occurrence |a |
| IBM HTTP Server |First occurrence |a |
| Perl CGI/Apache |First occurrence |a |
| mod_wsgi (Python)/Apache |First occurrence |a |
| Python/Zope |All occurrences in array |['a','b'] |
| Ruby on Rails |Last occurrence |b |
| Technology | Parsing Result | outcome (par1=) |
| ----------------------------------------------- | ------------------------ | --------------- |
| ASP.NET/IIS | All occurrences | a,b |
| ASP/IIS | All occurrences | a,b |
| Golang net/http - `r.URL.Query().Get("param")` | First occurrence | a |
| Golang net/http - `r.URL.Query()["param"]` | All occurrences in array | ['a','b'] |
| IBM HTTP Server | First occurrence | a |
| IBM Lotus Domino | First occurrence | a |
| JSP,Servlet/Tomcat | First occurrence | a |
| mod_wsgi (Python)/Apache | First occurrence | a |
| Nodejs | All occurrences | a,b |
| Perl CGI/Apache | First occurrence | a |
| Perl CGI/Apache | First occurrence | a |
| PHP/Apache | Last occurrence | b |
| PHP/Zues | Last occurrence | b |
| Python Django | Last occurrence | b |
| Python Flask | First occurrence | a |
| Python/Zope | All occurrences in array | ['a','b'] |
| Ruby on Rails | Last occurrence | b |
### Parameter Pollution Payloads
* Duplicate Parameters:
```ps1
param=value1&param=value2
```
* Array Injection:
```ps1
param[]=value1
param[]=value1&param[]=value2
param[]=value1&param=value2
param=value1&param[]=value2
```
* Encoded Injection:
```ps1
param=value1%26other=value2
```
* Nested Injection:
```ps1
param[key1]=value1&param[key2]=value2
```
* JSON Injection:
```ps1
{
"test": "user",
"test": "admin"
}
```
## References

View file

@ -9,7 +9,7 @@
* [Headless Commands](#headless-commands)
* [Local File Read](#local-file-read)
* [Debugging Port ](#debugging-port)
* [Debugging Port](#debugging-port)
* [Network](#network)
* [Port Scanning](#port-scanning)
* [DNS Rebinding](#dns-rebinding)
@ -20,11 +20,20 @@
Example of headless browsers commands:
```ps1
google-chrome --headless[=(new|old)] --print-to-pdf https://www.google.com
firefox --screenshot https://www.google.com
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --window-size=1280,720 --screenshot="C:\tmp\screen.png" "https://google.com"
```
* Google Chrome
```ps1
google-chrome --headless[=(new|old)] --print-to-pdf https://www.google.com
```
* Mozilla Firefox
```ps1
firefox --screenshot https://www.google.com
```
* Microsoft Edge
```ps1
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --window-size=1280,720 --screenshot="C:\tmp\screen.png" "https://google.com"
```
## Local File Read
@ -52,7 +61,7 @@ Target: `google-chrome-stable --headless[=(new|old)] --print-to-pdf https://site
```
## Debugging Port
## Debugging Port
**Target**: `google-chrome-stable --headless=new --remote-debugging-port=XXXX ./index.html`