performing-api-security-testing-with-postman
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerforming API Security Testing with Postman
使用Postman执行API安全测试
When to Use
使用场景
- Building repeatable API security test suites for OWASP API Security Top 10 coverage
- Creating automated security regression tests that run in CI/CD pipelines via Newman
- Testing API authentication and authorization across multiple user roles systematically
- Integrating Postman with OWASP ZAP proxy for combined manual and automated security testing
- Establishing a baseline security test collection for new API endpoints before deployment
Do not use against production APIs without authorization. Postman security testing involves sending potentially malicious payloads.
- 构建可重复的API安全测试套件,覆盖OWASP API Security Top 10漏洞
- 创建可通过Newman在CI/CD流水线中运行的自动化安全回归测试
- 系统地测试多用户角色下的API身份验证与授权机制
- 将Postman与OWASP ZAP代理集成,结合手动与自动化安全测试
- 在新API端点部署前建立基线安全测试集合
注意:未经授权请勿针对生产API执行测试。Postman安全测试会发送潜在恶意负载。
Prerequisites
前提条件
- Postman Desktop or web application with an active workspace
- Target API with OpenAPI/Swagger specification for collection import
- Test accounts for at least three roles: unauthenticated, regular user, admin
- Newman CLI installed for CI/CD integration:
npm install -g newman - OWASP ZAP configured as local proxy (localhost:8080) for Postman proxy integration
- API environment variables for base URL, tokens, and test data
- 拥有活跃工作区的Postman桌面版或网页版应用
- 带有OpenAPI/Swagger规范的目标API,用于导入集合
- 至少三个角色的测试账号:未认证用户、普通用户、管理员
- 安装用于CI/CD集成的Newman CLI:
npm install -g newman - 配置OWASP ZAP作为本地代理(localhost:8080),用于Postman代理集成
- 包含基础URL、令牌和测试数据的API环境变量
Workflow
工作流程
Step 1: Environment and Collection Setup
步骤1:环境与集合设置
Create Postman environments for multi-role testing:
json
// Environment: API Security Test - Regular User
{
"values": [
{"key": "base_url", "value": "https://target-api.example.com/api/v1"},
{"key": "auth_token", "value": ""},
{"key": "user_email", "value": "regular@test.com"},
{"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"}
]
}Pre-request script for automatic authentication:
javascript
// Collection-level pre-request script for auto-login
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);
}
});
}创建用于多角色测试的Postman环境:
json
// Environment: API Security Test - Regular User
{
"values": [
{"key": "base_url", "value": "https://target-api.example.com/api/v1"},
{"key": "auth_token", "value": ""},
{"key": "user_email", "value": "regular@test.com"},
{"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"}
]
}自动身份验证的预请求脚本:
javascript
// Collection-level pre-request script for auto-login
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);
}
});
}Step 2: BOLA (API1) Test Collection
步骤2:BOLA(API1)测试集合
javascript
// Test: Access other user's profile (BOLA)
// Request: GET {{base_url}}/users/{{other_user_id}}
// Auth: Bearer {{auth_token}}
// Test script:
pm.test("BOLA: Cannot access other user profile", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
pm.test("BOLA: No user data leaked on denial", 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");
// Flag as BOLA if full profile returned
console.error("BOLA VULNERABILITY: Full profile returned for other user");
}
});
// Test: Access other user's order
// Request: GET {{base_url}}/orders/{{other_user_order_id}}
pm.test("BOLA: Cannot access other user order", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403, 404]);
});
// Test: Modify other user's resource
// Request: PATCH {{base_url}}/users/{{other_user_id}}
// Body: {"name": "Hacked"}
pm.test("BOLA: Cannot modify other user profile", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});javascript
// Test: Access other user's profile (BOLA)
// Request: GET {{base_url}}/users/{{other_user_id}}
// Auth: Bearer {{auth_token}}
// Test script:
pm.test("BOLA: Cannot access other user profile", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
pm.test("BOLA: No user data leaked on denial", 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");
// Flag as BOLA if full profile returned
console.error("BOLA VULNERABILITY: Full profile returned for other user");
}
});
// Test: Access other user's order
// Request: GET {{base_url}}/orders/{{other_user_order_id}}
pm.test("BOLA: Cannot access other user order", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403, 404]);
});
// Test: Modify other user's resource
// Request: PATCH {{base_url}}/users/{{other_user_id}}
// Body: {"name": "Hacked"}
pm.test("BOLA: Cannot modify other user profile", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});Step 3: Authentication (API2) Test Collection
步骤3:身份验证(API2)测试集合
javascript
// Test: Token validation
// Request: GET {{base_url}}/users/me
// Auth: Bearer invalid_token_value
pm.test("Auth: Invalid token rejected", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// Test: Expired token handling
// Request: GET {{base_url}}/users/me
// Auth: Bearer {{expired_token}}
pm.test("Auth: Expired token rejected", function() {
pm.expect(pm.response.code).to.equal(401);
});
// Test: Missing authentication
// Request: GET {{base_url}}/users/me
// Auth: None
pm.test("Auth: Unauthenticated request rejected", function() {
pm.expect(pm.response.code).to.equal(401);
});
// Test: SQL injection in login
// Request: POST {{base_url}}/auth/login
// Body: {"email": "' OR 1=1--", "password": "test"}
pm.test("Auth: SQLi in login rejected", function() {
pm.expect(pm.response.code).to.not.equal(200);
pm.expect(pm.response.text()).to.not.include("token");
});
// Test: Account enumeration
// Pre-request: Send login with valid email + wrong password, then invalid email + wrong password
pm.test("Auth: No account enumeration", function() {
// Compare with stored response from valid email attempt
const validEmailResponse = pm.environment.get("valid_email_response");
const currentResponse = pm.response.text();
pm.expect(currentResponse).to.equal(validEmailResponse);
});javascript
// Test: Token validation
// Request: GET {{base_url}}/users/me
// Auth: Bearer invalid_token_value
pm.test("Auth: Invalid token rejected", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// Test: Expired token handling
// Request: GET {{base_url}}/users/me
// Auth: Bearer {{expired_token}}
pm.test("Auth: Expired token rejected", function() {
pm.expect(pm.response.code).to.equal(401);
});
// Test: Missing authentication
// Request: GET {{base_url}}/users/me
// Auth: None
pm.test("Auth: Unauthenticated request rejected", function() {
pm.expect(pm.response.code).to.equal(401);
});
// Test: SQL injection in login
// Request: POST {{base_url}}/auth/login
// Body: {"email": "' OR 1=1--", "password": "test"}
pm.test("Auth: SQLi in login rejected", function() {
pm.expect(pm.response.code).to.not.equal(200);
pm.expect(pm.response.text()).to.not.include("token");
});
// Test: Account enumeration
// Pre-request: Send login with valid email + wrong password, then invalid email + wrong password
pm.test("Auth: No account enumeration", function() {
// Compare with stored response from valid email attempt
const validEmailResponse = pm.environment.get("valid_email_response");
const currentResponse = pm.response.text();
pm.expect(currentResponse).to.equal(validEmailResponse);
});Step 4: Data Exposure (API3) and BFLA (API5) Tests
步骤4:数据泄露(API3)与BFLA(API5)测试
javascript
// Test: Excessive data exposure check
// Request: GET {{base_url}}/users/me
pm.test("Data Exposure: No sensitive fields in response", 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("Data Exposure: Security headers present", 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("Data Exposure: No server info leaked", function() {
pm.expect(pm.response.headers.has("Server")).to.be.false;
pm.expect(pm.response.headers.has("X-Powered-By")).to.be.false;
});
// Test: BFLA - Admin endpoint access
// Request: GET {{base_url}}{{admin_endpoint}}
// Auth: Bearer {{auth_token}} (regular user)
pm.test("BFLA: Regular user cannot access admin endpoint", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// Test: BFLA - Admin function execution
// Request: DELETE {{base_url}}/users/{{other_user_id}}
// Auth: Bearer {{auth_token}} (regular user)
pm.test("BFLA: Regular user cannot delete other users", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});javascript
// Test: Excessive data exposure check
// Request: GET {{base_url}}/users/me
pm.test("Data Exposure: No sensitive fields in response", 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("Data Exposure: Security headers present", 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("Data Exposure: No server info leaked", function() {
pm.expect(pm.response.headers.has("Server")).to.be.false;
pm.expect(pm.response.headers.has("X-Powered-By")).to.be.false;
});
// Test: BFLA - Admin endpoint access
// Request: GET {{base_url}}{{admin_endpoint}}
// Auth: Bearer {{auth_token}} (regular user)
pm.test("BFLA: Regular user cannot access admin endpoint", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});
// Test: BFLA - Admin function execution
// Request: DELETE {{base_url}}/users/{{other_user_id}}
// Auth: Bearer {{auth_token}} (regular user)
pm.test("BFLA: Regular user cannot delete other users", function() {
pm.expect(pm.response.code).to.be.oneOf([401, 403]);
});Step 5: Mass Assignment and Rate Limiting Tests
步骤5:批量赋值与速率限制测试
javascript
// Test: Mass assignment via profile update
// Request: PUT {{base_url}}/users/me
// Body: {"name": "Test", "role": "admin", "is_admin": true}
pm.test("Mass Assignment: Role field not accepted", 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);
}
});
// Test: Rate limiting enforcement
// This test should be run with the Collection Runner at high iteration count
pm.test("Rate Limiting: Returns 429 when limit exceeded", function() {
// This test expects to be rate-limited after many iterations
const iterationCount = pm.info.iteration;
if (iterationCount > 50) {
// After 50 iterations, we should see rate limiting
if (pm.response.code === 429) {
pm.expect(pm.response.headers.has("Retry-After")).to.be.true;
console.log("Rate limiting enforced at iteration " + iterationCount);
}
}
});
// Test: Rate limit headers present
pm.test("Rate Limiting: Rate limit headers present", 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;
});javascript
// Test: Mass assignment via profile update
// Request: PUT {{base_url}}/users/me
// Body: {"name": "Test", "role": "admin", "is_admin": true}
pm.test("Mass Assignment: Role field not accepted", 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);
}
});
// Test: Rate limiting enforcement
// This test should be run with the Collection Runner at high iteration count
pm.test("Rate Limiting: Returns 429 when limit exceeded", function() {
// This test expects to be rate-limited after many iterations
const iterationCount = pm.info.iteration;
if (iterationCount > 50) {
// After 50 iterations, we should see rate limiting
if (pm.response.code === 429) {
pm.expect(pm.response.headers.has("Retry-After")).to.be.true;
console.log("Rate limiting enforced at iteration " + iterationCount);
}
}
});
// Test: Rate limit headers present
pm.test("Rate Limiting: Rate limit headers present", 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;
});Step 6: Newman CI/CD Integration
步骤6:Newman CI/CD集成
bash
undefinedbash
undefinedRun security test collection via Newman CLI
Run security test collection via 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
--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
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
--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
Run with different user roles
Run with different user roles
for role in "regular_user" "admin_user" "unauthenticated"; do
echo "Testing with role: $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
--environment "Security-Test-${role}.postman_environment.json"
--reporters cli,junit
--reporter-junit-export "./reports/security-${role}.xml" done
**GitHub Actions Integration:**
```yamlfor role in "regular_user" "admin_user" "unauthenticated"; do
echo "Testing with role: $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
--environment "Security-Test-${role}.postman_environment.json"
--reporters cli,junit
--reporter-junit-export "./reports/security-${role}.xml" done
**GitHub Actions集成:**
```yaml.github/workflows/api-security-test.yml
.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/
--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/
undefinedname: 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/
--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/
undefinedKey Concepts
核心概念
| Term | Definition |
|---|---|
| Postman Collection | Organized group of API requests with test scripts that can be shared, version-controlled, and executed automatically |
| Newman | Command-line companion for Postman that enables running collections in CI/CD pipelines and generating test reports |
| Pre-request Script | JavaScript code that executes before a Postman request, used for dynamic authentication and test data setup |
| Test Script | JavaScript code that executes after a Postman response, used to validate security assertions against the response |
| Collection Runner | Postman feature that executes all requests in a collection sequentially with configurable iterations and delays |
| Environment Variables | Key-value pairs scoped to a Postman environment that parameterize requests for different targets, roles, and configurations |
| 术语 | 定义 |
|---|---|
| Postman Collection | 一组组织有序的API请求,附带测试脚本,可共享、版本控制并自动执行 |
| Newman | Postman的命令行工具,支持在CI/CD流水线中运行集合并生成测试报告 |
| Pre-request Script | 在Postman请求执行前运行的JavaScript代码,用于动态身份验证和测试数据设置 |
| Test Script | 在Postman响应返回后运行的JavaScript代码,用于针对响应验证安全断言 |
| Collection Runner | Postman的功能,可按顺序执行集合中的所有请求,支持配置迭代次数和延迟 |
| Environment Variables | 作用于Postman环境的键值对,用于为不同目标、角色和配置参数化请求 |
Tools & Systems
工具与系统
- Postman: API platform for building, testing, and documenting APIs with built-in scripting and collection management
- Newman: CLI runner for Postman collections supporting multiple reporters (HTML, JUnit, JSON) for CI/CD integration
- OWASP ZAP: Open-source security proxy that can be configured as Postman's proxy to scan all requests passively
- newman-reporter-htmlextra: Enhanced HTML reporter for Newman that generates detailed test reports with request/response data
- Postman Flows: Visual workflow builder for chaining complex security test sequences with conditional logic
- Postman: API平台,用于构建、测试和文档化API,内置脚本和集合管理功能
- Newman: Postman集合的CLI运行器,支持多种报告格式(HTML、JUnit、JSON),用于CI/CD集成
- OWASP ZAP: 开源安全代理,可配置为Postman的代理,被动扫描所有请求
- newman-reporter-htmlextra: Newman的增强HTML报告器,生成包含请求/响应数据的详细测试报告
- Postman Flows: 可视化工作流构建器,用于通过条件逻辑链接复杂的安全测试序列
Common Scenarios
常见场景
Scenario: API Security Regression Suite for CI/CD
场景:CI/CD中的API安全回归套件
Context: A development team releases API updates bi-weekly. They need an automated security test suite that runs on every pull request to catch authorization and authentication regressions before merge.
Approach:
- Import the OpenAPI spec into Postman to generate a base collection with all endpoints
- Create three environments: unauthenticated, regular user, admin with appropriate credentials
- Add security test scripts to each request: BOLA checks, auth validation, data exposure scanning, header security
- Create a dedicated "Security Tests" folder with injection payloads, mass assignment tests, and rate limit checks
- Export the collection and environments to the repository
- Configure Newman in GitHub Actions to run on every PR affecting API code
- Set the pipeline to fail on any security test failure, blocking the merge
Pitfalls:
- Hardcoding authentication tokens in collections instead of using pre-request scripts for dynamic token generation
- Not testing with all user roles - only testing authenticated vs unauthenticated misses role-based authorization issues
- Running security tests against production instead of staging environments
- Not updating the collection when new endpoints are added, leaving gaps in coverage
- Ignoring Newman exit codes in CI/CD, allowing failing security tests to pass silently
背景:开发团队每两周发布一次API更新。他们需要一个自动化安全测试套件,在每次拉取请求时运行,在合并前捕获授权和身份验证回归问题。
实施步骤:
- 将OpenAPI规范导入Postman,生成包含所有端点的基础集合
- 创建三个环境:未认证用户、普通用户、管理员,并配置相应凭证
- 为每个请求添加安全测试脚本:BOLA检查、身份验证验证、数据泄露扫描、头部安全检测
- 创建专门的“安全测试”文件夹,包含注入负载、批量赋值测试和速率限制检查
- 将集合和环境导出到代码仓库
- 在GitHub Actions中配置Newman,在所有影响API代码的PR上运行测试
- 设置流水线在任何安全测试失败时终止,阻止合并
常见陷阱:
- 在集合中硬编码身份验证令牌,而非使用预请求脚本动态生成令牌
- 未测试所有用户角色——仅测试已认证与未认证用户会遗漏基于角色的授权问题
- 在生产环境而非预发布环境运行安全测试
- 添加新端点时未更新集合,导致测试覆盖存在缺口
- 在CI/CD中忽略Newman退出码,允许失败的安全测试静默通过
Output Format
输出格式
undefinedundefinedAPI Security Test Report - Postman/Newman
API安全测试报告 - Postman/Newman
Collection: API Security Tests v2.3
Environment: Staging - Regular User
Date: 2024-12-15
Total Requests: 85
Total Tests: 234
Passed: 219
Failed: 15
集合: API安全测试 v2.3
环境: 预发布环境 - 普通用户
日期: 2024-12-15
总请求数: 85
总测试数: 234
通过: 219
失败: 15
Failed Tests Summary
失败测试摘要
| # | Request | Test Name | Severity |
|---|---|---|---|
| 1 | GET /users/1002 | BOLA: Cannot access other user profile | Critical |
| 2 | GET /orders/5003 | BOLA: Cannot access other user order | Critical |
| 3 | GET /admin/users | BFLA: Regular user cannot access admin endpoint | Critical |
| 4 | PUT /users/me | Mass Assignment: Role field not accepted | High |
| 5 | GET /users/me | Data Exposure: No sensitive fields in response | High |
| 6 | POST /auth/login | Auth: No account enumeration | Medium |
| ... | ... | ... | ... |
| # | 请求 | 测试名称 | 严重程度 |
|---|---|---|---|
| 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 | 身份验证: 无账号枚举漏洞 | 中 |
| ... | ... | ... | ... |
Recommendations
建议
- Fix BOLA on /users/{id} and /orders/{id} - add object-level authorization checks
- Fix BFLA on /admin/users - enforce role-based access control middleware
- Fix mass assignment on PUT /users/me - implement field allowlist
- Remove password_hash and mfa_secret from user serialization
- Standardize login error messages to prevent account enumeration
undefined- 修复/users/{id}和/orders/{id}的BOLA漏洞——添加对象级授权检查
- 修复/admin/users的BFLA漏洞——实施基于角色的访问控制中间件
- 修复PUT /users/me的批量赋值漏洞——实现字段白名单
- 从用户序列化中移除password_hash和mfa_secret字段
- 标准化登录错误信息,防止账号枚举
undefined