小薛同学个人博客,XXTX的个人主页,acnb,ACNB,www.acnb.cn,个人主页,技术博客,编程学习,代码分享,全栈开发,前端开发,网络安全,Web安全,XSS攻击,CSRF攻击,SQL注入,安全防护,渗透测试,安全审计,漏洞修复,安全最佳实践,小薛同学博客,acnb
2025年9月30日
网络安全
阅读时间:25分钟

网络安全攻防实战

Web应用安全防护全攻略

安全威胁概述

Web安全是保障用户数据和系统稳定性的重要环节。了解常见攻击手段是有效防御的第一步。

OWASP Top 10: 最重要的十大Web应用安全风险,是安全评估的基准。

1. XSS(跨站脚本攻击)

1.1 攻击原理

攻击者将恶意脚本注入到网页中,当用户浏览该页面时,脚本会在用户浏览器中执行。

http://example.com/search?q=<script>alert('XSS')</script> <script>stealCookie(document.cookie)</script> <script> // 漏洞代码 document.getElementById('output').innerHTML = location.hash.substring(1); </script> http://example.com/page#<img src=x onerror=alert('XSS')>

1.2 防御策略

// 1. 输入验证 function sanitizeInput(input) { // 移除危险字符 return input.replace(/[<>"'&]/g, function(match) { return { '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#x27;', '&': '&amp;' }[match]; }); } // 2. 输出编码 function encodeForHTML(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // 3. 使用CSP(内容安全策略) // HTTP头部 Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self'; // 4. 设置Cookie安全属性 Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict; // 5. 使用安全的DOM操作 // 避免使用innerHTML element.textContent = userInput; // 或使用DOMPurify const cleanHTML = DOMPurify.sanitize(userInput); element.innerHTML = cleanHTML;

2. CSRF(跨站请求伪造)

2.1 攻击原理

攻击者诱导用户在已登录状态下访问恶意网站,从而以用户身份执行非预期操作。

<!-- CSRF攻击示例 --> <!-- 攻击者页面 --> <html> <body> <form action="https://bank.com/transfer" method="POST"> <input type="hidden" name="to" value="attacker"> <input type="hidden" name="amount" value="10000"> </form> <script> document.forms[0].submit(); </script> </body> </html>

2.2 防御策略

// 1. CSRF Token // 生成Token const crypto = require('crypto'); function generateCSRFToken() { return crypto.randomBytes(32).toString('hex'); } // 服务器端验证 app.post('/transfer', (req, res) => { const userToken = req.body._csrf; const sessionToken = req.session.csrfToken; if (!userToken || userToken !== sessionToken) { return res.status(403).send('CSRF token验证失败'); } // 处理业务逻辑 }); // 2. SameSite Cookie属性 // 在设置Cookie时 res.cookie('sessionId', 'abc123', { httpOnly: true, secure: true, sameSite: 'strict' // 或 'lax' }); // 3. 验证Referer头部 app.use((req, res, next) => { const referer = req.headers.referer; const origin = req.headers.origin; if (req.method === 'POST' || req.method === 'PUT' || req.method === 'DELETE') { // 验证Referer是否来自同一域名 if (referer && !referer.startsWith('https://yourdomain.com')) { return res.status(403).send('非法请求来源'); } } next(); }); // 4. 使用自定义请求头部 // 前端设置 fetch('/api/transfer', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-Token': csrfToken }, body: JSON.stringify(data) }); // 后端验证 app.use((req, res, next) => { if (req.get('X-Requested-With') !== 'XMLHttpRequest') { return res.status(403).send('必须使用AJAX请求'); } next(); });

3. SQL注入

3.1 攻击原理

-- 原始查询 SELECT * FROM users WHERE username = '$username' AND password = '$password'; -- 攻击输入 username: admin' -- password: anything -- 最终执行的SQL SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything'; -- 注释掉后续条件,绕过密码验证 -- 更危险的注入 username: admin' OR '1'='1 password: ' OR '1'='1 -- 最终执行的SQL SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '' OR '1'='1'; -- 返回所有用户

3.2 防御策略

