本文目录导读:

在 PHP 中进行 SAST(静态应用安全测试),可以通过以下方式和工具实现:
主流 PHP SAST 工具
商业工具
- SonarQube - 最流行的开源的代码质量平台,支持 PHP
- Checkmarx - 企业级 SAST 工具
- Fortify SCA - 商业安全扫描工具
- Veracode - 云安全平台
开源工具
# RIPS - 最早的 PHP 安全扫描器 # PHPStan - 静态分析工具 # Psalm - 静态类型检查器 # PHP_CodeSniffer - 编码标准检查 # 专门的 PHP 安全工具: # - Progpilot # - Wapiti # - Phan
具体实施方法
使用 PHPStan
# 安装 composer require --dev phpstan/phpstan # 配置 phpstan.neon
parameters:
level: 8
paths:
- src
reportUnmatchedIgnoredErrors: false
checkMissingIterableValueType: true
使用 Psalm
# 安装 composer require --dev vimeo/psalm # 初始化 vendor/bin/psalm --init # 运行扫描 vendor/bin/psalm --alter --issues=Security
使用 SonarQube
# Docker 部署 docker run -d --name sonarqube -p 9000:9000 sonarqube # 安装 PHP 分析器 sonar-scanner -Dsonar.projectKey=your-project \ -Dsonar.sources=src \ -Dsonar.host.url=http://localhost:9000 \ -Dsonar.login=your-token
自定义 PHP SAST 实现
基础扫描脚本
<?php
class PHPCodeScanner {
private $dangerousFunctions = [
'eval', 'system', 'exec', 'shell_exec', 'passthru',
'popen', 'proc_open', 'assert', 'unserialize',
'include', 'require', 'file_get_contents', 'fopen'
];
private $vulnerabilities = [];
public function scanFile($filePath) {
$content = file_get_contents($filePath);
$lines = explode("\n", $content);
foreach ($lines as $lineNum => $line) {
$this->checkDangerousFunctions($line, $lineNum + 1);
$this->checkSQLInjection($line, $lineNum + 1);
$this->checkXSS($line, $lineNum + 1);
}
return $this->vulnerabilities;
}
private function checkDangerousFunctions($line, $lineNum) {
foreach ($this->dangerousFunctions as $func) {
if (preg_match('/\b' . $func . '\s*\(/', $line)) {
$this->vulnerabilities[] = [
'type' => 'dangerous_function',
'line' => $lineNum,
'description' => "使用危险函数: {$func}()",
'code' => $line
];
}
}
}
private function checkSQLInjection($line, $lineNum) {
if (preg_match('/(SELECT|INSERT|UPDATE|DELETE).*\$_(GET|POST|REQUEST)/i', $line)) {
$this->vulnerabilities[] = [
'type' => 'sql_injection',
'line' => $lineNum,
'description' => '可能存在 SQL 注入风险',
'code' => $line
];
}
}
private function checkXSS($line, $lineNum) {
if (preg_match('/echo.*\$_(GET|POST|REQUEST)/i', $line) &&
!preg_match('/htmlspecialchars|htmlentities|filter_var/i', $line)) {
$this->vulnerabilities[] = [
'type' => 'xss',
'line' => $lineNum,
'description' => '存在 XSS 漏洞风险',
'code' => $line
];
}
}
}
// 使用示例
$scanner = new PHPCodeScanner();
$result = $scanner->scanFile('path/to/your/file.php');
print_r($result);
目录递归扫描
<?php
function scanDirectory($dir, $scanner) {
$files = scandir($dir);
$allVulnerabilities = [];
foreach ($files as $file) {
if ($file == '.' || $file == '..') continue;
$path = $dir . '/' . $file;
if (is_dir($path)) {
$allVulnerabilities = array_merge(
$allVulnerabilities,
scanDirectory($path, $scanner)
);
} elseif (pathinfo($file, PATHINFO_EXTENSION) == 'php') {
$vulns = $scanner->scanFile($path);
foreach ($vulns as $v) {
$v['file'] = $path;
$allVulnerabilities[] = $v;
}
}
}
return $allVulnerabilities;
}
// 使用
$scanner = new PHPCodeScanner();
$results = scanDirectory('./src', $scanner);
CI/CD 集成
GitLab CI 配置
# .gitlab-ci.yml
php-sast:
stage: test
image: php:8.2
script:
- composer install --dev
- vendor/bin/phpstan analyse src --no-progress
- vendor/bin/psalm --no-cache
artifacts:
reports:
sast: gl-sast-report.json
GitHub Actions
name: PHP SAST
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- name: Install dependencies
run: composer install --dev
- name: Run PHPStan
run: vendor/bin/phpstan analyse src --level=8
- name: Run Psalm
run: vendor/bin/psalm --show-info=true
最佳实践建议
扫描策略
- 定期扫描 - 在每次代码提交时进行扫描
- 分层扫描 - 基础扫描 + 深度扫描
- 误报处理 - 建立误报库,减少干扰
关注重点
- SQL 注入
- XSS 跨站脚本
- 命令注入
- 文件包含漏洞
- 不安全的反序列化
- 敏感信息泄露
集成流程
选择工具组合 2. 配置扫描规则 3. 集成到 CI/CD 4. 建立问题追踪 5. 定期更新规则库
通过以上方法,你可以实现 PHP 代码的静态安全扫描,帮助在开发早期发现潜在的安全问题。