@comate/zulu 1.2.1-beta.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/comate-engine/assets/skills/auto-commit-comate/SKILL.md +260 -0
- package/comate-engine/assets/skills/auto-commit-comate/references/data_structures.md +189 -0
- package/comate-engine/assets/skills/auto-commit-comate/references/new_version_instruction.md +209 -0
- package/comate-engine/assets/skills/auto-commit-comate/references/old_version_instruction.md +208 -0
- package/comate-engine/assets/skills/auto-commit-comate/scripts/git_diff_cli.py +196 -0
- package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/git_utils.py +20 -10
- package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/client.py +69 -40
- package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/farseer.py +8 -9
- package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/matching.py +65 -9
- package/comate-engine/assets/skills/auto-commit-comate/scripts/match_card_cli.py +37 -0
- package/comate-engine/assets/skills/cnap-comate/SKILL.md +157 -0
- package/comate-engine/assets/skills/cnap-comate/references/cases.md +198 -0
- package/comate-engine/assets/skills/cnap-comate/references/deploy-troubleshoot.md +15 -0
- package/comate-engine/assets/skills/cnap-comate/references/install.md +43 -0
- package/comate-engine/assets/skills/cnap-comate/references/kubectl.md +55 -0
- package/comate-engine/assets/skills/cnap-comate/references/login.md +125 -0
- package/comate-engine/assets/skills/cnap-comate/references/oncall.md +24 -0
- package/comate-engine/assets/skills/cnap-comate/scripts/install_cnap_cli.sh +36 -0
- package/comate-engine/assets/skills/code-security/SKILL.md +176 -0
- package/comate-engine/assets/skills/code-security/references/credential_hosting.md +102 -0
- package/comate-engine/assets/skills/code-security/references/vul_repair_sensitive.md +219 -0
- package/comate-engine/assets/skills/code-security/scripts/build_repair_info.py +0 -0
- package/comate-engine/assets/skills/code-security/scripts/credential_hosting.py +99 -0
- package/comate-engine/assets/skills/code-security/scripts/credential_poll.py +350 -0
- package/comate-engine/assets/skills/code-security/scripts/http_client.py +173 -0
- package/comate-engine/assets/skills/code-security/scripts/parse_scan_result.py +301 -0
- package/comate-engine/assets/skills/code-security/scripts/repair_vulnerability.py +261 -0
- package/comate-engine/assets/skills/code-security/scripts/report_chat.py +198 -0
- package/comate-engine/assets/skills/code-security/scripts/scan_vulnerability.py +316 -0
- package/comate-engine/assets/skills/code-security-comate/SKILL.md +219 -0
- package/comate-engine/assets/skills/code-security-comate/references/credential_hosting.md +102 -0
- package/comate-engine/assets/skills/code-security-comate/references/vul_repair-go_sql_injection.md +399 -0
- package/comate-engine/assets/skills/code-security-comate/references/vul_repair-java_sql_injection.md +591 -0
- package/comate-engine/assets/skills/code-security-comate/references/vul_repair-php_sql_injection.md +318 -0
- package/comate-engine/assets/skills/code-security-comate/references/vul_repair-python_sql_injection.md +198 -0
- package/comate-engine/assets/skills/code-security-comate/references/vul_repair_sensitive.md +219 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/credential_hosting.py +87 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/credential_poll.py +345 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/http_client.py +173 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/parse_scan_result.py +392 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/repair_vulnerability.py +245 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/report_chat.py +145 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/scan_vulnerability.py +444 -0
- package/comate-engine/assets/skills/code-security-comate/scripts/utils.py +153 -0
- package/comate-engine/assets/skills/comate-docs-comate/SKILL.md +148 -0
- package/comate-engine/assets/skills/comate-docs-comate/references/doc-map-extended.md +78 -0
- package/comate-engine/assets/skills/comate-docs-comate/references/models-and-billing.md +51 -0
- package/comate-engine/assets/skills/comate-docs-comate/references/product-overview.md +73 -0
- package/comate-engine/assets/skills/comate-docs-comate/references/query_content.md +83 -0
- package/comate-engine/assets/skills/comate-docs-comate/references/query_repo.md +57 -0
- package/comate-engine/assets/skills/comate-docs-comate/scripts/ku_operator.py +1575 -0
- package/comate-engine/assets/skills/create-image-comate/SKILL.md +278 -0
- package/comate-engine/assets/skills/create-skill-comate/SKILL.md +308 -217
- package/comate-engine/assets/skills/create-skill-comate/agents/analyzer.md +274 -0
- package/comate-engine/assets/skills/create-skill-comate/agents/comparator.md +202 -0
- package/comate-engine/assets/skills/create-skill-comate/agents/grader.md +223 -0
- package/comate-engine/assets/skills/create-skill-comate/assets/eval_review.html +146 -0
- package/comate-engine/assets/skills/create-skill-comate/eval-viewer/generate_review.py +489 -0
- package/comate-engine/assets/skills/create-skill-comate/eval-viewer/viewer.html +1325 -0
- package/comate-engine/assets/skills/create-skill-comate/references/schemas.md +430 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/__init__.py +0 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/__pycache__/aggregate_benchmark.cpython-311.pyc +0 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/aggregate_benchmark.py +412 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/generate_report.py +334 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/package_skill.py +140 -0
- package/comate-engine/assets/skills/create-skill-comate/scripts/utils.py +53 -0
- package/comate-engine/assets/skills/find-skills-comate/SKILL.md +15 -12
- package/comate-engine/assets/skills/find-skills-comate/scripts/fetch_skills.py +32 -3
- package/comate-engine/assets/skills/get-ugate-token-comate/SKILL.md +159 -0
- package/comate-engine/assets/skills/get-ugate-token-comate/getUgateToken.py +150 -0
- package/comate-engine/assets/skills/icafe-comate/SKILL.md +240 -0
- package/comate-engine/assets/skills/icafe-comate/references/ai-workflows.md +233 -0
- package/comate-engine/assets/skills/icafe-comate/references/commands.md +1147 -0
- package/comate-engine/assets/skills/icafe-comate/references/error-handling.md +164 -0
- package/comate-engine/assets/skills/icafe-comate/references/git-auto-bindcard-workflow.md +201 -0
- package/comate-engine/assets/skills/icafe-comate/references/git-bindcard-workflow.md +327 -0
- package/comate-engine/assets/skills/icafe-comate/references/iql-syntax.md +327 -0
- package/comate-engine/assets/skills/icafe-comate/references/platform-concepts.md +317 -0
- package/comate-engine/assets/skills/icafe-comate/references/smart-create-workflow.md +171 -0
- package/comate-engine/assets/skills/icafe-comate/references/smart-find-workflow.md +127 -0
- package/comate-engine/assets/skills/icafe-comate/references/smart-update-workflow.md +118 -0
- package/comate-engine/assets/skills/icode-comate/SKILL.md +366 -0
- package/comate-engine/assets/skills/icode-comate/references/api/add_reviewers.md +44 -0
- package/comate-engine/assets/skills/icode-comate/references/api/build_fetch_command.md +89 -0
- package/comate-engine/assets/skills/icode-comate/references/api/check_repo_permission.md +89 -0
- package/comate-engine/assets/skills/icode-comate/references/api/create_branch.md +79 -0
- package/comate-engine/assets/skills/icode-comate/references/api/create_draft_comment.md +109 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_ai_cr_result.md +190 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_ai_review.md +97 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_diff_content.md +92 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_diff_file.md +88 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_machine_check.md +73 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_my_reviews.md +115 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_person_commit.md +89 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_person_repo.md +63 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_repo_branch.md +62 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_repo_config.md +91 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_repo_members.md +118 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_repo_reviews.md +91 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_review_comments.md +87 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_review_info.md +81 -0
- package/comate-engine/assets/skills/icode-comate/references/api/get_submit_settings.md +105 -0
- package/comate-engine/assets/skills/icode-comate/references/api/icode-api.md +86 -0
- package/comate-engine/assets/skills/icode-comate/references/api/publish_comments.md +72 -0
- package/comate-engine/assets/skills/icode-comate/references/api/set_review_score.md +58 -0
- package/comate-engine/assets/skills/icode-comate/references/api/start_ai_review.md +77 -0
- package/comate-engine/assets/skills/icode-comate/references/api/submit_review.md +50 -0
- package/comate-engine/assets/skills/icode-comate/references/api/trigger_ai_cr.md +63 -0
- package/comate-engine/assets/skills/icode-comate/references/feature/add-reviewer.md +92 -0
- package/comate-engine/assets/skills/icode-comate/references/feature/fix-machine-check.md +144 -0
- package/comate-engine/assets/skills/icode-comate/references/feature/merge-cr.md +100 -0
- package/comate-engine/assets/skills/icode-comate/references/feature/ssh-setup.md +106 -0
- package/comate-engine/assets/skills/icode-comate/references/feature/submit-acr.md +135 -0
- package/comate-engine/assets/skills/icode-comate/references/feature/submit-cr.md +123 -0
- package/comate-engine/assets/skills/icode-comate/references/git/clone.md +67 -0
- package/comate-engine/assets/skills/icode-comate/references/git/icode-git.md +68 -0
- package/comate-engine/assets/skills/icode-comate/references/git/push.md +64 -0
- package/comate-engine/assets/skills/icode-comate/references/git/push_cr.md +103 -0
- package/comate-engine/assets/skills/icode-comate/references/install.md +144 -0
- package/comate-engine/assets/skills/icode-comate/references/login.md +111 -0
- package/comate-engine/assets/skills/icode-comate/scripts/add-reviewer.sh +154 -0
- package/comate-engine/assets/skills/icode-comate/scripts/common.sh +145 -0
- package/comate-engine/assets/skills/icode-comate/scripts/fix-machine-check.sh +131 -0
- package/comate-engine/assets/skills/icode-comate/scripts/merge-cr.sh +105 -0
- package/comate-engine/assets/skills/icode-comate/scripts/ssh-setup.sh +159 -0
- package/comate-engine/assets/skills/icode-comate/scripts/submit-acr.sh +236 -0
- package/comate-engine/assets/skills/icode-comate/scripts/submit-cr.sh +104 -0
- package/comate-engine/assets/skills/icode-comate/scripts/test-preflight.sh +89 -0
- package/comate-engine/assets/skills/ku-operator-comate/SKILL.md +121 -0
- package/comate-engine/assets/skills/ku-operator-comate/examples.md +190 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/add_member.md +49 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/change_scope.md +38 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/copy_doc.md +50 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/create_doc.md +61 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/delete_doc.md +31 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/edit_content.md +568 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/move_doc.md +45 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_comment.md +79 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_content.md +83 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_flowchart.md +84 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_permission.md +38 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_recent_view.md +67 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_repo.md +57 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/query_user_info.md +37 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/update_member.md +41 -0
- package/comate-engine/assets/skills/ku-operator-comate/references/upload_attachment.md +52 -0
- package/comate-engine/assets/skills/ku-operator-comate/scripts/ku_operator.py +1575 -0
- package/comate-engine/node_modules/better-sqlite3/node_modules/.bin/prebuild-install +2 -2
- package/comate-engine/node_modules/tree-sitter-bash/node_modules/.bin/node-gyp-build +2 -2
- package/comate-engine/node_modules/tree-sitter-bash/node_modules/.bin/node-gyp-build-optional +2 -2
- package/comate-engine/node_modules/tree-sitter-bash/node_modules/.bin/node-gyp-build-test +2 -2
- package/comate-engine/package.json +2 -0
- package/comate-engine/server.js +263 -79
- package/dist/bundle/index.js +8 -8
- package/package.json +1 -1
- package/comate-engine/assets/skills/figma2code-comate/codeConnect.md +0 -37
- package/comate-engine/assets/skills/figma2code-comate/designToken.md +0 -3
- package/comate-engine/assets/skills/figma2code-comate/f2cMcp.md +0 -59
- package/comate-engine/assets/skills/smart-commit/SKILL.md +0 -646
- package/comate-engine/node_modules/@comate/plugin-host/dist/index-AZIho4HV.js +0 -1
- package/comate-engine/node_modules/@comate/plugin-host/dist/user-BIpzRUfb.js +0 -44
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/references/issue_type_mapping.json +0 -0
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/references/query_reference.md +0 -0
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/compat.py +0 -0
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/create_card_cli.py +0 -0
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/icafe/__init__.py +0 -0
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/logger.py +0 -0
- /package/comate-engine/assets/skills/{smart-commit → auto-commit-comate}/scripts/recognize_card_cli.py +0 -0
package/comate-engine/assets/skills/code-security-comate/references/vul_repair-php_sql_injection.md
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
php sqli 漏洞修复知识
|
|
2
|
+
|
|
3
|
+
# PHP SQL 注入漏洞修复最佳实践
|
|
4
|
+
采用先分析漏洞报告 -> 分析数据传递链路 -> 判断依赖与副作用 -> 选择修复方式 -> 修复 -> 校验的流程。
|
|
5
|
+
|
|
6
|
+
注意:**不要做与漏洞修复无关的代码改动**。
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## I. 核心修复分析逻辑
|
|
11
|
+
在开始修改代码前,仅需确认以下四点:
|
|
12
|
+
|
|
13
|
+
1. **分析修复方式**
|
|
14
|
+
|
|
15
|
+
* **值绑定**:数据值(如 `id=1`, `name='test'`)-> 必须预编译/参数绑定。
|
|
16
|
+
* **结构定义**:表名、列名、排序方向等结构化 SQL 片段 -> 必须过滤。
|
|
17
|
+
|
|
18
|
+
2. **分析数据链路**
|
|
19
|
+
|
|
20
|
+
* 确认变量从哪里进入、在哪个 sink 执行。
|
|
21
|
+
* 检查是否跨函数、跨文件、跨层(Controller -> Service -> DAO)。
|
|
22
|
+
|
|
23
|
+
3. **依赖与副作用**
|
|
24
|
+
|
|
25
|
+
* 修改函数签名后,调用方是否需要同步。
|
|
26
|
+
* 同一 SQL 在其他位置是否复用,修复是否会影响其他逻辑。
|
|
27
|
+
|
|
28
|
+
4. **框架能力确认(修复前必做)**
|
|
29
|
+
|
|
30
|
+
* 确认当前 DB/DAO 是否支持:`prepare`、`query($sql, $params)`、`execute($sql, $params)`。
|
|
31
|
+
* **禁止猜测 API**:若代码库中不存在该方法,不可直接使用。
|
|
32
|
+
* 修复前先查当前类同文件/同包已有调用方式,优先复用项目内已验证的安全写法。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## II. Yii (Yii2) 框架修复方案
|
|
37
|
+
Yii 提供了较完善的防注入机制,核心原则:**优先使用数组语法(Hash Format)代替字符串拼接**。
|
|
38
|
+
|
|
39
|
+
### 1. ActiveRecord / Query Builder(推荐)
|
|
40
|
+
Yii 的 `ActiveRecord` 和 `Query` 在数组条件场景会自动进行参数绑定。
|
|
41
|
+
|
|
42
|
+
**场景 A:普通条件查询**
|
|
43
|
+
|
|
44
|
+
```php
|
|
45
|
+
// Bad
|
|
46
|
+
$user = User::find()->where("name = '" . $name . "'")->one();
|
|
47
|
+
|
|
48
|
+
// Fix
|
|
49
|
+
$user = User::find()->where(['name' => $name])->one();
|
|
50
|
+
|
|
51
|
+
// 复杂条件
|
|
52
|
+
$users = User::find()->where(['>', 'age', $age])->all();
|
|
53
|
+
```
|
|
54
|
+
**场景 B:IN 查询**
|
|
55
|
+
|
|
56
|
+
```php
|
|
57
|
+
// Bad
|
|
58
|
+
$ids = $_GET['ids'];
|
|
59
|
+
$users = User::find()->where("id IN ($ids)")->all();
|
|
60
|
+
|
|
61
|
+
// Fix
|
|
62
|
+
$ids = explode(',', $_GET['ids']);
|
|
63
|
+
$users = User::find()->where(['id' => $ids])->all();
|
|
64
|
+
```
|
|
65
|
+
### 2. DAO / 原生 SQL(createCommand)
|
|
66
|
+
```php
|
|
67
|
+
// Bad
|
|
68
|
+
$sql = "SELECT * FROM post WHERE id=" . $id;
|
|
69
|
+
$posts = Yii::$app->db->createCommand($sql)->queryAll();
|
|
70
|
+
|
|
71
|
+
// Fix
|
|
72
|
+
$sql = "SELECT * FROM post WHERE id=:id";
|
|
73
|
+
$posts = Yii::$app->db->createCommand($sql)
|
|
74
|
+
->bindValue(':id', $id)
|
|
75
|
+
->queryAll();
|
|
76
|
+
```
|
|
77
|
+
### 3. `findBySql` 修复
|
|
78
|
+
```php
|
|
79
|
+
// Bad
|
|
80
|
+
$sql = "SELECT * FROM user WHERE status=" . $status;
|
|
81
|
+
$users = User::findBySql($sql)->all();
|
|
82
|
+
|
|
83
|
+
// Fix
|
|
84
|
+
$sql = "SELECT * FROM user WHERE status=:status";
|
|
85
|
+
$users = User::findBySql($sql, [':status' => $status])->all();
|
|
86
|
+
```
|
|
87
|
+
### 4. 无法预编译场景(Order By / Table Name)
|
|
88
|
+
```php
|
|
89
|
+
$sort = $_GET['sort'];
|
|
90
|
+
$regex = "/^[\w\s\[\]" . "`" . "$.,*]+$/";
|
|
91
|
+
|
|
92
|
+
if (!preg_match($regex, $sort)) {
|
|
93
|
+
throw new \yii\web\BadRequestHttpException("Invalid sort parameter");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
$users = User::find()->orderBy($sort)->all();
|
|
97
|
+
```
|
|
98
|
+
### 5. Yii 常见错误(必须规避)
|
|
99
|
+
1. `execute()`** 返回值误用**:Yii2 `execute()` 返回影响行数(int),不能继续 `->queryAll()`。
|
|
100
|
+
2. **提前创建 Command**:必须先拼完 SQL,再 `createCommand($sql)`。
|
|
101
|
+
3. **Yii1 **`criteria->params`** 覆盖**:`$criteria->params = [...]` 会覆盖已设置参数,需合并而非覆盖。
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## III. ODP 框架修复方案
|
|
106
|
+
适用于 `Bd_Db_ConnMgr` 等 DB 封装。
|
|
107
|
+
|
|
108
|
+
### 1. SQL 模板方式(推荐)
|
|
109
|
+
```php
|
|
110
|
+
$template = "SELECT * FROM users WHERE id={id:n} AND name={name:s}";
|
|
111
|
+
$sqlTemplate = new Bd_Db_SQLTemplate($db);
|
|
112
|
+
$sqlTemplate->prepare($template);
|
|
113
|
+
$sqlTemplate->bindParam('id', $userId);
|
|
114
|
+
$sqlTemplate->bindParam('name', $userName);
|
|
115
|
+
$sql = $sqlTemplate->getSQL();
|
|
116
|
+
```
|
|
117
|
+
### 2. SQL 组合器方式
|
|
118
|
+
```php
|
|
119
|
+
// 安全
|
|
120
|
+
$result = $db->select(
|
|
121
|
+
'users',
|
|
122
|
+
['id', 'name', 'email'],
|
|
123
|
+
['id' => $userId, 'status' => 1]
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
// 危险
|
|
127
|
+
$result = $db->select('users', '*', "id = $userId AND name = '$userName'");
|
|
128
|
+
```
|
|
129
|
+
### 3. 预处理语句方式(以项目实际 API 为准)
|
|
130
|
+
```php
|
|
131
|
+
$stmt = $db->prepare("SELECT * FROM users WHERE id = ? AND name = ?");
|
|
132
|
+
$stmt->bindParam('is', $userId, $userName);
|
|
133
|
+
$result = $stmt->execute();
|
|
134
|
+
```
|
|
135
|
+
### 4. 使用前先确认 API 存在
|
|
136
|
+
* 仅在代码库确认存在 `Bd_Db_SQLTemplate` / `queryf` / `prepare` 等 API 时才可使用。
|
|
137
|
+
* 若当前项目 DB 类仅支持 `query($sql)`,不可硬改成不存在的方法。
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## III.1 safeFilter / safeValidate 过滤函数规范
|
|
142
|
+
### 1. 命名与目标
|
|
143
|
+
* 过滤函数命名必须以 `safeFilter` 或 `safeValidate` 开头。
|
|
144
|
+
* 目的:
|
|
145
|
+
|
|
146
|
+
1. 统一修复风格;
|
|
147
|
+
2. 便于规则引擎识别清洗点(已存在对应 sanitizer 规则)。
|
|
148
|
+
|
|
149
|
+
### 2. 使用规则
|
|
150
|
+
1. **必须使用临时变量承接过滤结果**,后续 SQL 只能使用安全变量。
|
|
151
|
+
2. 禁止“过滤后继续使用原变量”。
|
|
152
|
+
3. 非法输入必须返回错误/中断,不允许静默放行。
|
|
153
|
+
4. 对对象参数,优先提供“对象级过滤函数”,返回安全对象后再下传。
|
|
154
|
+
|
|
155
|
+
### 3. 示例(标量)
|
|
156
|
+
```php
|
|
157
|
+
function safeFilterOrderBy($input) {
|
|
158
|
+
$regex = '/^[\w\s\[\]"`$.,*]+$/';
|
|
159
|
+
if (!is_string($input) || !preg_match($regex, $input)) {
|
|
160
|
+
throw new InvalidArgumentException('Invalid order by');
|
|
161
|
+
}
|
|
162
|
+
return $input;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
$safeOrderBy = safeFilterOrderBy($orderBy);
|
|
166
|
+
$sql = "SELECT * FROM t ORDER BY {$safeOrderBy}";
|
|
167
|
+
```
|
|
168
|
+
### 4. 示例(对象)
|
|
169
|
+
```php
|
|
170
|
+
function safeValidateQuery($query) {
|
|
171
|
+
$regex = '/^[\w\s\[\]"`$.,*]+$/';
|
|
172
|
+
if (isset($query['sort']) && !preg_match($regex, $query['sort'])) {
|
|
173
|
+
throw new InvalidArgumentException('Invalid sort');
|
|
174
|
+
}
|
|
175
|
+
return $query;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
$safeQuery = safeValidateQuery($query);
|
|
179
|
+
$sort = $safeQuery['sort'] ?? 'id DESC';
|
|
180
|
+
```
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## IV. 原生 PHP / PDO 修复方案(通用)
|
|
184
|
+
### 1. 预编译修复(跨函数/数据流)
|
|
185
|
+
当 SQL 在一个函数构建、另一个函数执行时,可通过默认参数兼容改造。
|
|
186
|
+
|
|
187
|
+
```php
|
|
188
|
+
// Bad
|
|
189
|
+
function getInfo($id) {
|
|
190
|
+
$sql = "SELECT * FROM news WHERE id = $id";
|
|
191
|
+
return fetchAll($sql);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function fetchAll($sql) {
|
|
195
|
+
global $conn;
|
|
196
|
+
return $conn->query($sql);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Fix
|
|
200
|
+
function getInfo($id) {
|
|
201
|
+
$sql = "SELECT * FROM news WHERE id = ?";
|
|
202
|
+
return fetchAll($sql, [$id]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function fetchAll($sql, $params = []) {
|
|
206
|
+
global $conn;
|
|
207
|
+
$stmt = $conn->prepare($sql);
|
|
208
|
+
$stmt->execute($params);
|
|
209
|
+
return $stmt->fetchAll();
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
### 2. IN 子句修复(原生 PDO)
|
|
213
|
+
```php
|
|
214
|
+
$ids = explode(',', $inputIds);
|
|
215
|
+
if (empty($ids)) {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
$inQuery = implode(',', array_fill(0, count($ids), '?'));
|
|
220
|
+
$sql = "SELECT * FROM table WHERE id IN ($inQuery)";
|
|
221
|
+
$stmt = $pdo->prepare($sql);
|
|
222
|
+
$stmt->execute($ids);
|
|
223
|
+
$rows = $stmt->fetchAll();
|
|
224
|
+
```
|
|
225
|
+
### 3. IN 子句强约束(必须满足)
|
|
226
|
+
1. 禁止 `IN (:ids)` 直接绑定数组。
|
|
227
|
+
2. 占位符数量必须与参数数量一致。
|
|
228
|
+
3. 空数组必须有兜底逻辑(返回空结果或显式中断)。
|
|
229
|
+
4. 禁止出现参数翻倍、错位绑定。
|
|
230
|
+
|
|
231
|
+
### 4. PDO 常见错误(必须规避)
|
|
232
|
+
1. `execute()` 返回 bool,不能当 Statement 使用。
|
|
233
|
+
2. `prepare + bindValue` 后必须 `execute()` 再 `fetch/fetchAll`。
|
|
234
|
+
3. 禁止同一 SQL 中混用 `?` 与 `:name`。
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## V. 必须使用正则过滤的场景
|
|
239
|
+
以下场景不支持预编译,必须使用正则 `^[\w\s\[\]\"\x60$.,*]+$` 过滤:
|
|
240
|
+
|
|
241
|
+
1. 动态表名/库名:`FROM $tableName`
|
|
242
|
+
2. 动态列名:`SELECT $columnName`
|
|
243
|
+
3. Order By:`ORDER BY $field $direction`
|
|
244
|
+
4. DDL/DCL:`CREATE`, `DROP`, `GRANT`, `SHOW`
|
|
245
|
+
|
|
246
|
+
**代码复用提示**
|
|
247
|
+
|
|
248
|
+
* 若文件头/类常量已定义类似正则(如 `SAFE_SQL_PATTERN`),直接复用。
|
|
249
|
+
|
|
250
|
+
### 补充:操作符/排序方向建议枚举校验(不替换现有正则)
|
|
251
|
+
在保留上述正则前提下,建议叠加枚举校验:
|
|
252
|
+
|
|
253
|
+
```php
|
|
254
|
+
$direction = strtoupper(trim($direction));
|
|
255
|
+
if (!in_array($direction, ['ASC', 'DESC'], true)) {
|
|
256
|
+
throw new InvalidArgumentException('Invalid sort direction');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
$op = strtoupper(trim($op));
|
|
260
|
+
$validOps = ['=', '!=', '<', '<=', '>', '>=', 'LIKE', 'IN'];
|
|
261
|
+
if (!in_array($op, $validOps, true)) {
|
|
262
|
+
throw new InvalidArgumentException('Invalid operator');
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## VI. 不可修复场景
|
|
268
|
+
遇到以下情况,标记为不可修复,不强行修改:
|
|
269
|
+
|
|
270
|
+
1. 外部生成整段 SQL(第三方 Jar/Extension/Service),无法拆解参数。
|
|
271
|
+
2. 污点作为复杂动态子句拼入(例如完整 WHERE 逻辑),无法安全结构化。
|
|
272
|
+
|
|
273
|
+
### 不可修复判定模板(建议)
|
|
274
|
+
* **数据流结论**:指出 taint 来源、传播路径、sink。
|
|
275
|
+
* **不可修复原因**:明确是“外部整段 SQL”还是“复杂子句不可拆解”。
|
|
276
|
+
* **风险说明**:说明为什么强修会破坏业务或产生误修。
|
|
277
|
+
* **建议动作**:补输入侧网关校验、人工评审、上游接口收敛。
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## VII. 修复后检查点(强检查清单)
|
|
282
|
+
1. 是否优先使用框架安全写法(Yii 数组语法等)。
|
|
283
|
+
2. 是否遗留旧拼接 SQL(避免新旧并存导致覆盖)。
|
|
284
|
+
3. 是否存在 `prepare/bind` 后漏 `execute()`。
|
|
285
|
+
4. 是否误用 `execute()` 返回值。
|
|
286
|
+
5. 占位符数量是否与参数数量一致。
|
|
287
|
+
6. 条件分支中的参数绑定是否一致、变量是否已定义。
|
|
288
|
+
7. 若改动公共函数签名,调用方是否全部兼容。
|
|
289
|
+
8. 修复位置是否与真实数据流文件/函数一致(避免改错位置)。
|
|
290
|
+
9. 是否引入语法错误、死代码或不可达代码。
|
|
291
|
+
10. 正则与枚举校验是否按预期拦截非法输入。
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## VIII. 高频修复失败反模式(来自 php_review_20260416)
|
|
296
|
+
以下为高频失败原因,修复时必须逐项自检:
|
|
297
|
+
|
|
298
|
+
1. **调用不存在 API**:如盲目使用 `prepare/queryf/execute($sql,$params)`。
|
|
299
|
+
2. **修错文件或修错函数**:与 SARIF 数据流路径不一致。
|
|
300
|
+
3. **部分修复**:只修一个分支或一部分参数,其他 sink 仍可注入。
|
|
301
|
+
4. **新旧 SQL 并存**:参数化查询后仍保留旧拼接查询。
|
|
302
|
+
5. **变量作用域错误**:分支变量在另一分支未定义即绑定。
|
|
303
|
+
6. **过滤顺序错误**:先拼接 SQL 后过滤/转义。
|
|
304
|
+
7. **仅加引号不转义**:`'$input'` 不是安全修复。
|
|
305
|
+
8. **IN 数组绑定错误**:单占位符绑定数组或空数组未兜底。
|
|
306
|
+
9. **过度依赖“看起来安全”**:未验证框架/DAO 真实能力。
|
|
307
|
+
10. **未做回归检查**:代码改了但未验证是否仍被扫描命中。
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## IX. 最小修复策略(执行建议)
|
|
312
|
+
为提高修复成功率,可按以下顺序执行:
|
|
313
|
+
|
|
314
|
+
1. 找到真实 sink 位置,确认是否可参数化。
|
|
315
|
+
2. 可参数化则优先参数化;不可参数化则走正则过滤。
|
|
316
|
+
3. 对结构化参数叠加枚举校验(方向、操作符等)。
|
|
317
|
+
4. 使用 `safeFilter/safeValidate` + 临时变量截断数据流。
|
|
318
|
+
5. 做 VII 节 10 条强检查后再提交。
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
python sqli 漏洞修复知识
|
|
2
|
+
|
|
3
|
+
# python sqli 漏洞修复最佳实践
|
|
4
|
+
采用先分析漏洞报告 -> 分析数据传递链路 -> 判断依赖与副作用 -> 选择修复方式 -> 修复漏洞 -> 验证语法与调用兼容性的流程。
|
|
5
|
+
|
|
6
|
+
注意:**不要做与漏洞修复无关的代码改动**。
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## I. 漏洞分析
|
|
11
|
+
### 1. 不可修复场景
|
|
12
|
+
1. SQL 语句由外部包/外部服务直接生成并传入,当前代码无法拆解 SQL 结构。
|
|
13
|
+
2. 污点以完整子句(如完整 `WHERE` / `ORDER` / `JOIN` 逻辑)注入,且无法安全结构化拆分。
|
|
14
|
+
3. 无法确认修复位置是否在真实数据流 sink 路径上(此时应先回到数据流定位,不盲改)。
|
|
15
|
+
|
|
16
|
+
### 2. 可修复场景
|
|
17
|
+
1. 仅在当前数据流相关文件内修复,不创建新的代码文件。
|
|
18
|
+
2. 同文件已有过滤函数/正则时优先复用。
|
|
19
|
+
3. 表名、列名、视图名、库名、`order/orderby` 等结构化 SQL 片段必须过滤,过滤正则使用:`"^[\\w\\s\\[\\]\"`$.,*]+$"`。
|
|
20
|
+
4. `show/create/drop/grant` 等场景不支持参数化绑定,必须过滤,过滤正则同上。
|
|
21
|
+
5. `IN` 参数优先参数化:按元素数量展开占位符,不允许单占位符直接绑定数组。
|
|
22
|
+
6. 同一参数只采用一种修复方式,不要叠加“过滤 + 参数化 + 转义”多种方案。
|
|
23
|
+
7. 禁止直接对完整 SQL 做“整体过滤”;应对拼接进 SQL 的污点参数做防护。
|
|
24
|
+
8. 需要改函数签名时,要保证现有调用方兼容(默认参数或同步改调用方)。
|
|
25
|
+
9. 修复前先确认当前 DB API 能力(`execute` 占位符风格、是否支持命名参数等),禁止猜测 API。
|
|
26
|
+
10. 若 SQL 在多个函数复用,修复时需一并分析其他调用点,避免只修一处导致复发。
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## II. 过滤方式规则(safeFilter / safeValidate)
|
|
31
|
+
### 1. 命名规范
|
|
32
|
+
* 过滤函数命名建议以 `safeFilter` 或 `safeValidate` 开头。
|
|
33
|
+
* 便于规则引擎识别清洗点(仓库已存在对应 sanitizer 规则)。
|
|
34
|
+
|
|
35
|
+
### 2. 使用规范
|
|
36
|
+
1. 过滤结果必须由临时变量承接,后续拼接 SQL 只能使用过滤后的变量。
|
|
37
|
+
2. 禁止“先赋值污点变量,再覆盖为安全值”的写法。
|
|
38
|
+
3. 非法输入必须抛错/返回错误,不能静默放行。
|
|
39
|
+
4. 对对象参数,建议返回安全对象后再向下传递。
|
|
40
|
+
|
|
41
|
+
### 3. 标量示例
|
|
42
|
+
```python
|
|
43
|
+
import re
|
|
44
|
+
|
|
45
|
+
SAFE_SQL_PATTERN = r'^[\w\s\[\]"`$.,*]+$'
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def safeFilterOrderBy(order_by: str) -> str:
|
|
49
|
+
if not isinstance(order_by, str) or not re.fullmatch(SAFE_SQL_PATTERN, order_by):
|
|
50
|
+
raise ValueError("invalid order by")
|
|
51
|
+
return order_by
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
safe_order = safeFilterOrderBy(request.GET.get("sort", "id DESC"))
|
|
55
|
+
sql = f"SELECT * FROM users ORDER BY {safe_order}"
|
|
56
|
+
cursor.execute(sql)
|
|
57
|
+
```
|
|
58
|
+
### 4. 对象示例
|
|
59
|
+
```python
|
|
60
|
+
import re
|
|
61
|
+
|
|
62
|
+
SAFE_SQL_PATTERN = r'^[\w\s\[\]"`$.,*]+$'
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def safeValidateQuery(query: dict) -> dict:
|
|
66
|
+
safe_query = dict(query)
|
|
67
|
+
sort_value = safe_query.get("sort")
|
|
68
|
+
if sort_value is not None and not re.fullmatch(SAFE_SQL_PATTERN, sort_value):
|
|
69
|
+
raise ValueError("invalid sort")
|
|
70
|
+
return safe_query
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
safe_query = safeValidateQuery(query)
|
|
74
|
+
sql = f"SELECT * FROM users ORDER BY {safe_query.get('sort', 'id DESC')}"
|
|
75
|
+
cursor.execute(sql)
|
|
76
|
+
```
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## III. Python 常见修复方案
|
|
80
|
+
### 1. DB-API 参数化查询(优先)
|
|
81
|
+
```python
|
|
82
|
+
# Bad
|
|
83
|
+
sql = "SELECT * FROM users WHERE username = '" + username + "'"
|
|
84
|
+
cursor.execute(sql)
|
|
85
|
+
|
|
86
|
+
# Fix(MySQL/PostgreSQL/多数驱动)
|
|
87
|
+
cursor.execute("SELECT * FROM users WHERE username = %s", (username,))
|
|
88
|
+
|
|
89
|
+
# Fix(sqlite3 常见写法)
|
|
90
|
+
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
|
|
91
|
+
```
|
|
92
|
+
### 2. IN 子句参数化
|
|
93
|
+
```python
|
|
94
|
+
ids = request.GET.getlist("ids")
|
|
95
|
+
if not ids:
|
|
96
|
+
return []
|
|
97
|
+
|
|
98
|
+
placeholders = ",".join(["%s"] * len(ids))
|
|
99
|
+
sql = f"SELECT * FROM users WHERE id IN ({placeholders})"
|
|
100
|
+
cursor.execute(sql, tuple(ids))
|
|
101
|
+
rows = cursor.fetchall()
|
|
102
|
+
```
|
|
103
|
+
### 3. 结构化片段过滤(表名/列名/排序)
|
|
104
|
+
```python
|
|
105
|
+
import re
|
|
106
|
+
|
|
107
|
+
SAFE_SQL_PATTERN = r'^[\w\s\[\]"`$.,*]+$'
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def safeFilterIdentifier(value: str) -> str:
|
|
111
|
+
if not re.fullmatch(SAFE_SQL_PATTERN, value):
|
|
112
|
+
raise ValueError("invalid identifier")
|
|
113
|
+
return value
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
sort_col = safeFilterIdentifier(request.GET.get("sort", "id DESC"))
|
|
117
|
+
sql = f"SELECT id, username FROM users ORDER BY {sort_col}"
|
|
118
|
+
cursor.execute(sql)
|
|
119
|
+
```
|
|
120
|
+
### 4. Django 原生 SQL 场景
|
|
121
|
+
```python
|
|
122
|
+
from django.db import connection
|
|
123
|
+
|
|
124
|
+
username = request.GET.get("username")
|
|
125
|
+
with connection.cursor() as cursor:
|
|
126
|
+
# Bad: f-string 拼接
|
|
127
|
+
# cursor.execute(f"SELECT * FROM auth_user WHERE username = '{username}'")
|
|
128
|
+
|
|
129
|
+
# Fix: 参数化
|
|
130
|
+
cursor.execute("SELECT * FROM auth_user WHERE username = %s", [username])
|
|
131
|
+
```
|
|
132
|
+
### 5. SQLAlchemy 场景
|
|
133
|
+
```python
|
|
134
|
+
from sqlalchemy import text
|
|
135
|
+
|
|
136
|
+
# Bad
|
|
137
|
+
# session.execute(text(f"SELECT * FROM users WHERE name = '{name}'"))
|
|
138
|
+
|
|
139
|
+
# Fix
|
|
140
|
+
session.execute(text("SELECT * FROM users WHERE name = :name"), {"name": name})
|
|
141
|
+
```
|
|
142
|
+
### 6. pandas `read_sql` 场景
|
|
143
|
+
```python
|
|
144
|
+
import pandas as pd
|
|
145
|
+
|
|
146
|
+
# Bad
|
|
147
|
+
# sql = f"SELECT * FROM users WHERE name = '{user_input}'"
|
|
148
|
+
# df = pd.read_sql(sql, conn)
|
|
149
|
+
|
|
150
|
+
# Fix
|
|
151
|
+
sql = "SELECT * FROM users WHERE name = ?"
|
|
152
|
+
df = pd.read_sql(sql, conn, params=[user_input])
|
|
153
|
+
```
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## IV. 必须使用正则过滤的场景
|
|
157
|
+
以下场景不支持预编译,必须使用正则 `^[\w\s\[\]"`$.,*]+$` 过滤:
|
|
158
|
+
|
|
159
|
+
1. 动态表名/库名:`FROM {table_name}`
|
|
160
|
+
2. 动态列名:`SELECT {columns}`
|
|
161
|
+
3. 动态排序:`ORDER BY {order_by}`
|
|
162
|
+
4. DDL/DCL:`CREATE` / `DROP` / `GRANT` / `SHOW`
|
|
163
|
+
|
|
164
|
+
代码复用提示:若文件中已定义 `SAFE_SQL_PATTERN`,直接复用,不重复定义。
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## V. 修复后检查点(强检查清单)
|
|
169
|
+
1. 参数值是否全部走参数化,是否遗留字符串拼接。
|
|
170
|
+
2. 结构化 SQL 片段是否全部走过滤。
|
|
171
|
+
3. `IN` 子句占位符数量是否与参数数量一致。
|
|
172
|
+
4. 空数组场景是否有兜底(避免 `IN ()` 语法错误)。
|
|
173
|
+
5. 是否混用了不兼容的占位符风格(`%s` / `?` / `:name`)。
|
|
174
|
+
6. 是否修复了真实 sink 所在函数/文件(不是“改错位置”)。
|
|
175
|
+
7. 改动函数签名后,调用方是否同步兼容。
|
|
176
|
+
8. 是否出现“新旧 SQL 并存”导致旧拼接逻辑覆盖新逻辑。
|
|
177
|
+
9. 是否存在变量作用域问题(分支变量未定义)。
|
|
178
|
+
10. 修复代码是否保持原业务语义(避免把 `UPDATE/DELETE` 改成 `SELECT`)。
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## VI. 高频失败反模式(修复时必须规避)
|
|
183
|
+
1. 仍使用 `%`/`format`/f-string 拼接 SQL。
|
|
184
|
+
2. `IN` 直接绑定列表到单占位符。
|
|
185
|
+
3. 修复一个分支,遗漏同函数其他分支。
|
|
186
|
+
4. 修复一个 sink,遗漏同参数的其他 sink。
|
|
187
|
+
5. 调用不存在的 DB API 或错误假设驱动能力。
|
|
188
|
+
6. 修复后仍保留旧的拼接 SQL。
|
|
189
|
+
7. 只加引号不做参数化/过滤。
|
|
190
|
+
8. 先使用污点变量,后再“补过滤”(数据流已放行)。
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## VII. 最小修复策略(执行建议)
|
|
195
|
+
1. 先定位真实数据流 sink,再选修复方式。
|
|
196
|
+
2. 值参数优先参数化;结构化片段用正则过滤。
|
|
197
|
+
3. 使用 `safeFilter/safeValidate` + 临时变量承接。
|
|
198
|
+
4. 完成后按 V 节 10 条逐项自检,再提交。
|