Skip to content

Commit

Permalink
docs: updated
Browse files Browse the repository at this point in the history
Signed-off-by: Neko Ayaka <[email protected]>
  • Loading branch information
nekomeowww committed Jan 24, 2024
1 parent 9a242e1 commit c4b200a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 34 deletions.
31 changes: 13 additions & 18 deletions content/en/docs/features/raw-sql-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ weight: 2

Different users may have different needs, and although Clusterpedia provides many easy search options, such as specifying a set of namespaces or clusters, or specifying an owner for a query, users may still need to use more complex queries to query the resources.

In this case, you can use the `Raw SQL Query` provided by the `default storage layer` to pass more complex search conditions by enabling either of the following feature gates:
In this case, you can use the `Raw SQL Query` provided by the `default storage layer` to pass more complex search conditions by enabling either of the following Feature Gates:

| desc | feature gates | default |
| desc | Feature Gates | default |
|------|---------------|---------|
| Allow search conditions to be set using raw SQL. | `AllowRawSQLQuery` | `false` |
| Allow querying by the parameterized SQL (for better defense against SQL injection). | `AllowParameterizedSQLQuery` | `false` |

Note: **This feature gate is exclusive to the `clusterpedia apiserver`.**
Note: **This Feature Gate is exclusive to the `clusterpedia apiserver`.**

{{% alert title="Disclaimer" color="warning" %}}

Either of `AllowRawSQLQuery` and `AllowParameterizedSQLQuery` feature gates will potentially introduce vulnerabilities to SQL injection when enabled since the final SQL statements is not possible to be wrapped, escaped, parameterized, or validated by Clusterpedia.
Either of `AllowRawSQLQuery` and `AllowParameterizedSQLQuery` Feature Gates will potentially introduce vulnerabilities to SQL injection when enabled since the final SQL statements is not possible to be wrapped, escaped, parameterized, or validated by Clusterpedia.

Such vulnerabilities can be exploited by malicious users to access unauthorized data or even causing data leaks, data loss and corruption.

It is always the responsibility and obligation of callers and end users interacting with Clusterpedia to defend incoming SQL WHERE clauses to protect data and resources from malicious access.

Clusterpedia cannot guarantee there will be no potential threats of SQL injections in the future and should never be when raw SQL involves.

If you still need to use the "Raw SQL Query" functionalities while understood the potential security issues, it is recommended to use the `AllowParameterizedSQLQuery` feature gate rather than the `AllowRawSQLQuery` feature gate. The introduced parameters of `AllowParameterizedSQLQuery` feature gate allow callers to pass statements and parameters separately, which can be better protected against SQL injection.
If you still need to use the "Raw SQL Query" functionalities while understood the potential security issues, it is recommended to use the `AllowParameterizedSQLQuery` Feature Gate rather than the `AllowRawSQLQuery` Feature Gate. The introduced parameters of `AllowParameterizedSQLQuery` Feature Gate allow callers to pass statements and parameters separately, which can be better protected against SQL injection.

{{% /alert %}}

Expand All @@ -34,7 +34,7 @@ If you still need to use the "Raw SQL Query" functionalities while understood th

Raw SQL queries are currently in alpha and are not well protected against SQL injection, so you need to enable this feature via Feature Gate.

And due to the introduction of the `AllowParameterizedSQLQuery` feature gate later, this feature gate has serious flaws in defending against SQL injection, and will be deprecated in future versions, and it is not recommended to use this feature gate.
And due to the introduction of the `AllowParameterizedSQLQuery` Feature Gate later, this Feature Gate has serious flaws in defending against SQL injection, and will be deprecated in future versions, and it is not recommended to use this Feature Gate.

{{% /alert %}}

Expand Down Expand Up @@ -81,6 +81,8 @@ Once enabled, three additional query parameters will be introduced:

Assumes we have the following resources:

### Use cases

```shell
$ kubectl get all -A
NAMESPACE NAME READY STATUS RESTARTS AGE
Expand All @@ -100,8 +102,6 @@ clusterpedia-test-ns replicaset.apps/hello-node-in-clusterpedia-test-ns-6fbb88
default replicaset.apps/hello-node-7579565d66 1 1 1 4h9m
```

### Use cases

#### Use of `whereSQLStatement` and single `whereSQLParam`

When querying the resources, callers should use `?` (question mark) to represent the parameters in the SQL statement, and pass the actual parameters in the `whereSQLParam` field.
Expand Down Expand Up @@ -313,11 +313,11 @@ You will get the following resources that returned by database:
| :--- | :--- |
| `hello-node` | `default` |

### How to defense against SQL injection when `AllowParameterizedSQLQuery` feature gate is enabled?
### How to defense against SQL injection when `AllowParameterizedSQLQuery` Feature Gate is enabled?

