diff --git a/src/network-services-pentesting/pentesting-web/graphql.md b/src/network-services-pentesting/pentesting-web/graphql.md
index c0060d481..ae95ebee0 100644
--- a/src/network-services-pentesting/pentesting-web/graphql.md
+++ b/src/network-services-pentesting/pentesting-web/graphql.md
@@ -8,7 +8,7 @@ GraphQL 被 **强调** 为 REST API 的 **高效替代方案**,提供了一种
## GraphQL 和安全性
-随着包括 GraphQL 在内的新技术的出现,新安全漏洞也随之而来。一个关键点是 **GraphQL 默认不包含身份验证机制**。开发者有责任实施这些安全措施。没有适当的身份验证,GraphQL 端点可能会向未认证的用户暴露敏感信息,构成重大安全风险。
+随着新技术的出现,包括 GraphQL,新的安全漏洞也随之出现。一个关键点是 **GraphQL 默认不包含身份验证机制**。开发者有责任实施这些安全措施。没有适当的身份验证,GraphQL 端点可能会向未认证的用户暴露敏感信息,构成重大安全风险。
### 目录暴力攻击和 GraphQL
@@ -23,11 +23,11 @@ GraphQL 被 **强调** 为 REST API 的 **高效替代方案**,提供了一种
- `/graphql/api`
- `/graphql/graphql`
-识别开放的 GraphQL 实例可以检查支持的查询。这对于理解通过端点可访问的数据至关重要。GraphQL 的自省系统通过详细说明模式支持的查询来促进这一点。有关更多信息,请参阅 GraphQL 文档中的自省:[**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/)
+识别开放的 GraphQL 实例可以检查支持的查询。这对于理解通过端点可访问的数据至关重要。GraphQL 的自省系统通过详细说明模式支持的查询来促进这一点。有关更多信息,请参阅 GraphQL 关于自省的文档:[**GraphQL: A query language for APIs.**](https://graphql.org/learn/introspection/)
### 指纹识别
-工具 [**graphw00f**](https://github.com/dolevf/graphw00f) 能够检测服务器使用的 GraphQL 引擎,并打印一些对安全审计员有用的信息。
+工具 [**graphw00f**](https://github.com/dolevf/graphw00f) 能够检测服务器使用的 GraphQL 引擎,并打印一些对安全审计员有帮助的信息。
#### 通用查询
@@ -57,7 +57,7 @@ query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofTy
**错误**
-了解 **错误** 是否会被 **显示** 是很有趣的,因为它们将提供有用的 **信息。**
+了解**错误**是否会被**显示**是很有趣的,因为它们将提供有用的**信息。**
```
?query={__schema}
?query={}
@@ -172,7 +172,7 @@ name
现在我们知道数据库中保存了哪种信息,让我们尝试 **提取一些值**。
-在自省中,您可以找到 **可以直接查询的对象**(因为您不能仅仅因为对象存在就查询它)。在下面的图像中,您可以看到 "_queryType_" 被称为 "_Query_",而 "_Query_" 对象的一个字段是 "_flags_",这也是一种对象类型。因此,您可以查询标志对象。
+在自省中,您可以找到 **可以直接查询的对象**(因为您不能仅仅因为对象存在就查询它)。在下图中,您可以看到 "_queryType_" 被称为 "_Query_",而 "_Query_" 对象的一个字段是 "_flags_",这也是一种对象类型。因此,您可以查询标志对象。

@@ -180,7 +180,7 @@ name
.png>)
-您可以看到 "_Flags_" 对象由 **name** 和 **value** 组成。然后,您可以使用以下查询获取所有标志的名称和值:
+您可以看到 "_Flags_" 对象由 **name** 和 **value** 组成。然后,您可以使用查询获取所有标志的名称和值:
```javascript
query={flags{name, value}}
```
@@ -204,7 +204,7 @@ query = { hiddenFlags }
看起来它会使用类型为 _**Int**_ 的 "_**uid**_" 参数进行搜索。\
无论如何,我们已经知道,在 [Basic Enumeration](graphql.md#basic-enumeration) 部分提出了一个查询,显示了所有所需的信息:`query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
-如果你阅读提供的图像,当我运行该查询时,你会看到 "_**user**_" 有一个类型为 _Int_ 的 **arg** "_**uid**_"。
+如果你阅读提供的图像,当我运行该查询时,你会看到 "_**user**_" 有类型为 _Int_ 的 **arg** "_**uid**_"。
因此,通过一些轻量级的 _**uid**_ 暴力破解,我发现 _**uid**=**1** 时检索到了一个用户名和密码:\
`query={user(uid:1){user,password}}`
@@ -219,11 +219,11 @@ query = { hiddenFlags }
**查询字符串转储技巧(感谢 @BinaryShadow\_)**
-如果你可以通过字符串类型进行搜索,例如:`query={theusers(description: ""){username,password}}`,并且你**搜索一个空字符串**,它将**转储所有数据**。 (_注意这个例子与教程的例子无关,对于这个例子假设你可以通过一个名为 "**description**" 的字符串字段使用 "**theusers**" 进行搜索_).
+如果你可以通过字符串类型进行搜索,例如:`query={theusers(description: ""){username,password}}`,并且你**搜索一个空字符串**,它将**转储所有数据**。 (_注意这个例子与教程的例子无关,对于这个例子假设你可以通过一个名为 "**description**" 的字符串字段使用 "**theusers**" 进行搜索_)。
### 搜索
-在这个设置中,一个**数据库**包含**人员**和**电影**。**人员**通过他们的**电子邮件**和**姓名**进行识别;**电影**通过它们的**名称**和**评分**进行识别。**人员**可以互为朋友,也可以拥有电影,表示数据库中的关系。
+在这个设置中,一个**数据库**包含**人员**和**电影**。**人员**通过他们的**电子邮件**和**姓名**进行识别;**电影**通过它们的**名称**和**评分**进行识别。**人员**可以互为朋友,并且也有电影,表示数据库中的关系。
你可以通过**姓名**搜索人员并获取他们的电子邮件:
```javascript
@@ -233,7 +233,7 @@ email
}
}
```
-您可以通过姓名搜索人员并获取他们订阅的电影:
+您可以通过**姓名**搜索人员并获取他们**订阅**的**电影**:
```javascript
{
searchPerson(name: "John Doe") {
@@ -258,7 +258,7 @@ name
}
}r
```
-或者甚至是 **使用别名的多个不同对象的关系**:
+或者甚至**使用别名的多个不同对象的关系**:
```javascript
{
johnsMovieList: searchPerson(name: "John Doe") {
@@ -285,13 +285,13 @@ name
**变更用于在服务器端进行更改。**
-在**自省**中,您可以找到**声明的** **变更**。在下图中,"_MutationType_" 被称为 "_Mutation_",而 "_Mutation_" 对象包含变更的名称(在本例中为 "_addPerson_"):
+在 **introspection** 中可以找到 **声明的** **变更**。在下图中,"_MutationType_" 被称为 "_Mutation_",而 "_Mutation_" 对象包含变更的名称(在本例中为 "_addPerson_"):
.png>)
-在此设置中,**数据库**包含**人员**和**电影**。**人员**通过其**电子邮件**和**姓名**进行识别;**电影**通过其**名称**和**评分**进行识别。**人员**可以互为朋友,并且也可以拥有电影,表示数据库中的关系。
+在此设置中,**数据库** 包含 **人员** 和 **电影**。**人员** 通过他们的 **电子邮件** 和 **姓名** 进行识别;**电影** 通过它们的 **名称** 和 **评分** 进行识别。**人员** 可以互为朋友,并且也可以拥有电影,表示数据库中的关系。
-一个**在数据库中创建新**电影的变更可以如下所示(在此示例中,变更被称为 `addMovie`):
+一个 **在数据库中创建新** 电影的变更可以如下所示(在此示例中,变更被称为 `addMovie`):
```javascript
mutation {
addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) {
@@ -304,7 +304,7 @@ rating
```
**注意查询中如何指示值和数据类型。**
-此外,数据库支持一个**mutation**操作,名为`addPerson`,允许创建**persons**及其与现有**friends**和**movies**的关联。重要的是要注意,朋友和电影必须在数据库中预先存在,然后才能将它们链接到新创建的人。
+此外,数据库支持一个 **mutation** 操作,名为 `addPerson`,允许创建 **persons** 及其与现有 **friends** 和 **movies** 的关联。重要的是要注意,朋友和电影必须在数据库中预先存在,然后才能将它们链接到新创建的人。
```javascript
mutation {
addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) {
@@ -353,7 +353,7 @@ releaseYear
越来越多的**graphql端点正在禁用自省**。然而,当收到意外请求时,graphql抛出的错误足以让像[**clairvoyance**](https://github.com/nikitastupin/clairvoyance)这样的工具重建大部分架构。
-此外,Burp Suite扩展[**GraphQuail**](https://github.com/forcesunseen/graphquail)扩展**观察通过Burp的GraphQL API请求**,并**构建**一个内部GraphQL**架构**,每当它看到新的查询时。它还可以为GraphiQL和Voyager公开架构。当收到自省查询时,该扩展返回一个假响应。因此,GraphQuail显示了API中可用的所有查询、参数和字段。有关更多信息,[**请查看此处**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema)。
+此外,Burp Suite扩展[**GraphQuail**](https://github.com/forcesunseen/graphquail) **观察通过Burp的GraphQL API请求**并**构建**一个内部GraphQL **架构**,每当它看到新的查询时。它还可以为GraphiQL和Voyager公开架构。当收到自省查询时,该扩展返回一个假响应。因此,GraphQuail显示了API中可用的所有查询、参数和字段。有关更多信息,[**请查看此处**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema)。
一个很好的**词表**可以在这里发现[**GraphQL实体**](https://github.com/Escape-Technologies/graphql-wordlist?)。
@@ -397,23 +397,23 @@ ws.send(JSON.stringify(graphqlMsg))
```
### **发现暴露的 GraphQL 结构**
-当 introspection 被禁用时,检查网站源代码中 JavaScript 库中预加载的查询是一种有用的策略。这些查询可以通过开发者工具中的 `Sources` 选项卡找到,提供有关 API 架构的见解,并揭示潜在的 **暴露的敏感查询**。在开发者工具中搜索的命令是:
+当 introspection 被禁用时,检查网站源代码中 JavaScript 库中预加载的查询是一种有用的策略。这些查询可以通过开发者工具中的 `Sources` 选项卡找到,提供有关 API 架构的见解,并揭示潜在的 **暴露敏感查询**。在开发者工具中搜索的命令是:
```javascript
Inspect/Sources/"Search all files"
file:* mutation
file:* query
```
-## CSRF in GraphQL
+## GraphQL中的CSRF
-如果你不知道什么是 CSRF,请阅读以下页面:
+如果你不知道什么是CSRF,请阅读以下页面:
{{#ref}}
../../pentesting-web/csrf-cross-site-request-forgery.md
{{#endref}}
-在外面,你将能够找到几个 **未配置 CSRF 令牌的** GraphQL 端点。
+在外面,你将能够找到几个**未配置CSRF令牌的**GraphQL端点。
-请注意,GraphQL 请求通常通过使用 Content-Type **`application/json`** 的 POST 请求发送。
+请注意,GraphQL请求通常通过使用Content-Type **`application/json`**的POST请求发送。
```javascript
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
```
@@ -459,7 +459,7 @@ query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
[将查询链接](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln)在一起可以绕过一个弱认证系统。
-在下面的示例中,您可以看到操作是 "forgotPassword",并且它应该只执行与之关联的 forgotPassword 查询。通过在末尾添加一个查询可以绕过这一点,在这种情况下,我们添加 "register" 和一个用户变量,以便系统注册为新用户。
+在下面的示例中,您可以看到操作是“forgotPassword”,并且它应该只执行与之关联的 forgotPassword 查询。通过在末尾添加一个查询可以绕过这一点,在这种情况下,我们添加“register”和一个用户变量,以便系统注册为新用户。
@@ -469,7 +469,7 @@ query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
要详细了解 GraphQL 别名,推荐以下资源:[Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases)。
-虽然别名的主要目的是减少大量 API 调用的必要性,但已识别出一个意外的用例,其中别名可以被用来对 GraphQL 端点执行暴力攻击。这是可能的,因为某些端点受到速率限制器的保护,旨在通过限制**HTTP 请求的数量**来阻止暴力攻击。然而,这些速率限制器可能没有考虑到每个请求中的操作数量。鉴于别名允许在单个 HTTP 请求中包含多个查询,它们可以绕过此类速率限制措施。
+虽然别名的主要目的是减少大量 API 调用的必要性,但已识别出一个意外的用例,其中别名可以被利用来对 GraphQL 端点执行暴力攻击。这是可能的,因为某些端点受到速率限制器的保护,旨在通过限制**HTTP 请求的数量**来阻止暴力攻击。然而,这些速率限制器可能没有考虑到每个请求中的操作数量。鉴于别名允许在单个 HTTP 请求中包含多个查询,它们可以绕过此类速率限制措施。
考虑下面提供的示例,它说明了如何使用别名查询来验证商店折扣代码的有效性。这种方法可以绕过速率限制,因为它将多个查询编译成一个 HTTP 请求,可能允许同时验证多个折扣代码。
```bash
@@ -490,7 +490,7 @@ valid
### Alias Overloading
-**Alias Overloading** 是一种 GraphQL 漏洞,攻击者通过为同一字段重载查询,使用多个别名,导致后端解析器重复执行该字段。这可能会使服务器资源过载,从而导致 **Denial of Service (DoS)**。例如,在下面的查询中,同一字段 (`expensiveField`) 被请求了 1,000 次,使用别名,迫使后端计算 1,000 次,可能会耗尽 CPU 或内存:
+**Alias Overloading** 是一种 GraphQL 漏洞,攻击者通过为同一字段重载查询中的多个别名,导致后端解析器重复执行该字段。这可能会使服务器资源过载,从而导致 **Denial of Service (DoS)**。例如,在下面的查询中,同一字段 (`expensiveField`) 被请求了 1,000 次,使用别名强迫后端计算 1,000 次,可能会耗尽 CPU 或内存:
```graphql
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "Content-Type: application/json" \
@@ -501,7 +501,7 @@ curl -X POST -H "Content-Type: application/json" \
### **基于数组的查询批处理**
-**基于数组的查询批处理**是一种漏洞,其中GraphQL API允许在单个请求中批处理多个查询,使攻击者能够同时发送大量查询。这可能会通过并行执行所有批处理查询来压垮后端,消耗过多的资源(CPU、内存、数据库连接),并可能导致**服务拒绝(DoS)**。如果对批处理中的查询数量没有限制,攻击者可以利用这一点来降低服务可用性。
+**基于数组的查询批处理** 是一种漏洞,其中 GraphQL API 允许在单个请求中批处理多个查询,使攻击者能够同时发送大量查询。这可能会通过并行执行所有批处理查询来压垮后端,消耗过多的资源(CPU、内存、数据库连接),并可能导致 **服务拒绝(DoS)**。如果对批处理中的查询数量没有限制,攻击者可以利用这一点来降低服务可用性。
```graphql
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" \