Builds Postman test collections for structured API security testing covering OWASP Top 10 vulnerabilities like BOLA, auth bypass, injection, with multi-role environments, automated scripts, and Newman/ZAP CI/CD integration.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cybersecurity-skills-zh:performing-api-security-testing-with-postmanThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- 构建覆盖 OWASP API 安全 Top 10 的可重复 API 安全测试套件
不适用于 未经授权对生产 API 使用。Postman 安全测试涉及发送潜在恶意载荷。
npm install -g newman为多角色测试创建 Postman 环境:
// 环境:API 安全测试 - 普通用户
{
"values": [
{"key": "base_url", "value": "https://target-api.example.com/api/v1"},
{"key": "auth_token", "value": ""},
{"key": "user_email", "value": "[email protected]"},
{"key": "user_password", "value": "TestPass123!"},
{"key": "user_id", "value": ""},
{"key": "other_user_id", "value": "1002"},
{"key": "admin_endpoint", "value": "/admin/users"},
{"key": "test_order_id", "value": ""},
{"key": "other_user_order_id", "value": "5003"}
]
}
用于自动认证的前置请求脚本:
// 集合级前置请求脚本,用于自动登录
if (!pm.environment.get("auth_token") || pm.environment.get("token_expired")) {
const loginRequest = {
url: pm.environment.get("base_url") + "/auth/login",
method: "POST",
header: {"Content-Type": "application/json"},
body: {
mode: "raw",
raw: JSON.stringify({
email: pm.environment.get("user_email"),
password: pm.environment.get("user_password")
})
}
};
pm.sendRequest(loginRequest, (err, res) => {
if (!err && res.code === 200) {
const token = res.json().access_token;
pm.environment.set("auth_token", token);
pm.environment.set("user_id", res.json().user.id);
}
});
}
// 测试:访问其他用户的个人资料(BOLA)
// 请求:GET {{base_url}}/users/{{other_user_id}}
// 认证:Bearer {{auth_token}}
// 测试脚本:
pm.test("BOLA:不能访问其他用户资料", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
pm.test("BOLA:拒绝时无用户数据泄露", function() {
if (pm.response.code === 200) {
const body = pm.response.json();
pm.expect(body).to.not.have.property("email");
pm.expect(body).to.not.have.property("phone");
pm.expect(body).to.not.have.property("address");
// 如果返回了完整资料,标记为 BOLA 漏洞
console.error("BOLA 漏洞:返回了其他用户的完整资料");
}
});
// 测试:访问其他用户的订单
// 请求:GET {{base_url}}/orders/{{other_user_order_id}}
pm.test("BOLA:不能访问其他用户订单", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403, 404]);
});
// 测试:修改其他用户的资源
// 请求:PATCH {{base_url}}/users/{{other_user_id}}
// 请求体:{"name": "Hacked"}
pm.test("BOLA:不能修改其他用户资料", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// 测试:令牌验证
// 请求:GET {{base_url}}/users/me
// 认证:Bearer invalid_token_value
pm.test("认证:无效令牌被拒绝", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// 测试:过期令牌处理
// 请求:GET {{base_url}}/users/me
// 认证:Bearer {{expired_token}}
pm.test("认证:过期令牌被拒绝", function() {
pm.expect(pm.response.code).to.equal(401);
});
// 测试:缺少认证
// 请求:GET {{base_url}}/users/me
// 认证:无
pm.test("认证:未认证请求被拒绝", function() {
pm.expect(pm.response.code).to.equal(401);
});
// 测试:登录中的 SQL 注入
// 请求:POST {{base_url}}/auth/login
// 请求体:{"email": "' OR 1=1--", "password": "test"}
pm.test("认证:登录中的 SQL 注入被拒绝", function() {
pm.expect(pm.response.code).to.not.equal(200);
pm.expect(pm.response.text()).to.not.include("token");
});
// 测试:账号枚举
// 前置:使用有效邮箱+错误密码发送,然后使用无效邮箱+错误密码发送
pm.test("认证:无账号枚举", function() {
// 与存储的有效邮箱尝试响应进行比较
const validEmailResponse = pm.environment.get("valid_email_response");
const currentResponse = pm.response.text();
pm.expect(currentResponse).to.equal(validEmailResponse);
});
// 测试:过度数据暴露检查
// 请求:GET {{base_url}}/users/me
pm.test("数据暴露:响应中无敏感字段", function() {
const sensitiveFields = [
"password", "password_hash", "passwordHash",
"ssn", "social_security", "credit_card",
"api_key", "secret_key", "mfa_secret",
"refresh_token", "session_id"
];
const responseText = pm.response.text().toLowerCase();
sensitiveFields.forEach(field => {
pm.expect(responseText).to.not.include('"' + field + '"');
});
});
pm.test("数据暴露:安全响应头存在", function() {
pm.expect(pm.response.headers.has("X-Content-Type-Options")).to.be.true;
pm.expect(pm.response.headers.has("X-Frame-Options")).to.be.true;
pm.expect(pm.response.headers.get("X-Content-Type-Options")).to.equal("nosniff");
});
pm.test("数据暴露:无服务器信息泄露", function() {
pm.expect(pm.response.headers.has("Server")).to.be.false;
pm.expect(pm.response.headers.has("X-Powered-By")).to.be.false;
});
// 测试:BFLA - 管理员端点访问
// 请求:GET {{base_url}}{{admin_endpoint}}
// 认证:Bearer {{auth_token}}(普通用户)
pm.test("BFLA:普通用户不能访问管理员端点", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// 测试:BFLA - 管理员功能执行
// 请求:DELETE {{base_url}}/users/{{other_user_id}}
// 认证:Bearer {{auth_token}}(普通用户)
pm.test("BFLA:普通用户不能删除其他用户", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// 测试:通过资料更新进行批量赋值
// 请求:PUT {{base_url}}/users/me
// 请求体:{"name": "Test", "role": "admin", "is_admin": true}
pm.test("批量赋值:角色字段不被接受", function() {
if (pm.response.code === 200) {
const user = pm.response.json();
pm.expect(user.role).to.not.equal("admin");
pm.expect(user.is_admin).to.not.equal(true);
}
});
// 测试:限速执行
// 此测试应在高迭代次数的集合运行器中运行
pm.test("限速:超过限制时返回 429", function() {
// 此测试期望在多次迭代后触发限速
const iterationCount = pm.info.iteration;
if (iterationCount > 50) {
// 50 次迭代后应看到限速
if (pm.response.code === 429) {
pm.expect(pm.response.headers.has("Retry-After")).to.be.true;
console.log("在第 " + iterationCount + " 次迭代时触发限速");
}
}
});
// 测试:限速响应头存在
pm.test("限速:限速响应头存在", function() {
const hasRateHeaders = pm.response.headers.has("X-RateLimit-Limit") ||
pm.response.headers.has("X-Rate-Limit-Limit") ||
pm.response.headers.has("RateLimit-Limit");
pm.expect(hasRateHeaders).to.be.true;
});
# 通过 Newman CLI 运行安全测试集合
newman run "API-Security-Tests.postman_collection.json" \
--environment "Security-Test-Environment.postman_environment.json" \
--reporters cli,htmlextra,junit \
--reporter-htmlextra-export ./reports/security-test-report.html \
--reporter-junit-export ./reports/security-test-results.xml \
--iteration-count 1 \
--timeout-request 10000 \
--delay-request 100 \
--bail
# 使用不同用户角色运行
for role in "regular_user" "admin_user" "unauthenticated"; do
echo "使用角色测试:$role"
newman run "API-Security-Tests.postman_collection.json" \
--environment "Security-Test-${role}.postman_environment.json" \
--reporters cli,junit \
--reporter-junit-export "./reports/security-${role}.xml"
done
GitHub Actions 集成:
# .github/workflows/api-security-test.yml
name: API Security Tests
on:
pull_request:
paths: ['src/api/**', 'openapi.yaml']
jobs:
security-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install -g newman newman-reporter-htmlextra
- name: Run API Security Tests
run: |
newman run tests/postman/api-security.json \
--environment tests/postman/env-staging.json \
--reporters cli,htmlextra,junit \
--reporter-htmlextra-export reports/security.html \
--reporter-junit-export reports/security.xml
- uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: reports/
| 术语 | 定义 |
|---|---|
| Postman 集合(Postman Collection) | 包含测试脚本的有组织 API 请求组,可共享、版本控制和自动执行 |
| Newman | Postman 的命令行伴侣工具,可在 CI/CD 流水线中运行集合并生成测试报告 |
| 前置请求脚本(Pre-request Script) | 在 Postman 请求前执行的 JavaScript 代码,用于动态认证和测试数据设置 |
| 测试脚本(Test Script) | 在 Postman 响应后执行的 JavaScript 代码,用于针对响应验证安全断言 |
| 集合运行器(Collection Runner) | Postman 功能,按顺序执行集合中所有请求,可配置迭代次数和延迟 |
| 环境变量(Environment Variables) | 限定在 Postman 环境范围内的键值对,用于针对不同目标、角色和配置参数化请求 |
场景背景:一个开发团队每两周发布 API 更新。他们需要一个自动化安全测试套件,在每次拉取请求时运行,以在合并前发现授权和认证回归问题。
方法:
常见陷阱:
## API 安全测试报告 - Postman/Newman
**集合**:API 安全测试 v2.3
**环境**:预发布 - 普通用户
**日期**:2024-12-15
**总请求数**:85
**总测试数**:234
**通过**:219
**失败**:15
### 失败测试摘要
| # | 请求 | 测试名称 | 严重性 |
|---|---------|-----------|----------|
| 1 | GET /users/1002 | BOLA:不能访问其他用户资料 | 严重 |
| 2 | GET /orders/5003 | BOLA:不能访问其他用户订单 | 严重 |
| 3 | GET /admin/users | BFLA:普通用户不能访问管理员端点 | 严重 |
| 4 | PUT /users/me | 批量赋值:角色字段不被接受 | 高 |
| 5 | GET /users/me | 数据暴露:响应中无敏感字段 | 高 |
| 6 | POST /auth/login | 认证:无账号枚举 | 中 |
| ... | ... | ... | ... |
### 建议
1. 修复 /users/{id} 和 /orders/{id} 的 BOLA——添加对象级授权检查
2. 修复 /admin/users 的 BFLA——执行基于角色的访问控制中间件
3. 修复 PUT /users/me 的批量赋值——实现字段允许列表
4. 从用户序列化中删除 password_hash 和 mfa_secret
5. 标准化登录错误消息以防止账号枚举
npx claudepluginhub killvxk/cybersecurity-skills-zhPerforms API security testing with Postman targeting OWASP API Top 10 vulnerabilities including auth bypass, injection, and data exposure. Builds multi-role environments, test scripts, and integrates with ZAP/Newman for CI/CD.
Builds Postman collections for OWASP API Security Top 10 testing with automated scripts, multiple user roles, and Newman CI/CD integration.
Builds Postman collections for OWASP API Security Top 10 testing with automated scripts, multiple user roles, and Newman CI/CD integration.