소스 정보
- 저장소
- ZeroZ-lab/unified-skills
- 최근 소스 활동
- 2026년 5월 16일 01:54
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 16
- 포크
- 1
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/ZeroZ-lab/unified-skills --skill verify-quality-security명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | verify-quality-security |
| description | 安全加固——假设每个外部输入是敌意的。当涉及用户输入、认证、数据存储、上线前审查,或提到"XSS""SQL注入""CSRF""OWASP" |
/review 和 /ship 前/review| 级别 | 规则 | 示例 |
|---|---|---|
| Always Do | 提交前验证输入、参数化查询、哈希密码、HTTPS only cookies | 输入 sanitization、bcrypt、helmet |
| Ask First | 泄露用户数据、改权限模型、引入认证依赖、加密算法选择 | 新 OAuth provider、加密库选型 |
| Never Do | 提交密钥、信任客户端验证、eval() 用户输入、innerHTML 用户数据、暴露堆栈给用户 | .env 在仓库、dangerouslySetInnerHTML |
// Bad: SQL 拼接
const task = await db.query(`SELECT * FROM tasks WHERE id = '${req.params.id}'`);
// Good: 参数化查询
const task = await db.tasks.findById(req.params.id);
// 命令行参数必须通过 exec/spawn 的参数数组,不拼接字符串
// Bad: 直接插入用户内容
<div>{user.bio}</div> // 如果 bio 包含 <script>...
// Good: 框架自动转义 + DOMPurify for rich text
<div>{user.bio}</div> // React 默认转义
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(richBio) }} />
// Bad: 错误暴露内部信息
catch (err) {
res.status(500).json({ error: err.message, stack: err.stack });
}
// Good: 用户可见错误不含内部信息
catch (err) {
logger.error('Task creation failed', { taskId, error: err.message });
res.status(500).json({ error: { code: 'INTERNAL_ERROR', message: '处理请求时发生错误' } });
}
// Bad: 任何登录用户都能删任何任务
app.delete('/tasks/:id', auth, async (req, res) => {
await db.tasks.delete(req.params.id);
});
// Good: 验证所有权
app.delete('/tasks/:id', auth, async (req, res) => {
const task = await db.tasks.findById(req.params.id);
if (!task) return res.status(404).end();
if (task.ownerId !== req.user.id) return res.status(403).end();
await db.tasks.delete(req.params.id);
});
// 必须: helmet、CORS 白名单、HTTPS 重定向、安全 cookies
app.use(helmet());
app.use(cors({ origin: ALLOWED_ORIGINS }));
app.use(session({ cookie: { secure: true, httpOnly: true, sameSite: 'strict' } }));
npm audit # 检查已知 CVE
npm audit fix # 自动修复兼容补丁
分类:
import { z } from 'zod';
const CreateTaskSchema = z.object({
title: z.string().min(1).max(200),
description: z.string().max(5000).optional(),
priority: z.enum(['low', 'medium', 'high']),
assigneeId: z.string().uuid().optional(),
});
规则: 所有外部输入在边界(API handler)验证。验证完之后内部信任。
项目结构:
├── .env.example # 模板(可提交)
├── .env # 真实密钥(在 .gitignore,绝不提交)
└── src/config.ts # 从环境变量读取
.gitignore 必须包含:
.env
.env.local
*.pem
*.key
credentials.json
检查是否误提交:
git log --all --full-history -- '*.env' '*.pem' 'credentials.*'
A01 注入:SQL 全部参数化 ✓ → A02 XSS:框架自动转义 + DOMPurify ✓ → A04 访问控制:每个写端点验证所有权 ✓ → A06 依赖:npm audit 无 high/critical ✓ → 输入验证:所有外部输入 Zod 校验 ✓。每项有通过/未通过判定。
"这只是内部工具,用户输入在前端验证过了" — 后端没有输入验证,一行 curl 即可绕过前端。SQL 拼接、未参数化查询、无权限检查。内网被攻破后横向移动无阻碍。
安全审查结论(合并入 04-review.md 的 Security 轴区块):
## Security 审查
### OWASP Top 10 检查
| 类目 | 状态 | 发现 |
|------|------|------|
| A01 注入 | PASS / FAIL | 具体发现描述 |
| A02 XSS | PASS / FAIL | ... |
| A03 敏感数据暴露 | PASS / FAIL | ... |
| A04 访问控制缺失 | PASS / FAIL | ... |
| A05 安全配置错误 | PASS / FAIL | ... |
| A06 依赖漏洞 | PASS / FAIL | npm audit 结果摘要 |
### 输入验证覆盖
- 已验证的输入端: <列出>
- 未验证的输入端: <列出> (如有则为 Blocking)
### 密钥管理
- 密钥存储方式: 环境变量 / 配置文件 / 硬编码 (如有硬编码则为 Blocking)
- 误提交检查: git log 结果 (如有误提交则为 Blocking)
### 结论
- 审查结果: PASS / FAIL
- Blocking 问题: <列出> (如有)
- 建议: <列出>
输出或记录必须包含:
| 说辞 | 现实 | 后果 |
|---|---|---|
| "只在内部用,不对外开放" | 内网不是信任边界。Dependency confusion、内网横向移动——内部应用仍需要安全加固。 | 内网被攻破后横向移动无阻碍,一台内网机器沦陷 = 整个内网沦陷。Target 数据泄露就是从空调供应商内网渗透的。 |
| "npm audit 报的都是低风险" | 低风险可能组合成高风险。至少读一遍 audit 报告。 | 低风险 CVE 组合利用的攻击链已经发生多次(Log4j 就是"低风险"日志库),忽略 audit = 赌博。 |
| "用户输入在前端验证过了" | 前端验证是 UX 优化,不是安全。攻击者发 curl 直接绕过。 | 一行 curl -X POST 即可绕过所有前端验证。未后端验证的输入 = SQL 注入 / XSS 的直接入口。 |
| "这是个简单的内部工具" | 简单工具暴露一个未验证输入就被用作内网跳板。 | 内部工具被钓鱼或供应链攻击攻破后成为内网跳板,损失范围从 1 个工具扩大到整个基础设施。 |
| "以后再加强安全" | 安全债和技术债不同——安全债可能导致数据泄露。不能之后补。 | 数据泄露赔偿 + 声誉损失 + 用户流失。安全事件后补救的成本是预防成本的 10-50x(IBM 安全报告)。 |
违反字面规则就是违反精神。 没有灰色地带。
| 失败场景 | 处理方式 |
|---|---|
| 发现 SQL/命令注入(OWASP A01) | Blocking — 立即退回 build 修复,修复后重新提交安全审查,不能上线 |
| 发现 XSS / innerHTML 用户数据(OWASP A02) | Blocking — 立即退回 build 修复,必须使用参数化或 DOMPurify |
| 密钥或令牌硬编码/误提交 | Blocking — 立即移除密钥,轮换泄露密钥值,加入 .gitignore,重新提交 |
| 访问控制缺失(OWASP A04) | Blocking — 添加所有权验证或权限检查,修复后重新审查 |
| npm audit 有 Critical/High CVE | Blocking — 修复或替换依赖后才可上线,Low 可排期但不忽略 |
| 未验证输入端存在 | Blocking — 所有外部输入必须在边界验证,遗漏 = 潜在注入入口 |
Authorization: Bearer <token> 在没有 HTTPS 的连接上< 或 > 字符串比较做权限检查(可绕过)innerHTML、dangerouslySetInnerHTML、eval() 含用户数据npm audit(或同等)无 critical/high