The most common SQL injection is to use the `OR` operator to bypass the original SQL statement and return all the resources in the database.

Let's say when `AllowRawSQLQuery` feature gate is enabled, the caller sends the following request:
Let's say when `AllowRawSQLQuery` Feature Gate is enabled, the caller sends the following request:

```shell
URL="/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments"
Expand All @@ -342,7 +342,7 @@ The problem is that **the `OR` operator with statement of `1 = 1` will always be

And this is quite hard to wrap, escape, and validate the SQL statement since in some extreme cases, such as resource search by users, the caller may need to pass the SQL statement directly to the apiserver without any modification.

However, such SQL injection can be easily avoided by using `whereSQLStatement` and `whereSQLParam` by enabling `AllowParameterizedSQLQuery` feature gate instead.
However, such SQL injection can be easily avoided by using `whereSQLStatement` and `whereSQLParam` by enabling `AllowParameterizedSQLQuery` Feature Gate instead.

For example, with the same constructed payload:

Expand Down Expand Up @@ -372,17 +372,12 @@ WHERE
AND namespace = "\"\" OR 1 = 1"
```

you will get the following resources that returned by database:

| name | namespace |
| :--- | :--- |

instead of all the resources in the database.
you will **get none (0) resources that returned** by database instead of all the resources in the database.

This is because when using either the `whereSQLParam` or the `whereSQLJSONParams` parameter, the values passed in are parsed as strings before it got executed inside of the database, therefore `"" OR 1 = 1` will be treated as string literals rather than as part of the SQL statement, thus avoiding SQL injection.

## Security Considerations

