- REST APIs
- RESTful
- URL structure
- Often use resource-oriented URLs such as:
/api/v1/product/1234
- Often use resource-oriented URLs such as:
- Response structure
- Often in JSON or XML format
- Consistent and hierarchical structure
- URL structure
- OData
- A metadata document is usually provided at
/odata/$metadata
- Specific query options present on the URL:
/odata/Products?$filter=Price&$orderby=desc
- Response often includes annotations
@odata.context
or@odata.metadata
- Typically format is JSON
- Usually the response
Content-Type
includes the stringodata
:application/json;odata.metadata=full
- A metadata document is usually provided at
- RESTful
- GraphQL
- Response structure
- If there an issue with the query, an
errors
object is included in the response - Errors like
Cannot query field
orField <field_name> not found
is usually indicative of a GraphQL API - If the response is successful the response will often contain a
data
field which includes the actual query results
- If there an issue with the query, an
- Specific fields
- Response may include
__typename
which is used to identify the type of an object
- Response may include
- Response structure
- SOAP
- Transfered data in XML format
- XML-RPC
- Transfered data in simpler XML format
<users><user><firstName>David</firstName>
- Transfered data in simpler XML format
- JSON-RPC
- Transfered data similar to XML-RPC but in JSON format
{"users":[{"firstName":"David"}]
- Transfered data similar to XML-RPC but in JSON format
- gRPC-Protobuf
- Identify
grpc
- Accept request header
- Content-Type request header
- Access-control-expose-headers in the response header
- gRPC messages are encoded using Protobuf, which is binary
- Identify
- Webhooks
- Event-driven APIs that send information or perform a specific function in response to a trigger (e.g. time of the day, clicking a button, receiving a form submission)
- Identify
- Search for
webhooks
orevent subscriptions
on the documentation - Find a reference on how to register a callback URL
- Is there a list of events types that can trigger a webhook?
- Search for
- Identify
- Event-driven APIs that send information or perform a specific function in response to a trigger (e.g. time of the day, clicking a button, receiving a form submission)
- https://smartbear.com/blog/soap-vs-rest-whats-the-difference/
- https://www.odata.org/documentation/
- https://www.howtographql.com/basics/1-graphql-is-the-better-rest/
- https://www.smashingmagazine.com/2016/09/understanding-rest-and-rpc-for-http-apis/
- https://www.soapui.org/docs/rest-testing/working-with-rest-services/
- https://cloud.google.com/blog/products/api-management/understanding-grpc-openapi-and-rest-and-when-to-use-them
- https://openapi.tools/
- https://developers.hubspot.com/docs/api/webhooks
- https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/swagger.txt
/openapi.json
/$metadata
/application.wadl
/application.wadl?detail=true
/api/application.wadl
- ?wsdl or ?singleWsdl
- wsdl-wizard
- SoapUI
- Wsdler
/_vti_bin/lists.asmx?WSDL
- site:target.tld intitle:api | developer
- REST
- OData
- GraphQL
- SOAP
- XML-RPC
- JSON-RPC
- gRPC-Protobuf
- mitmproxy
- Wireshark
echo HEX_STREAM | xxd -r -p | protoc --decode_raw
- protoc
- Wireshark Protobuf Dissector
- gRPC UI
- ZAP - gRPC Support
- /api/v1
- /api/v2
- /api/v3
site:target.tld inurl:api
intitle:"index of" "api.yaml" site:target.tld
- REST
site:target.tld inurl:api | site:*/rest | site:*/v1 | site:*/v2 | site:*/v3
- GraphQL
site:target.tld inurl:graphql
- WADL
inurl:/application.wadl
user filetype:wadl
ext:wadl
- WSDL
user filetype:wsdl
ext:wsdl
- Odata
inurl:/%24metadata
- Webhooks
inurl:docs webhook
intitle:"index of" intext:"apikey.txt" site:target.tld
allintext:"API_SECRET*" ext:env | ext:yml site:target.tld
- truffleHog
- shhgit
- API list
- API Harmony
- ProgrammableWeb
- RapidAPI Hub
- APIs.io
- SwaggerHub
- APIs.guru
- Postman Public API Network
- Any API
- SmartAPI Registry
- API Stack
- Public APIs
- https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/api/api_endpoints.txt
- https://s3.amazonaws.com/assetnote-wordlists/data/automated/httparchive_apiroutes_2020_11_20.txt
- https://github.com/chrislockard/api_wordlist
ffuf -w wordlists/WORDLIST -u https://TARGET.TLD/FUZZ
- https://github.com/ffuf/ffuf
amass enum -active -d TARGET.TLD -config /root/amass/config.ini
- https://github.com/OWASP/Amass
nuclei -target TARGET.TLD -t exposures/apis/
- https://github.com/projectdiscovery/nuclei
jaeles scan -s /jaeles-signatures/sensitive/swagger-ui-probing.yaml -u TARGET.TLD
- https://github.com/jaeles-project/jaeles
arjun -u https://api.TARGET.TLD/endpoint
- https://github.com/s0md3v/Arjun
python3 paramspider.py --domain TARGET.TLD
- https://github.com/devanshbatham/ParamSpider
tntfuzzer --url https://TARGET.TLD/v2/swagger.json --iterations 100 --log_all
- https://github.com/Teebytes/TnT-Fuzzer
kr scan TARGET.TLD -w routes.kite -A=apiroutes-210228:20000 -x 10 --ignore-length=34
- https://github.com/assetnote/kiterunner
python3 main.py -f -d -t http://localhost:5000
- https://github.com/dolevf/graphw00f
python3 -m clairvoyance -vv -o schema.json -w wordlist.txt https://api-example/graphql
- https://github.com/nikitastupin/clairvoyance
j2p -p http://example.com/+burp.xml
- https://github.com/s0md3v/dump/tree/master/json2paths
wfuzz -z file,/usr/share/wordlists/api_list.txt https://targetname.com/FUZZ
- https://github.com/xmendez/wfuzz
gobuster vhost -k --append-domain -u TARGET.TLD -w wordlist.txt
- https://github.com/OJ/gobuster
cat subdomains_list.httpx | katana -mdc 'contains(endpoint, "api")' -o katana_api_output
- https://github.com/projectdiscovery/katana
sasori start -c config.json -o sasori_output.txt
- https://github.com/karthikuj/sasori
- Play with request URL
- Requested resource extension e.g. replacing
.json
by.xml
- Query string e.g. replacing
?json
by?xml
or?format=json
by?format=xml
- Requested resource extension e.g. replacing
- Play with
Content-Type
request header and payload- Without
Content-Type
, submit eitherjson
,xml
, ... - Changing
Content-Type
and payload accordingly
- Without
- Sequential
- Encoded
- UUID (aka GUID)
- Composite IDs
- Hashed
- Randomly Generated Strings
- Temporal
- Next/Previous value
- Compute/Predict (e.g. UUIDv1)
- Data Type
- Is it a number? Change it to a string
- Is it a string? Change it to a number
- Method
- GET to POST
- GET to PUT
- GET to PATCH
- Base64 encoded?
- Decoded it, modify it, encode it again
- ?id=1&id=2
- ?id[]=1&id[]=2
- GET /users/id -> GET /users/*
- Identify other deployments (hosts) of your target API
- Enumerate resources IDs (often non- numerical/sequential ones)
- Test those IDs on your target API host
- REST APIs
- GraphQL
- gRPC-protobuf
- UUIDs
- Passwords
- Tokens
- Login
- Forget Password
- Forget Username
- Changing Password
- Registration
- Plain text
- Weak encryption
- Weak hash algorithm
- Predictable
- Weak hash algorithm
- jwt_tool
python3 jwt_tool.py -t https://api.example.com/api/working_endpoint -rh "Content-Type: application/json" -rh "Authorization: Bearer [JWT]" -M at
- https://github.com/ticarpi/jwt_tool
- jwt_tool
python3 jwt_tool.py <JWT> -C -d <Wordlist>
- https://github.com/ticarpi/jwt_tool
- jwt_cracker
jwt-cracker <JWT> <Alphabet> <Max length>
- https://github.com/lmammino/jwt-cracker
- jwtcat
python jwcat.py brute-force <JWT>
python jwcat.py wordlist -w <Wordlist> <JWT>
- https://github.com/aress31/jwtcat
- JWT Heartbreaker
- gojwtcrack
cat rockyou.txt | ./gojwtcrack -t mytoken.txt
- https://github.com/x1sec/gojwtcrack
- Change algorithm to None
- jwt_tool
python3 jwt_tool.py <JWT> -X a
- https://github.com/ticarpi/jwt_tool
- jwtcat
python jwcat.py vulnerable <JWT>
- https://github.com/aress31/jwtcat
- jwt_tool
- Change algorithm from RS256 to HS256
- jtw_tool
python3 jwt_tool.py <JWT> -S hs256 -k public.pem
- https://github.com/ticarpi/jwt_tool
- jwtcat
python jwcat.py vulnerable <JWT>
- https://github.com/aress31/jwtcat
- jtw_tool
- jwt.io
- JSON Web Token Attacker
- jwt_tool
python3 jwt_tool.py <JWT> -I -pc <Key> -pv <Value>
- https://github.com/ticarpi/jwt_tool
- jtwXploiter
jwtxpl <JWT> -a hs256 -p <key>:<value> --unverified
- https://github.com/DontPanicO/jwtXploiter
- jwt_tool
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
- https://github.com/ticarpi/jwt_tool
- jwtXploiter
jwtxpl <JWT> -a hs256 -p <key>:<value> --inject-kid "../../dev/null"
- https://github.com/DontPanicO/jwtXploiter
- Test redirect_uri
- Open redirects
- Common issues
?redirect_uri=https://atttacker.com
?redirect_uri=https://ATTACKER.TARGET.TLD
?redirect_uri=https://ALLOWED_HOST.com/callback?redirectUrl=https://attacker.com
?redirect_uri=https://TARGET.TLD.attacker.com
?redirect_uri=https://TARGET.TLD%252eattacker.com
?redirect_uri=https://TARGET.TLD//attacker.com/
- Fuzz
?redirect_uri=https://TARGET.TLD§FUZZ§
?redirect_uri=https://§FUZZ§TARGET.TLD
- URL validation bypass cheat sheet
- Common issues
- XSS
- Open redirects
- Test the existence of response_type=token
- Testing state
- Missing state parameter?
- CSRF
- Generate a valid
authorization_code
and don't use it- Send the crafted CSRF page to TARGET
- Generate a valid
- CSRF
- Predictable state parameter?
- Is state parameter being verified?
- Missing state parameter?
- If you revocate access, will code be also revocated?
- Credential leakage
- Check the Referer header
- Check the browser history
- Can a regular user access administrative endpoints? (MindAPI recon can help you here)
- Testing different HTTP methods (GET, POST, PUT, DELETE, PATCH) will allow level escalation?
- Enumerate/Bruteforce endpoints for getting unauthorized requests (MindAPI recon can help you here)
- API documentation (Reconnaissance)
- Inspect available API clients' network traffic
- Desktop
- Mobile
- Web
- Exercise data retrieval endpoints
- watch-out for
?include=user.addresses,user.cards
-like parameters
- watch-out for
- Uncover hidden properties
- Guessing, based on API context
- Reverse engineering available API clients
- Fuzzing
- GraphQL
- Include augmented objects
- One additional property at a time
- Possible combinations of properties
- All enumerated properties at once
- Vary properties data types/values
- Number, String, Array, Object
- State values:
to-do
->in-progress
->done
(keep in mind possible state transitions)
- Test different operation types
- Create
- Update
- Introspection Query and/or GraphiQL is enabled
- GraphQL server provides fields name hints
- Query batching is enabled without limit
- Unlimited Depth and/or Amount
- REST APIs
- GraphQL
- gRPC-protobuf
- REST APIs
- GraphQL
- gRPC-protobuf
- Check for the API documentation (MindAPI recon can help you here)
- REST APIs
oasdiff diff openapi-test1.yaml openapi-test5.yaml -f text
- https://www.oasdiff.com/diff-calculator
- https://github.com/Tufin/oasdiff
- Detecting new API endpoints with oasdiff
- REST APIs
- Hosts inventory is missing or outdated.
- Integrated services inventory, either first- or third-party, is missing or outdated.
- Old or previous API versions are running unpatched.
- The aspects of the API (e.g. authentication, endpoints, redirects, errors, parameters, rate-limiting, request and response formats, etc) are missing or outdated.
- If the API documentation is exposed to the internet, implement an access control mechanism (e.g. login portal) to ensure that only authorized users access the OpenAPI specification or even to the documentation as a whole.
- If your API shares data with a third-party or you are consuming a third-party API, make sure to include it in the inventory.