PHP 安全编码培训指南
培训目标
通过本培训,使开发人员掌握PHP安全编码的核心技能,能够识别和防范常见的安全漏洞。

常见安全漏洞及防护
SQL注入(SQL Injection)
危险代码示例:
// ❌ 危险代码 $username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $result = mysqli_query($conn, $sql);
安全代码示例:
// ✅ 安全代码 - 使用预处理语句
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
$stmt->bind_param("ss", $username, $password);
$stmt->execute();
$result = $stmt->get_result();
跨站脚本攻击(XSS)
危险代码示例:
// ❌ 危险代码 echo "欢迎,".$_GET['username'];
安全代码示例:
// ✅ 安全代码 - 输出转义
echo "欢迎,".htmlspecialchars($_GET['username'], ENT_QUOTES, 'UTF-8');
// 或者使用模板引擎(如Twig)自动转义
echo $twig->render('welcome.html', ['username' => $_GET['username']]);
CSRF防护
危险代码示例:
// ❌ 危险代码
if ($_POST['action'] == 'delete') {
deleteUser($_POST['user_id']);
}
安全代码示例:
// ✅ 安全代码 - 使用CSRF令牌
session_start();
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
if ($_POST['action'] == 'delete') {
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die('CSRF验证失败');
}
deleteUser($_POST['user_id']);
}
文件上传漏洞
危险代码示例:
// ❌ 危险代码 move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name']);
安全代码示例:
// ✅ 安全代码
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif'];
$maxSize = 2 * 1024 * 1024; // 2MB
if (!in_array($_FILES['file']['type'], $allowedTypes)) {
die('不允许的文件类型');
}
if ($_FILES['file']['size'] > $maxSize) {
die('文件过大');
}
// 生成随机文件名
$extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
$newName = bin2hex(random_bytes(16)).'.'.$extension;
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$newName);
路径遍历
危险代码示例:
// ❌ 危险代码
$file = $_GET['file'];
$content = file_get_contents('/var/www/html/files/'.$file);
安全代码示例:
// ✅ 安全代码
$baseDir = '/var/www/html/files/';
$file = basename($_GET['file']);
$fullPath = $baseDir.$file;
if (strpos(realpath($fullPath), realpath($baseDir)) !== 0) {
die('非法的路径');
}
$content = file_get_contents($fullPath);
安全编码最佳实践
输入验证与过滤
// 使用filter_var进行输入验证
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if (!$email) {
die('邮箱格式不正确');
}
$id = filter_var($_GET['id'], FILTER_VALIDATE_INT);
if (!$id || $id <= 0) {
die('无效的ID');
}
会话安全
// 会话安全配置
session_start();
session_regenerate_id(true); // 防止会话固定攻击
// 设置安全的会话cookie
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.use_strict_mode', 1);
密码安全存储
// ✅ 使用password_hash和password_verify
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
if (password_verify($password, $hashedPassword)) {
echo '密码正确';
}
安全配置
// php.ini 重要安全配置 error_reporting(E_ALL); display_errors = Off; // 生产环境关闭错误显示 log_errors = On; expose_php = Off; // 隐藏PHP版本信息 open_basedir = "/var/www/html"; // 限制脚本可访问目录
实战演练
项目包含以下功能模块:
- 用户登录/注册 - 使用安全的会话管理和密码存储
- 文件上传 - 严格验证文件类型和大小
- 数据展示 - 防止XSS攻击
- 搜索功能 - 防止SQL注入
安全清单(Checklist):
- [ ] 所有数据库操作使用预处理语句
- [ ] 所有输出进行HTML转义
- [ ] 使用CSRF令牌
- [ ] 限制文件上传类型和大小
- [ ] 密码使用password_hash存储
- [ ] 合理设置会话参数
- [ ] 关闭PHP错误显示
- [ ] 使用HTTPS
资源推荐
常用安全库:
- HTMLPurifier: XSS防护
- ParagonIE: 加密和随机数
- Bouncer: 权限控制
参考资料:
- OWASP PHP Security Cheat Sheet
- PHP官方安全手册
- SANS PHP安全编码指南
常见问题解答
Q1: 我应该使用什么字符集?
A: 统一使用UTF-8,包括数据库连接、页面输出和文件保存。
Q2: 如何防止暴力破解?
A: 实现登录限速、锁定策略和验证码机制。
Q3: 第三方库是否安全?
A: 需要定期更新,关注CVE漏洞公告。
通过以上培训内容和实战练习,开发人员应该能够掌握PHP安全编码的核心技能,建议配套进行代码审计和渗透测试练习,加深理解。