本文目录导读:

我来详细介绍 PHP 安全测试自动化的几个主要方法和工具。
静态代码分析工具
PHPStan
# 安装
composer require --dev phpstan/phpstan
# 配置文件 phpstan.neon
parameters:
level: max
paths:
- src
checkMissingIterableValueType: true
reportUnmatchedIgnoredErrors: true
# 运行检查
vendor/bin/phpstan analyse
Psalm
# 安装 composer require --dev vimeo/psalm # 初始化配置 vendor/bin/psalm --init # 运行检查 vendor/bin/psalm --show-info=true
RIPS (静态代码分析)
# Docker 方式运行 docker run -v /path/to/php/code:/code rips/rips
动态安全扫描工具
OWASP ZAP
# Docker 运行 ZAP docker run -u zap -p 8080:8080 -i owasp/zap2docker-stable # 自动化扫描脚本
PHP 自动化扫描脚本:
<?php
class ZAPAutomation {
private $zapUrl = 'http://localhost:8080';
private $apiKey = 'your-api-key';
public function scanTarget($targetUrl) {
// 启动 Spider
$spiderResponse = $this->apiRequest('spider', 'action', 'scan', [
'url' => $targetUrl
]);
// 等待 Spider 完成
sleep(5);
// 启动主动扫描
$scanResponse = $this->apiRequest('ascan', 'action', 'scan', [
'url' => $targetUrl,
'recurse' => true
]);
return $this->getAlerts();
}
private function apiRequest($component, $type, $action, $params) {
$url = "{$this->zapUrl}/JSON/{$component}/{$type}/{$action}/";
$params['apikey'] = $this->apiKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
private function getAlerts() {
return $this->apiRequest('alert', 'view', 'alerts', []);
}
}
自动化测试框架集成
Codeception + Security Testing
// tests/_support/Helper/SecurityHelper.php
<?php
namespace Helper;
class SecurityTest extends \Codeception\Test\Unit {
protected $tester;
// XSS 测试
public function testXSSProtection() {
$payloads = [
'<script>alert("XSS")</script>',
'"><script>alert(1)</script>',
'<img src=x onerror=alert(1)>'
];
foreach ($payloads as $payload) {
$this->tester->sendPOST('/search', ['q' => $payload]);
$this->tester->dontSee($payload);
}
}
// SQL 注入测试
public function testSQLInjection() {
$payloads = [
"' OR '1'='1",
"1; DROP TABLE users--",
"admin'--"
];
foreach ($payloads as $payload) {
$this->tester->sendPOST('/login', [
'username' => $payload,
'password' => 'test'
]);
$this->tester->dontSee('SQL');
}
}
}
Composer 安全审计
# 安装本地安全审计工具 composer require --dev localheinz/composer-normalize # 检查依赖安全 composer audit # 使用 Roave Security Advisories composer require --dev roave/security-advisories:dev-latest
自动化安全检查脚本:
<?php
// security-audit.php
class SecurityAudit {
public function checkComposerSecurity() {
// 检查已知漏洞包
$packages = json_decode(
file_get_contents('composer.lock'),
true
);
$vulnerablePackages = [];
foreach ($packages['packages'] as $package) {
if ($this->isVulnerable($package['name'], $package['version'])) {
$vulnerablePackages[] = $package;
}
}
return $vulnerablePackages;
}
private function isVulnerable($name, $version) {
// 这里可以集成 FriendsOfPHP/security-advisories
// 或者使用在线 API 检查
return false;
}
}
CI/CD 集成示例
GitHub Actions 配置
# .github/workflows/security.yml
name: Security Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: composer, phpstan, psalm
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run PHPStan
run: vendor/bin/phpstan analyse --error-format=github
- name: Run Psalm
run: vendor/bin/psalm --show-info=true
- name: Run Composer Audit
run: composer audit
- name: Run Security Tests
run: |
# 启动测试服务器
php -S localhost:8000 -t public &
# 运行安全测试
vendor/bin/codecept run SecurityTest
- name: OWASP ZAP Scan
uses: zaproxy/action-api-scan@v0.1.1
with:
target: 'http://localhost:8000'
rules_file_name: '.zap/rules.tsv'
自定义安全测试框架
<?php
// CustomSecurityTester.php
class CustomSecurityTester {
private $baseUrl;
private $testResults = [];
public function __construct($baseUrl) {
$this->baseUrl = $baseUrl;
}
public function runAllTests() {
$this->testCSRF();
$this->testSessionFixation();
$this->testFileUpload();
$this->testAuthentication();
$this->testAuthorization();
return $this->generateReport();
}
private function testCSRF() {
// 测试所有 POST 端点是否有 CSRF token
$endpoints = ['/login', '/register', '/update-profile'];
foreach ($endpoints as $endpoint) {
$response = $this->makeRequest('POST', $endpoint, [
'data' => 'test'
]);
$this->testResults[] = [
'type' => 'CSRF',
'endpoint' => $endpoint,
'passed' => $response['http_code'] === 403
];
}
}
private function testSessionFixation() {
// 测试登录后 session ID 是否改变
$sessionBefore = $this->getSessionId();
$this->login('test', 'password');
$sessionAfter = $this->getSessionId();
$this->testResults[] = [
'type' => 'Session Fixation',
'endpoint' => '/login',
'passed' => $sessionBefore !== $sessionAfter
];
}
private function testFileUpload() {
// 测试文件上传漏洞
$testFiles = [
'shell.php' => '<?php system($_GET["cmd"]); ?>',
'shell.php5' => '<?php phpinfo(); ?>',
'test.html' => '<script>alert("XSS")</script>'
];
foreach ($testFiles as $filename => $content) {
$response = $this->uploadFile('/upload', $filename, $content);
$this->testResults[] = [
'type' => 'File Upload',
'filename' => $filename,
'passed' => $response['http_code'] === 400
];
}
}
private function generateReport() {
$html = "<h1>Security Test Report</h1>";
$html .= "<table border='1'>";
$html .= "<tr><th>Type</th><th>Endpoint/File</th><th>Status</th></tr>";
$failed = 0;
$passed = 0;
foreach ($this->testResults as $result) {
$status = $result['passed'] ? 'PASS' : 'FAIL';
$color = $result['passed'] ? 'green' : 'red';
if ($result['passed']) {
$passed++;
} else {
$failed++;
}
$html .= "<tr style='color: {$color}'>";
$html .= "<td>{$result['type']}</td>";
$html .= "<td>{$result['endpoint']}</td>";
$html .= "<td>{$status}</td>";
$html .= "</tr>";
}
$html .= "</table>";
$html .= "<p>Total: " . ($passed + $failed) . " | ";
$html .= "Passed: {$passed} | Failed: {$failed}</p>";
file_put_contents('security-report.html', $html);
return [
'passed' => $passed,
'failed' => $failed,
'report_file' => 'security-report.html'
];
}
}
// 使用示例
$tester = new CustomSecurityTester('http://localhost:8000');
$results = $tester->runAllTests();
print_r($results);
定期自动化扫描
#!/bin/bash # security-cron.sh # 每周日晚上执行安全扫描 # 0 2 * * 0 /path/to/security-cron.sh echo "Starting Security Scan: $(date)" # 运行 PHPStan cd /path/to/project vendor/bin/phpstan analyse --level=max # 运行 Composer 审计 composer audit # 运行安全测试 vendor/bin/codecept run SecurityTest # 发送报告 php send-security-report.php echo "Security Scan Complete: $(date)"
最佳实践建议
- 多层次测试:结合静态分析和动态扫描
- CI/CD 集成:在每次提交时自动运行基础安全检查
- 定期深度扫描:每周执行全面安全审计
- 依赖管理:定期更新依赖并检查漏洞
- 报告生成:自动生成并发送安全报告
- 优先级排序:根据风险等级分类安全问题
这些工具和脚本组合使用可以实现 PHP 安全测试的自动化,帮助你在开发过程中及时发现和修复安全漏洞。