网站安全加固完全指南:XSS、CSRF、SQL 注入防护实践

网站安全不是可选项,而是建站的基础要求。据 Verizon 数据泄露报告,43% 的网络攻击针对小型网站。

OWASP Top 10 关键威胁

OWASP(开放 Web 应用安全项目)每三年更新一次 Web 应用十大安全风险。以下是针对最常见的几种攻击的防护方案。

一、XSS(跨站脚本攻击)

XSS 攻击者将恶意脚本注入网页,在用户浏览器中执行。

防护方案

1. 输出编码

// 前端编码函数
function escapeHtml(str) {
    const div = document.createElement("div");
    div.textContent = str;
    return div.innerHTML;
}

// React 默认对 JSX 变量进行转义
// Vue 使用 {{ }} 会转义,v-html 不会

2. Content Security Policy(CSP)

# 只允许加载同源资源
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'" always;

3. 设置 HttpOnly Cookie

// 设置 Cookie 时标记 HttpOnly
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax;

二、CSRF(跨站请求伪造)

CSRF 攻击者诱导用户点击链接,在已登录状态下执行非自愿操作。

防护方案

1. CSRF Token

<form method="POST" action="/transfer">
    <input type="hidden" name="_csrf" value="{{csrfToken}}">
    <input type="text" name="amount">
    <button type="submit">提交</button>
</form>

2. SameSite Cookie 属性

Set-Cookie: session=abc123; SameSite=Strict; Secure;

SameSite=Strict 可防止所有跨站 Cookie 发送,SameSite=Lax 允许部分安全请求。

3. 验证 Referer/Origin 头

// 服务端验证
function isValidRequest(req) {
    const origin = req.headers.origin;
    const allowedOrigins = ['https://example.com'];
    return allowedOrigins.includes(origin);
}

三、SQL 注入

SQL 注入攻击者通过输入恶意 SQL 片段操纵数据库查询。

防护方案

1. 参数化查询(最重要)

// ❌ 错误:字符串拼接
const query = `SELECT * FROM users WHERE id = ${userId}`;

// ✅ 正确:参数化查询 (Node.js + pg)
const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);

// ✅ 正确:参数化查询 (PHP + PDO)
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute([':id' => $userId]);

2. ORM 框架

使用 Prisma、TypeORM、Eloquent、SQLAlchemy 等 ORM 可以自动避免 SQL 注入。

// Prisma 安全查询
const user = await prisma.user.findUnique({
    where: { id: userId }
});

3. 最小权限原则

数据库用户只应拥有其功能所需的最小权限。不要使用 root 连接数据库。

-- 只给应用用户 SELECT, INSERT, UPDATE, DELETE 权限
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'localhost';

四、更多安全实践

4.1 密码安全

// 使用 bcrypt 哈希密码
const bcrypt = require('bcrypt');
const salt = await bcrypt.genSalt(12);
const hash = await bcrypt.hash(password, salt);

4.2 HTTPS 强制

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

4.3 文件上传安全

  • 限制文件类型(白名单方式)
  • 限制文件大小
  • 上传到独立域名(防止 XSS)
  • 对上传文件进行病毒扫描

安全检查清单

  • 所有用户输入都经过验证和转义
  • 使用参数化查询或 ORM
  • 启用 HTTPS 并配置 HSTS
  • 设置安全响应头(CSP, X-Frame-Options 等)
  • CSRF Token 或 SameSite Cookie 已配置
  • 密码使用 bcrypt/argon2 哈希
  • 文件和目录权限正确
  • 软件和依赖定期更新
  • 日志记录和监控已启用
  • 数据备份策略已制定

16IDC 观察

网站安全防护的核心不是单一措施,而是多层防御(Defense in Depth)。即使配置了 WAF 和 CDN,应用层的安全编码仍然是不可替代的基础防线。

建议参考 Nginx 安全配置指南SSL/TLS 部署指南 完善基础设施安全。