// 1. 使用参数化查询(Prepared Statements) // Node.js + MySQL const mysql = require('mysql2/promise'); async function getUser(username, password) { const connection = await mysql.createConnection({ host: 'localhost', user: 'root', database: 'test' }); // 使用参数化查询 const [rows] = await connection.execute( 'SELECT * FROM users WHERE username = ? AND password = ?', [username, password] ); return rows[0]; } // 2. 使用ORM框架 // Sequelize示例 const User = require('./models/user'); async function findUser(username, password) { return await User.findOne({ where: { username: username, password: password } }); } // 3. 输入验证 function validateInput(input) { // 只允许字母数字和下划线 if (!/^[a-zA-Z0-9_]+$/.test(input)) { throw new Error('非法输入'); } return input; } // 4. 最小权限原则 -- 创建专门用于查询的数据库用户 CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'password'; GRANT SELECT, INSERT, UPDATE ON database.users TO 'webapp'@'localhost'; -- 不授予DELETE、DROP等危险权限 // 5. 使用存储过程 DELIMITER // CREATE PROCEDURE GetUser(IN p_username VARCHAR(50), IN p_password VARCHAR(50)) BEGIN SELECT * FROM users WHERE username = p_username AND password = p_password; END // DELIMITER ; -- 调用存储过程 CALL GetUser('admin', 'password123');

4. 文件上传漏洞

4.1 攻击原理

<!-- 攻击者上传恶意文件 --> 1. 上传PHP Webshell <?php system($_GET['cmd']); ?> 2. 上传恶意HTML <script>alert('XSS')</script> 3. 利用路径遍历 filename: ../../../etc/passwd 4. 利用文件包含 <?php include($_GET['file']); ?>

4.2 防御策略

// 1. 文件类型验证 const multer = require('multer'); const path = require('path'); const storage = multer.diskStorage({ destination: './uploads/', filename: (req, file, cb) => { // 生成随机文件名 const uniqueName = Date.now() + '-' + Math.round(Math.random() * 1E9); // 获取文件扩展名 const ext = path.extname(file.originalname).toLowerCase(); // 只允许特定扩展名 const allowedExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.pdf']; if (!allowedExtensions.includes(ext)) { return cb(new Error('文件类型不支持')); } cb(null, uniqueName + ext); } }); const upload = multer({ storage: storage, limits: { fileSize: 5 * 1024 * 1024, // 5MB files: 1 }, fileFilter: (req, file, cb) => { // 检查MIME类型 const allowedMimeTypes = [ 'image/jpeg', 'image/png', 'image/gif', 'application/pdf' ]; if (!allowedMimeTypes.includes(file.mimetype)) { return cb(new Error('文件类型不支持'), false); } cb(null, true); } }); // 2. 重命名文件 function generateSafeFilename(originalname) { // 移除特殊字符 const safeName = originalname.replace(/[^a-zA-Z0-9.-]/g, '_'); // 添加随机前缀 const randomPrefix = Date.now() + '-' + Math.random().toString(36).substr(2, 9); return randomPrefix + '_' + safeName; } // 3. 隔离上传目录 // 将上传文件存放在Web根目录之外 app.use('/uploads', express.static(path.join(__dirname, '../uploads'))); // 4. 文件内容检查 const fileType = require('file-type'); const fs = require('fs'); async function validateFileContent(filePath) { const buffer = fs.readFileSync(filePath); const type = await fileType.fromBuffer(buffer); if (!type) { throw new Error('无法识别文件类型'); } // 验证实际文件类型与扩展名是否匹配 const allowedTypes = [ { ext: 'jpg', mime: 'image/jpeg' }, { ext: 'png', mime: 'image/png' }, { ext: 'gif', mime: 'image/gif' }, { ext: 'pdf', mime: 'application/pdf' } ]; const isValid = allowedTypes.some(allowed => allowed.ext === type.ext && allowed.mime === type.mime ); if (!isValid) { throw new Error('文件内容与类型不匹配'); } return true; } // 5. 设置文件权限 // 上传的文件应该只有读取权限 fs.chmodSync(filePath, 0o644);

5. 安全头部配置