1. While `AllowParameterizedSQLQuery` feature gate offers better defense against SQL injection, the potentials of SQL injection will **NEVER** be resolved if implementations of caller still use string concatenation to build the raw SQL query with parameters directly without `whereSQLParam` or `whereSQLJSONParams` when using `whereSQLStatement`.
1. While `AllowParameterizedSQLQuery` Feature Gate offers better defense against SQL injection, the potentials of SQL injection will **NEVER** be resolved if implementations of caller still use string concatenation to build the raw SQL query with parameters directly without `whereSQLParam` or `whereSQLJSONParams` when using `whereSQLStatement`.
2. It is recommended to update all the existing SQLs of raw queries to pass the parameters of raw SQL in `whereSQLParam` or `whereSQLJSONParams` field instead of `whereSQL` field when string concatenation is used to construct SQL statements or fuzzy search is implemented.
3. For more about the SQL injection of GORM, please read it more here: [https://gorm.io/docs/security.html](https://gorm.io/docs/security.html).
2 changes: 1 addition & 1 deletion content/zh/docs/features/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Clusterpedia APIServer 和 Clusterpedia ClusterSynchro Manager 分别具有不
|---|--------|----|
| [设置默认返回剩余的资源数量](./remaining-item-count) | `RemainingItemCount` | `false` |
| [原生 SQL 查询](./raw-sql-query) | `AllowRawSQLQuery` | `false` |
| [Raw Parameterized SQL Query](./raw-sql-query) | `AllowRawSQLQueryWithParameter` | `false` |
| [原生参数化 SQL 查询](./raw-sql-query) | `AllowRawSQLQueryWithParameter` | `false` |

## ClusterSynchro Manager

Expand Down
25 changes: 10 additions & 15 deletions content/zh/docs/features/raw-sql-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ weight: 2

Clusterpedia 不能保证将来不会有 SQL 注入的潜在威胁,而且在涉及原始 SQL 时也不应该能够保证。

如果已经知晓上述提及的安全问题,并且还是希望使用「原生 SQL 查询」的能力,建议使用 `AllowParameterizedSQLQuery` Feature Gate 而不是 `AllowRawSQLQuery` Feature Gate 。这是因为 `AllowParameterizedSQLQuery` 特性门口引入的参数允许调用方分别传递**语句****参数**,这可以更易于防御 SQL 注入。
如果已经知晓上述提及的安全问题,并且还是希望使用「原生 SQL 查询」的能力,建议使用 `AllowParameterizedSQLQuery` Feature Gate 而不是 `AllowRawSQLQuery` Feature Gate 。这是因为 `AllowParameterizedSQLQuery` Feature Gate 引入的参数允许调用方分别传递**语句****参数**,这可以更易于防御 SQL 注入。

{{% /alert %}}

Expand All @@ -47,7 +47,7 @@ kubectl get --raw="$URL?whereSQL=(cluster='global') OR (namespace IN ('kube-syst

在这个示例中,我们传递了一个用于查询 SQL 语句的 *WHERE* 子句:

```
```sql
(cluster='global') OR (namespace IN ('kube-system','default'))
```

Expand Down Expand Up @@ -75,10 +75,12 @@ WHERE

| 字段 | 类型 | 说明 |
| :--- | :--- | :--- |
| `whereSQLStatement` | `string` | SQL 语句的 `WHERE` 子句正文。可直接替换现有的 `whereSQL` 字段。通过使用 `?` 作为参数占位符(与 GORM 兼容),允许调用方更安全地发送原生。 |
| `whereSQLParam` | `string``string[]` | 将在 SQL 语句的 `WHERE` 子句中使用的 SQL 语句的实际参数。此字段仅在设置了 `whereSQLStatement硬拼接为` 时有效,否则将被忽略。 的一部分。
| `whereSQLStatement` | `string` | SQL 语句的 `WHERE` 子句正文。可直接替换现有的 `whereSQL` 字段。通过使用 `?` 作为参数占位符(与 GORM 兼容),允许调用方更安全地发送原生 SQL 查询|
| `whereSQLParam` | `string``string[]` | 将在 SQL 语句的 `WHERE` 子句中使用的 SQL 语句的实际参数。此字段仅在设置了 `whereSQLStatement` 时有效,否则将被忽略。 |
| `whereSQLJSONParams` | `any[]` | 工作原理与 `whereSQLParam`相同,但在使用 `IN``JSON` 操作符时,调用方可以通过这个参数发送数组和更复杂的参数。支持任意的 JSON 数组字符串,并且由于查询字符串不能包含 `[]`(方括号),因此需要进行 `base64` 编码。该字段仅在设置了 `whereSQLStatement` 时有效,否则将被忽略。 |

### 使用案例

假设我们拥有以下资源

```shell
Expand All @@ -100,8 +102,6 @@ clusterpedia-test-ns replicaset.apps/hello-node-in-clusterpedia-test-ns-6fbb88
default replicaset.apps/hello-node-7579565d66 1 1 1 4h9m
```

### 使用案例

#### `whereSQLStatement` 参数搭配单个 `whereSQLParam` 参数使用

查询资源时,调用方应使用 `?`(问号)来表示 SQL 语句中的参数,并在 `whereSQLParam` 字段中传递实际参数。
Expand Down Expand Up @@ -304,11 +304,11 @@ WHERE
| :--- | :--- |
| `hello-node` | `default` |

### 启用 `AllowParameterizedSQLQuery` 功能门时,如何防御 SQL 注入?
### 启用 `AllowParameterizedSQLQuery` Feature Gate 时,如何防御 SQL 注入?

最常见的 SQL 注入是使用 `OR` 操作符绕过原始 SQL 语句,返回数据库中的所有资源。

假设启用了 `AllowRawSQLQuery` 功能门控,调用方将会像这样发送请求:
假设启用了 `AllowRawSQLQuery` Feature Gate,调用方将会像这样发送请求:

```shell
URL="/apis/clusterpedia.io/v1beta1/resources/apis/apps/v1/deployments"
Expand Down Expand Up @@ -365,17 +365,12 @@ WHERE

这个语句会检索 `"" OR 1 = 1` 命名空间下的 `deployments` 类型的资源。

最终将获得数据库返回的以下资源:

| 资源名称 | namespace |
| :--- | :--- |

而不是所有资源。
最终将获得数据库**返回 0 个资源,而不是所有资源**

这是因为在使用 `whereSQLParam` 参数或是 `whereSQLJSONParams` 参数时,传入的值将在数据库执行前被解析为字符串,因此 `"" OR 1 = 1` 将被视为字符串字面形式,而不是 SQL 语句的一部分,从而避免了 SQL 注入。

## 安全注意事项

1. 虽然 `AllowParameterizedSQLQuery` 功能门提供了更好的 SQL 注入防御,但如果调用者的实现在使用 `whereSQLStatement` 时仍使用字符串连接来直接构建带参数的原始 SQL 查询,而不使用 `whereSQLParam``whereSQLJSONParams` 参数,那么 SQL 注入的隐患将**永远**无法解决。
1. 虽然 `AllowParameterizedSQLQuery` Feature Gate 提供了更好的 SQL 注入防御,但如果调用者的实现在使用 `whereSQLStatement` 时仍使用字符串连接来直接构建带参数的原始 SQL 查询,而不使用 `whereSQLParam``whereSQLJSONParams` 参数,那么 SQL 注入的隐患将**永远**无法解决。
2. 在涉及到模糊搜索、字符串拼接的使用场景的时候,建议更新所有现有的原生 SQL 查询,将原始 SQL 的参数传递到 `whereSQLParam``whereSQLJSONParams` 字段,而不是硬拼接为 `whereSQL` 字段的一部分。
3. 有关 GORM 的 SQL 注入的更多信息,请在此处阅读更多信息:[https://gorm.io/docs/security.html](https://gorm.io/docs/security.html)

0 comments on commit c4b200a

Please sign in to comment.