diff --git a/.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png b/.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png new file mode 100644 index 000000000..eef992753 Binary files /dev/null and b/.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png differ diff --git a/.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png b/.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png new file mode 100644 index 000000000..722d32196 Binary files /dev/null and b/.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png differ diff --git a/.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png b/.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png new file mode 100644 index 000000000..44a446c60 Binary files /dev/null and b/.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png differ diff --git a/pentesting/pentesting-web/graphql.md b/pentesting/pentesting-web/graphql.md index d019b12dd..3889fe152 100644 --- a/pentesting/pentesting-web/graphql.md +++ b/pentesting/pentesting-web/graphql.md @@ -49,18 +49,30 @@ It's interesting to know if the **errors** are going to be **shown** as they wil #### Enumerate Database Schema via Introspection ```text -fragment+FullType+on+__Type+{++kind++name++description++fields(includeDeprecated%3a+true)+{++++name++++description++++args+{++++++...InputValue++++}++++type+{++++++...TypeRef++++}++++isDeprecated++++deprecationReason++}++inputFields+{++++...InputValue++}++interfaces+{++++...TypeRef++}++enumValues(includeDeprecated%3a+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++++++++ofType+{++++++++++kind++++++++++name++++++++++ofType+{++++++++++++kind++++++++++++name++++++++++++ofType+{++++++++++++++kind++++++++++++++name++++++++++++++ofType+{++++++++++++++++kind++++++++++++++++name++++++++++++++}++++++++++++}++++++++++}++++++++}++++++}++++}++}}query+IntrospectionQuery+{++__schema+{++++queryType+{++++++name++++}++++mutationType+{++++++name++++}++++types+{++++++...FullType++++}++++directives+{++++++name++++++description++++++locations++++++args+{++++++++...InputValue++++++}++++}++}} +/?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%2 0description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20 %20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20 %20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20 %20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20 %20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20 %20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef +%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%2 0description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue +}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofT ype%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20 %20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofTyp e%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%2 0%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind +%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20 %20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20 %20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%2 0ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%2 0%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20% 20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%2 0%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20na me+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%2 0%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20 %20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20In trospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20 %20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%2 0%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20 %20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20% 20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20 %20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%2 0%20%20}+%20%20%20%20}+%20%20}+}The last code line is a graphql query that will dump all the meta-information from the graphql (objects names, parameters, types...) ``` -The last code line is a graphql query that will **dump all the meta-information** from the graphql \(_objects names, parameters, types..._\) - ![](../../.gitbook/assets/image%20%28159%29.png) ### Quering Now that we know which kind of information is saved inside the database, let's try to **extract some values**. -In our example there were 2 objects inside the "_Query_" type object: "_user_" and "_users_". +In the introspection you can find **which object you can directly query for** \(because you cannot query an object just because it exists\). In the following image you can see that the "_queryType_" is called "_Query_" and that one of the fields of the "_Query_" object is "_flags_", which is also a type of object. Therefore you can query the flag object. + +![](../../.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png) + +Flags object is defined below as: + +![](../../.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png) + +Where you can see that the flags objects are composed by name and value. Then you can get all the names and values of the flags with the query: + +```javascript +query={flags{name, value}} +``` + +In another example where there were 2 objects inside the "_Query_" type object: "_user_" and "_users_". If these objects don't need any argument to search, could **retrieve all the information from them** just **asking** for the data you want. In this example from Internet you could extract the saved usernames and passwords: ![](../../.gitbook/assets/image%20%28138%29.png) @@ -163,6 +175,10 @@ Or even **relations of several different objects using aliases**: **Mutations are used to make changes in the server-side.** +In the **introspection** you can find the **declared** **mutations**. In the following image the "_MutationType_" is called "_Mutation_" and the "_Mutation_" object contains the names of the mutations \(like "_addPerson_" in this case\): + +![](../../.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png) + For this example imagine a data base with **persons** identified by the email and the name and **movies** identified by the name and rating. A **person** can be **friend** with other **persons** and a person can **have movies**. A mutation to **create new** movies inside the database can be like the following one \(in this example the mutation is called `addMovie`\):