security-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSecurity Testing
安全测试
Overview
概述
Security testing identifies vulnerabilities, weaknesses, and threats in applications to ensure data protection, prevent unauthorized access, and maintain system integrity. It combines automated scanning (SAST, DAST) with manual penetration testing and code review.
安全测试用于识别应用程序中的漏洞、弱点和威胁,以确保数据保护、防止未授权访问并维护系统完整性。它结合了自动化扫描(SAST、DAST)与手动渗透测试和代码审查。
When to Use
适用场景
- Testing for OWASP Top 10 vulnerabilities
- Scanning dependencies for known vulnerabilities
- Testing authentication and authorization
- Validating input sanitization
- Testing API security
- Checking for sensitive data exposure
- Validating security headers
- Testing session management
- 测试OWASP Top 10漏洞
- 扫描依赖项中的已知漏洞
- 测试身份验证与授权机制
- 验证输入清理逻辑
- 测试API安全性
- 检查敏感数据暴露情况
- 验证安全头配置
- 测试会话管理
Security Testing Types
安全测试类型
- SAST: Static Application Security Testing (code analysis)
- DAST: Dynamic Application Security Testing (runtime)
- IAST: Interactive Application Security Testing
- SCA: Software Composition Analysis (dependencies)
- Penetration Testing: Manual security testing
- Fuzz Testing: Invalid/random input testing
- SAST:静态应用程序安全测试(代码分析)
- DAST:动态应用程序安全测试(运行时)
- IAST:交互式应用程序安全测试
- SCA:软件成分分析(依赖项检测)
- Penetration Testing:手动渗透测试
- Fuzz Testing:无效/随机输入测试
Instructions
操作指南
1. OWASP ZAP (DAST)
1. OWASP ZAP (DAST)
python
undefinedpython
undefinedsecurity_scan.py
security_scan.py
from zapv2 import ZAPv2
import time
class SecurityScanner:
def init(self, target_url, api_key=None):
self.zap = ZAPv2(apikey=api_key, proxies={
'http': 'http://localhost:8080',
'https': 'http://localhost:8080'
})
self.target = target_url
def scan(self):
"""Run full security scan."""
print(f"Scanning {self.target}...")
# Spider the application
print("Spidering...")
scan_id = self.zap.spider.scan(self.target)
while int(self.zap.spider.status(scan_id)) < 100:
time.sleep(2)
print(f"Spider progress: {self.zap.spider.status(scan_id)}%")
# Active scan
print("Running active scan...")
scan_id = self.zap.ascan.scan(self.target)
while int(self.zap.ascan.status(scan_id)) < 100:
time.sleep(5)
print(f"Scan progress: {self.zap.ascan.status(scan_id)}%")
return self.get_results()
def get_results(self):
"""Get scan results."""
alerts = self.zap.core.alerts(baseurl=self.target)
# Group by risk level
results = {
'high': [],
'medium': [],
'low': [],
'informational': []
}
for alert in alerts:
risk = alert['risk'].lower()
results[risk].append({
'name': alert['alert'],
'description': alert['description'],
'solution': alert['solution'],
'url': alert['url'],
'param': alert.get('param', ''),
'evidence': alert.get('evidence', '')
})
return results
def report(self, results):
"""Generate security report."""
print("\n" + "="*60)
print("SECURITY SCAN RESULTS")
print("="*60)
for risk_level in ['high', 'medium', 'low', 'informational']:
issues = results[risk_level]
if issues:
print(f"\n{risk_level.upper()} Risk Issues: {len(issues)}")
for issue in issues[:5]: # Show first 5
print(f" - {issue['name']}")
print(f" URL: {issue['url']}")
if issue['param']:
print(f" Parameter: {issue['param']}")
# Fail if high risk found
if results['high']:
raise Exception(f"Found {len(results['high'])} HIGH risk vulnerabilities!")from zapv2 import ZAPv2
import time
class SecurityScanner:
def init(self, target_url, api_key=None):
self.zap = ZAPv2(apikey=api_key, proxies={
'http': 'http://localhost:8080',
'https': 'http://localhost:8080'
})
self.target = target_url
def scan(self):
"""Run full security scan."""
print(f"Scanning {self.target}...")
# Spider the application
print("Spidering...")
scan_id = self.zap.spider.scan(self.target)
while int(self.zap.spider.status(scan_id)) < 100:
time.sleep(2)
print(f"Spider progress: {self.zap.spider.status(scan_id)}%")
# Active scan
print("Running active scan...")
scan_id = self.zap.ascan.scan(self.target)
while int(self.zap.ascan.status(scan_id)) < 100:
time.sleep(5)
print(f"Scan progress: {self.zap.ascan.status(scan_id)}%")
return self.get_results()
def get_results(self):
"""Get scan results."""
alerts = self.zap.core.alerts(baseurl=self.target)
# Group by risk level
results = {
'high': [],
'medium': [],
'low': [],
'informational': []
}
for alert in alerts:
risk = alert['risk'].lower()
results[risk].append({
'name': alert['alert'],
'description': alert['description'],
'solution': alert['solution'],
'url': alert['url'],
'param': alert.get('param', ''),
'evidence': alert.get('evidence', '')
})
return results
def report(self, results):
"""Generate security report."""
print("\n" + "="*60)
print("SECURITY SCAN RESULTS")
print("="*60)
for risk_level in ['high', 'medium', 'low', 'informational']:
issues = results[risk_level]
if issues:
print(f"\n{risk_level.upper()} Risk Issues: {len(issues)}")
for issue in issues[:5]: # Show first 5
print(f" - {issue['name']}")
print(f" URL: {issue['url']}")
if issue['param']:
print(f" Parameter: {issue['param']}")
# Fail if high risk found
if results['high']:
raise Exception(f"Found {len(results['high'])} HIGH risk vulnerabilities!")Usage
Usage
scanner = SecurityScanner('http://localhost:3000')
results = scanner.scan()
scanner.report(results)
undefinedscanner = SecurityScanner('http://localhost:3000')
results = scanner.scan()
scanner.report(results)
undefined2. SQL Injection Testing
2. SQL注入测试
typescript
// tests/security/sql-injection.test.ts
import { test, expect } from '@playwright/test';
import request from 'supertest';
import { app } from '../../src/app';
test.describe('SQL Injection Protection', () => {
const sqlInjectionPayloads = [
"' OR '1'='1",
"'; DROP TABLE users; --",
"' UNION SELECT * FROM users --",
"admin'--",
"' OR 1=1--",
"1' AND '1'='1",
];
test('login should prevent SQL injection', async () => {
for (const payload of sqlInjectionPayloads) {
const response = await request(app)
.post('/api/auth/login')
.send({
email: payload,
password: payload,
});
// Should return 400/401, not 500 (SQL error)
expect([400, 401]).toContain(response.status);
expect(response.body).not.toMatch(/SQL|syntax|error/i);
}
});
test('search should sanitize input', async () => {
for (const payload of sqlInjectionPayloads) {
const response = await request(app)
.get('/api/products/search')
.query({ q: payload });
// Should not cause SQL error
expect(response.status).toBeLessThan(500);
expect(response.body).not.toMatch(/SQL|syntax/i);
}
});
test('numeric parameters should be validated', async () => {
const response = await request(app)
.get('/api/users/abc') // Non-numeric ID
.expect(400);
expect(response.body.error).toBeTruthy();
});
});typescript
// tests/security/sql-injection.test.ts
import { test, expect } from '@playwright/test';
import request from 'supertest';
import { app } from '../../src/app';
test.describe('SQL Injection Protection', () => {
const sqlInjectionPayloads = [
"' OR '1'='1",
"'; DROP TABLE users; --",
"' UNION SELECT * FROM users --",
"admin'--",
"' OR 1=1--",
"1' AND '1'='1",
];
test('login should prevent SQL injection', async () => {
for (const payload of sqlInjectionPayloads) {
const response = await request(app)
.post('/api/auth/login')
.send({
email: payload,
password: payload,
});
// Should return 400/401, not 500 (SQL error)
expect([400, 401]).toContain(response.status);
expect(response.body).not.toMatch(/SQL|syntax|error/i);
}
});
test('search should sanitize input', async () => {
for (const payload of sqlInjectionPayloads) {
const response = await request(app)
.get('/api/products/search')
.query({ q: payload });
// Should not cause SQL error
expect(response.status).toBeLessThan(500);
expect(response.body).not.toMatch(/SQL|syntax/i);
}
});
test('numeric parameters should be validated', async () => {
const response = await request(app)
.get('/api/users/abc') // Non-numeric ID
.expect(400);
expect(response.body.error).toBeTruthy();
});
});3. XSS Testing
3. XSS测试
javascript
// tests/security/xss.test.js
describe('XSS Protection', () => {
const xssPayloads = [
'<script>alert("XSS")</script>',
'<img src=x onerror=alert("XSS")>',
'<svg onload=alert("XSS")>',
'javascript:alert("XSS")',
'<iframe src="javascript:alert(\'XSS\')">',
'<body onload=alert("XSS")>',
];
test('user input should be escaped', async () => {
const { page } = await browser.newPage();
for (const payload of xssPayloads) {
await page.goto('/');
// Submit comment with XSS payload
await page.fill('[name="comment"]', payload);
await page.click('[type="submit"]');
// Wait for comment to appear
await page.waitForSelector('.comment');
// Check that script was not executed
const dialogAppeared = await page.evaluate(() => {
return window.xssDetected || false;
});
expect(dialogAppeared).toBe(false);
// Check HTML is escaped
const commentHTML = await page.$eval('.comment', el => el.innerHTML);
expect(commentHTML).not.toContain('<script>');
expect(commentHTML).toContain('<script>');
}
});
test('URLs should be validated', async () => {
const response = await request(app)
.post('/api/links')
.send({ url: 'javascript:alert("XSS")' })
.expect(400);
expect(response.body.error).toMatch(/invalid url/i);
});
});javascript
// tests/security/xss.test.js
describe('XSS Protection', () => {
const xssPayloads = [
'<script>alert("XSS")</script>',
'<img src=x onerror=alert("XSS")>',
'<svg onload=alert("XSS")>',
'javascript:alert("XSS")',
'<iframe src="javascript:alert(\'XSS\')">',
'<body onload=alert("XSS")>',
];
test('user input should be escaped', async () => {
const { page } = await browser.newPage();
for (const payload of xssPayloads) {
await page.goto('/');
// Submit comment with XSS payload
await page.fill('[name="comment"]', payload);
await page.click('[type="submit"]');
// Wait for comment to appear
await page.waitForSelector('.comment');
// Check that script was not executed
const dialogAppeared = await page.evaluate(() => {
return window.xssDetected || false;
});
expect(dialogAppeared).toBe(false);
// Check HTML is escaped
const commentHTML = await page.$eval('.comment', el => el.innerHTML);
expect(commentHTML).not.toContain('<script>');
expect(commentHTML).toContain('<script>');
}
});
test('URLs should be validated', async () => {
const response = await request(app)
.post('/api/links')
.send({ url: 'javascript:alert("XSS")' })
.expect(400);
expect(response.body.error).toMatch(/invalid url/i);
});
});4. Authentication & Authorization Testing
4. 身份验证与授权测试
typescript
// tests/security/auth.test.ts
describe('Authentication Security', () => {
test('should reject weak passwords', async () => {
const weakPasswords = [
'password',
'12345678',
'qwerty',
'abc123',
'password123',
];
for (const password of weakPasswords) {
const response = await request(app)
.post('/api/users')
.send({
email: 'test@example.com',
password,
});
expect(response.status).toBe(400);
expect(response.body.error).toMatch(/password.*weak|password.*requirements/i);
}
});
test('should rate limit login attempts', async () => {
const credentials = {
email: 'test@example.com',
password: 'wrongpassword',
};
// Try 10 failed logins
for (let i = 0; i < 10; i++) {
await request(app)
.post('/api/auth/login')
.send(credentials);
}
// 11th attempt should be rate limited
const response = await request(app)
.post('/api/auth/login')
.send(credentials);
expect(response.status).toBe(429);
expect(response.body.error).toMatch(/too many attempts|rate limit/i);
});
test('should prevent unauthorized access', async () => {
const response = await request(app)
.get('/api/admin/users')
.expect(401);
});
test('should prevent privilege escalation', async () => {
const regularUserToken = await getRegularUserToken();
const response = await request(app)
.delete('/api/users/999') // Try to delete another user
.set('Authorization', `Bearer ${regularUserToken}`)
.expect(403);
});
test('JWT tokens should expire', async () => {
// Create expired token
const expiredToken = jwt.sign(
{ userId: '123' },
JWT_SECRET,
{ expiresIn: '-1s' }
);
const response = await request(app)
.get('/api/protected')
.set('Authorization', `Bearer ${expiredToken}`)
.expect(401);
});
});typescript
// tests/security/auth.test.ts
describe('Authentication Security', () => {
test('should reject weak passwords', async () => {
const weakPasswords = [
'password',
'12345678',
'qwerty',
'abc123',
'password123',
];
for (const password of weakPasswords) {
const response = await request(app)
.post('/api/users')
.send({
email: 'test@example.com',
password,
});
expect(response.status).toBe(400);
expect(response.body.error).toMatch(/password.*weak|password.*requirements/i);
}
});
test('should rate limit login attempts', async () => {
const credentials = {
email: 'test@example.com',
password: 'wrongpassword',
};
// Try 10 failed logins
for (let i = 0; i < 10; i++) {
await request(app)
.post('/api/auth/login')
.send(credentials);
}
// 11th attempt should be rate limited
const response = await request(app)
.post('/api/auth/login')
.send(credentials);
expect(response.status).toBe(429);
expect(response.body.error).toMatch(/too many attempts|rate limit/i);
});
test('should prevent unauthorized access', async () => {
const response = await request(app)
.get('/api/admin/users')
.expect(401);
});
test('should prevent privilege escalation', async () => {
const regularUserToken = await getRegularUserToken();
const response = await request(app)
.delete('/api/users/999') // Try to delete another user
.set('Authorization', `Bearer ${regularUserToken}`)
.expect(403);
});
test('JWT tokens should expire', async () => {
// Create expired token
const expiredToken = jwt.sign(
{ userId: '123' },
JWT_SECRET,
{ expiresIn: '-1s' }
);
const response = await request(app)
.get('/api/protected')
.set('Authorization', `Bearer ${expiredToken}`)
.expect(401);
});
});5. CSRF Protection Testing
5. CSRF防护测试
python
undefinedpython
undefinedtests/security/test_csrf.py
tests/security/test_csrf.py
import pytest
from flask import session
class TestCSRFProtection:
def test_post_without_csrf_token_rejected(self, client):
"""POST requests without CSRF token should be rejected."""
response = client.post('/api/users', json={
'email': 'test@example.com',
'name': 'Test'
})
assert response.status_code == 403
assert 'CSRF' in response.json['error']
def test_post_with_invalid_csrf_token_rejected(self, client):
"""POST with invalid CSRF token should be rejected."""
response = client.post('/api/users',
json={'email': 'test@example.com'},
headers={'X-CSRF-Token': 'invalid-token'}
)
assert response.status_code == 403
def test_post_with_valid_csrf_token_accepted(self, client):
"""POST with valid CSRF token should be accepted."""
# Get CSRF token
response = client.get('/api/csrf-token')
csrf_token = response.json['csrfToken']
# Use token in POST
response = client.post('/api/users',
json={'email': 'test@example.com', 'name': 'Test'},
headers={'X-CSRF-Token': csrf_token}
)
assert response.status_code == 201undefinedimport pytest
from flask import session
class TestCSRFProtection:
def test_post_without_csrf_token_rejected(self, client):
"""POST requests without CSRF token should be rejected."""
response = client.post('/api/users', json={
'email': 'test@example.com',
'name': 'Test'
})
assert response.status_code == 403
assert 'CSRF' in response.json['error']
def test_post_with_invalid_csrf_token_rejected(self, client):
"""POST with invalid CSRF token should be rejected."""
response = client.post('/api/users',
json={'email': 'test@example.com'},
headers={'X-CSRF-Token': 'invalid-token'}
)
assert response.status_code == 403
def test_post_with_valid_csrf_token_accepted(self, client):
"""POST with valid CSRF token should be accepted."""
# Get CSRF token
response = client.get('/api/csrf-token')
csrf_token = response.json['csrfToken']
# Use token in POST
response = client.post('/api/users',
json={'email': 'test@example.com', 'name': 'Test'},
headers={'X-CSRF-Token': csrf_token}
)
assert response.status_code == 201undefined6. Dependency Vulnerability Scanning
6. 依赖项漏洞扫描
bash
undefinedbash
undefinedRun npm audit
Run npm audit
npm audit
npm audit
Fix vulnerabilities
Fix vulnerabilities
npm audit fix
npm audit fix
For Python - Safety
For Python - Safety
pip install safety
safety check
pip install safety
safety check
For Java - OWASP Dependency Check
For Java - OWASP Dependency Check
mvn org.owasp:dependency-check-maven:check
```yamlmvn org.owasp:dependency-check-maven:check
```yaml.github/workflows/security.yml
.github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
dependency-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run npm audit
run: npm audit --audit-level=high
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}sast-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/owasp-top-tendast-scan:
runs-on: ubuntu-latest
steps:
- name: ZAP Scan
uses: zaproxy/action-baseline@v0.7.0
with:
target: 'http://localhost:3000'
undefinedname: Security Scan
on: [push, pull_request]
jobs:
dependency-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run npm audit
run: npm audit --audit-level=high
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}sast-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/owasp-top-tendast-scan:
runs-on: ubuntu-latest
steps:
- name: ZAP Scan
uses: zaproxy/action-baseline@v0.7.0
with:
target: 'http://localhost:3000'
undefined7. Security Headers Testing
7. 安全头测试
typescript
// tests/security/headers.test.ts
test.describe('Security Headers', () => {
test('should have required security headers', async () => {
const response = await request(app).get('/');
expect(response.headers).toMatchObject({
'x-frame-options': 'DENY',
'x-content-type-options': 'nosniff',
'x-xss-protection': '1; mode=block',
'strict-transport-security': expect.stringMatching(/max-age=/),
'content-security-policy': expect.any(String),
});
});
test('should not expose sensitive headers', async () => {
const response = await request(app).get('/');
expect(response.headers['x-powered-by']).toBeUndefined();
expect(response.headers['server']).not.toMatch(/express|nginx|apache/i);
});
test('CSP should prevent inline scripts', async ({ page }) => {
await page.goto('/');
const cspViolations = [];
page.on('console', msg => {
if (msg.type() === 'error' && msg.text().includes('Content Security Policy')) {
cspViolations.push(msg.text());
}
});
// Try to inject inline script
await page.evaluate(() => {
const script = document.createElement('script');
script.textContent = 'alert("test")';
document.body.appendChild(script);
});
expect(cspViolations.length).toBeGreaterThan(0);
});
});typescript
// tests/security/headers.test.ts
test.describe('Security Headers', () => {
test('should have required security headers', async () => {
const response = await request(app).get('/');
expect(response.headers).toMatchObject({
'x-frame-options': 'DENY',
'x-content-type-options': 'nosniff',
'x-xss-protection': '1; mode=block',
'strict-transport-security': expect.stringMatching(/max-age=/),
'content-security-policy': expect.any(String),
});
});
test('should not expose sensitive headers', async () => {
const response = await request(app).get('/');
expect(response.headers['x-powered-by']).toBeUndefined();
expect(response.headers['server']).not.toMatch(/express|nginx|apache/i);
});
test('CSP should prevent inline scripts', async ({ page }) => {
await page.goto('/');
const cspViolations = [];
page.on('console', msg => {
if (msg.type() === 'error' && msg.text().includes('Content Security Policy')) {
cspViolations.push(msg.text());
}
});
// Try to inject inline script
await page.evaluate(() => {
const script = document.createElement('script');
script.textContent = 'alert("test")';
document.body.appendChild(script);
});
expect(cspViolations.length).toBeGreaterThan(0);
});
});8. Secrets Detection
8. 密钥检测
bash
undefinedbash
undefinedInstall detect-secrets
Install detect-secrets
pip install detect-secrets
pip install detect-secrets
Scan repository
Scan repository
detect-secrets scan --all-files --force-use-all-plugins
detect-secrets scan --all-files --force-use-all-plugins
Check for hardcoded secrets
Check for hardcoded secrets
git secrets --scan
git secrets --scan
TruffleHog for git history
TruffleHog for git history
trufflehog git https://github.com/user/repo --only-verified
undefinedtrufflehog git https://github.com/user/repo --only-verified
undefinedOWASP Top 10 Testing
OWASP Top 10测试要点
- Broken Access Control: Test authorization, privilege escalation
- Cryptographic Failures: Check for weak encryption, exposed secrets
- Injection: SQL, NoSQL, Command injection
- Insecure Design: Architecture flaws
- Security Misconfiguration: Default configs, unnecessary features
- Vulnerable Components: Outdated dependencies
- Authentication Failures: Weak passwords, session management
- Software & Data Integrity: Unsigned packages, insecure CI/CD
- Logging Failures: Insufficient logging, sensitive data in logs
- SSRF: Server-side request forgery
- Broken Access Control(访问控制失效):测试授权机制、权限提升漏洞
- Cryptographic Failures(加密失败):检查弱加密方式、密钥暴露情况
- Injection(注入):SQL、NoSQL、命令注入测试
- Insecure Design(不安全设计):架构缺陷检测
- Security Misconfiguration(安全配置错误):默认配置、不必要功能检查
- Vulnerable Components(易受攻击的组件):过时依赖项检测
- Authentication Failures(身份验证失败):弱密码、会话管理测试
- Software & Data Integrity(软件与数据完整性失效):未签名包、不安全CI/CD检查
- Logging Failures(日志记录失效):日志不足、敏感数据日志检查
- SSRF(服务器端请求伪造):SSRF漏洞测试
Best Practices
最佳实践
✅ DO
✅ 应该做
- Run security scans in CI/CD
- Test with real attack vectors
- Scan dependencies regularly
- Use security headers
- Implement rate limiting
- Validate and sanitize all input
- Use parameterized queries
- Test authentication/authorization thoroughly
- 在CI/CD流程中运行安全扫描
- 使用真实攻击向量进行测试
- 定期扫描依赖项
- 配置安全头
- 实现速率限制
- 验证并清理所有用户输入
- 使用参数化查询
- 全面测试身份验证/授权机制
❌ DON'T
❌ 不应该做
- Store secrets in code
- Trust user input
- Expose detailed error messages
- Skip dependency updates
- Use default credentials
- Ignore security warnings
- Test only happy paths
- Commit sensitive data
- 在代码中存储密钥
- 信任用户输入
- 暴露详细错误信息
- 跳过依赖项更新
- 使用默认凭据
- 忽略安全警告
- 仅测试正常流程
- 提交敏感数据
Tools
工具
SAST
SAST
- Semgrep: Multi-language static analysis
- SonarQube: Code quality and security
- Bandit: Python security linter
- ESLint plugins: JavaScript security
- Semgrep:多语言静态分析工具
- SonarQube:代码质量与安全检测平台
- Bandit:Python安全代码检查工具
- ESLint插件:JavaScript安全检测
DAST
DAST
- OWASP ZAP: Web app security scanner
- Burp Suite: Security testing platform
- Nikto: Web server scanner
- OWASP ZAP:Web应用安全扫描器
- Burp Suite:安全测试平台
- Nikto:Web服务器扫描器
SCA
SCA
- Snyk: Dependency vulnerability scanning
- npm audit: Node.js dependencies
- OWASP Dependency-Check: Multi-language
- Safety: Python dependencies
- Snyk:依赖项漏洞扫描工具
- npm audit:Node.js依赖项检测
- OWASP Dependency-Check:多语言依赖项检测
- Safety:Python依赖项安全检查
Secrets
密钥检测
- detect-secrets: Pre-commit hook
- GitGuardian: Secrets detection
- TruffleHog: Git history scanning
- detect-secrets:提交前密钥检测钩子
- GitGuardian:密钥检测平台
- TruffleHog:Git历史密钥扫描工具
Penetration Testing Checklist
渗透测试检查清单
Input Validation
输入验证
- SQL injection attempts blocked
- XSS payloads escaped
- Command injection prevented
- Path traversal blocked
- File upload restrictions
- 阻止SQL注入尝试
- 转义XSS攻击载荷
- 防止命令注入
- 阻止路径遍历
- 限制文件上传
Authentication
身份验证
- Strong password policy
- Account lockout after failed attempts
- Session timeout implemented
- Password reset secure
- MFA available
- 实施强密码策略
- 失败尝试后锁定账户
- 实现会话超时
- 安全的密码重置流程
- 支持多因素认证(MFA)
Authorization
授权
- Role-based access control
- Privilege escalation prevented
- Direct object reference secure
- API endpoints protected
- 基于角色的访问控制
- 防止权限提升
- 安全的直接对象引用
- 保护API端点
Data Protection
数据保护
- Sensitive data encrypted
- HTTPS enforced
- Secure cookies (HttpOnly, Secure)
- No secrets in logs
- PII properly handled
- 加密敏感数据
- 强制使用HTTPS
- 安全Cookie配置(HttpOnly、Secure)
- 日志中不包含密钥
- 正确处理个人可识别信息(PII)
Examples
示例
See also: continuous-testing, api-contract-testing, code-review-analysis for comprehensive security practices.
另可参考:持续测试、API契约测试、代码审查分析以获取全面的安全实践。