// Express安全头部配置 const helmet = require('helmet'); app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"], styleSrc: ["'self'", "'unsafe-inline'"], scriptSrc: ["'self'", "'unsafe-inline'", "https://cdn.example.com"], imgSrc: ["'self'", "data:", "https://*.example.com"], connectSrc: ["'self'", "https://api.example.com"], fontSrc: ["'self'", "https://fonts.example.com"], objectSrc: ["'none'"], mediaSrc: ["'self'"], frameSrc: ["'none'"], baseUri: ["'self'"], formAction: ["'self'"], frameAncestors: ["'none'"], upgradeInsecureRequests: [] } }, hsts: { maxAge: 31536000, includeSubDomains: true, preload: true }, referrerPolicy: { policy: 'strict-origin-when-cross-origin' }, permissionsPolicy: { features: { camera: ["'none'"], microphone: ["'none'"], geolocation: ["'none'"] } } })); // 自定义安全头部 app.use((req, res, next) => { res.setHeader('X-Content-Type-Options', 'nosniff'); res.setHeader('X-Frame-Options', 'DENY'); res.setHeader('X-XSS-Protection', '1; mode=block'); res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin'); res.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()'); next(); });

6. 安全测试工具

6.1 自动化扫描工具

# OWASP ZAP基础使用 # 启动ZAP ./zap.sh -daemon -port 8080 -config api.disablekey=true # 使用Docker运行ZAP docker run -u zap -p 8080:8080 -i owasp/zap2docker-stable \ zap.sh -daemon -host 0.0.0.0 -port 8080 -config api.disablekey=true # 使用ZAP API扫描 curl "http://localhost:8080/JSON/core/action/newSession/?name=test&overwrite=true" curl "http://localhost:8080/JSON/spider/action/scan/?url=http://target.com" curl "http://localhost:8080/JSON/ascan/action/scan/?url=http://target.com" # 使用ZAP进行主动扫描 docker run -u zap -p 8080:8080 -i owasp/zap2docker-stable \ zap-full-scan.py -t http://target.com -r report.html # Burp Suite社区版 # 1. 配置代理(127.0.0.1:8080) # 2. 安装证书 # 3. 使用Intruder进行暴力破解测试 # 4. 使用Repeater修改请求 # 5. 使用Scanner自动扫描 # SQLMap示例 sqlmap -u "http://target.com/product?id=1" --dbs sqlmap -u "http://target.com/product?id=1" -D database --tables sqlmap -u "http://target.com/product?id=1" -D database -T users --dump # Nmap安全扫描 nmap -sV -sC -O target.com nmap --script vuln target.com nmap -p 80,443,8080,8443 target.com

6.2 代码审计工具

# Semgrep(代码静态分析) semgrep --config auto . semgrep --config "p/security-audit" . # ESLint安全插件 # .eslintrc.js module.exports = { plugins: ['security'], extends: ['plugin:security/recommended'], rules: { 'security/detect-object-injection': 'error', 'security/detect-eval-with-expression': 'error', 'security/detect-non-literal-fs-filename': 'error', 'security/detect-pseudoRandomBytes': 'error' } }; # npm audit检查依赖漏洞 npm audit npm audit fix npm audit fix --force # Snyk安全检查 npx snyk test npx snyk monitor npx snyk wizard # OWASP Dependency-Check dependency-check --project "My Project" --scan ./ --out ./report

7. 应急响应计划

7.1 安全事件响应流程

// 1. 检测与识别 const securityEvents = { methods: [ '实时日志监控', '入侵检测系统(IDS)', 'Web应用防火墙(WAF)告警', '异常流量检测' ], indicators: [ '异常登录尝试', '大量404错误', '数据库查询异常', '文件系统变化' ] }; // 2. 隔离与遏制 const incidentResponse = { immediateActions: [ '断开受影响系统网络', '备份系统日志', '保存内存dump', '记录时间线' ], containmentStrategies: [ '修改防火墙规则', '重置用户密码', '禁用受影响账户', '关闭相关服务' ] }; // 3. 根除与恢复 const recoveryProcess = { steps: [ '识别攻击入口点', '修复安全漏洞', '清除恶意文件', '恢复干净备份', '验证系统完整性' ], verification: [ '安全扫描验证', '渗透测试验证', '日志审计验证', '功能测试验证' ] }; // 4. 总结与改进 const postMortem = { requirements: [ '编写事件报告', '分析攻击路径', '评估影响范围', '制定改进措施' ], improvements: [ '更新安全策略', '加强监控系统', '员工安全培训', '完善应急预案' ] };

总结

网络安全是一个持续的过程,而非一次性的任务。建立多层防御体系、定期安全审计和持续的安全意识教育是保障系统安全的关键。

安全原则:

  1. 最小权限原则
  2. 深度防御原则
  3. 默认拒绝原则
  4. 完整监控原则