9.6 网络安全基础
网络安全是每个开发者都必须掌握的知识,现在网络攻击越来越普遍,了解常见的攻击方式和防护方法,才能写出安全可靠的应用,避免数据泄露和系统被入侵。
常见网络攻击方式
1. XSS攻击(跨站脚本攻击)
原理:攻击者在网页中注入恶意的JavaScript脚本,当用户访问网页时,脚本会在用户的浏览器中执行,窃取用户的Cookie、账号信息,或者执行恶意操作。
- 类型:
- 存储型XSS:恶意脚本被存储到服务器数据库中,所有访问该内容的用户都会被攻击,比如论坛的帖子评论中注入脚本
- 反射型XSS:恶意脚本放在URL中,诱导用户点击链接,服务器将脚本反射回浏览器执行
- DOM型XSS:攻击完全发生在客户端,通过修改页面DOM执行脚本,不需要服务器参与
- 危害:窃取用户Cookie、冒充用户操作、钓鱼、挂马
- 防范方法:
- 所有用户输入的内容在输出到页面时都进行HTML转义,替换特殊字符< > ’ “ &等
- 设置Cookie的HttpOnly属性,禁止JavaScript读取Cookie
- 对用户输入进行过滤和校验,禁止输入危险的标签和脚本
- 使用内容安全策略CSP,限制页面可以加载的脚本来源
2. CSRF攻击(跨站请求伪造)
原理:攻击者诱导用户登录A网站后,访问攻击者的恶意网站,恶意网站自动向A网站发送请求,利用用户在A网站的登录状态,冒充用户执行操作(比如转账、修改密码)。
- 攻击条件:用户登录了A网站,并且没有退出,Cookie还在有效期内,访问了恶意网站
- 危害:冒充用户执行敏感操作,比如转账、发消息、修改信息
- 防范方法:
- 使用CSRF Token:每个请求携带一个随机的Token,服务器验证Token是否合法
- 验证Referer字段,检查请求是否来自合法的来源
- 敏感操作增加二次验证,比如短信验证码、密码确认
- 重要操作使用POST请求,不要用GET请求执行修改操作
3. SQL注入攻击
原理:攻击者在输入的参数中注入SQL语句,服务器没有对输入进行校验,直接拼接到SQL语句中执行,导致攻击者可以执行任意SQL语句,获取、修改、删除数据库数据,甚至控制数据库服务器。
- 例子:登录接口的SQL语句是
SELECT * FROM users WHERE username='$username' AND password='$password',攻击者输入用户名' OR 1=1 --,拼接后的SQL变成SELECT * FROM users WHERE username='' OR 1=1 --' AND password='xxx',直接绕过密码验证 - 危害:拖库(获取整个数据库的数据)、删库、篡改数据、获取服务器权限
- 防范方法:
- 永远不要拼接SQL语句,使用预编译SQL(PreparedStatement)和参数绑定
- 不要使用动态SQL,禁止用户输入直接拼接到SQL中
- 数据库权限最小化,应用的数据库账号不要给超级管理员权限,只给必要的权限
- 对用户输入进行严格的校验和过滤,特殊字符转义
- 生产环境禁止返回数据库错误信息到前端,避免泄露表结构
4. DDoS攻击(分布式拒绝服务攻击)
原理:攻击者控制大量肉鸡(被入侵的机器),同时向目标服务器发送大量的合法或伪造的请求,占满服务器的带宽和资源,导致正常用户无法访问。
- 常见类型:
- 流量型攻击:发送大量的流量占满服务器带宽,比如UDP洪水、ICMP洪水
- 资源耗尽型攻击:发送大量合法请求,占满服务器的连接、CPU、内存资源,比如SYN洪水、CC攻击
- 危害:服务不可用,业务中断,造成巨大经济损失
- 防范方法:
- 接入高防服务、CDN、流量清洗,清洗异常流量
- 带宽扩容,冗余部署
- 优化服务器性能,提升抗攻击能力
- 封禁异常IP,限制单IP的请求频率
- SYN Cookie、限速、限流等防护措施
5. 目录遍历攻击
原理:攻击者在URL中输入../等字符,穿越到网站根目录之外,读取服务器上的敏感文件,比如配置文件、源码、/etc/passwd等。
- 例子:网站的图片地址是
/download?filename=1.jpg,攻击者访问/download?filename=../etc/passwd,如果没有校验,就可以读取/etc/passwd文件 - 危害:泄露服务器敏感文件、源码、配置信息,甚至获取服务器权限
- 防范方法:
- 对用户传入的文件名进行严格校验,禁止包含
../等特殊字符 - 路径规范化后判断是否在允许的目录范围内
- 不要把敏感文件放在web目录下
- 权限最小化,web进程不要有敏感文件的读取权限
- 对用户传入的文件名进行严格校验,禁止包含
6. 命令注入攻击
原理:攻击者在输入中注入系统命令,服务器没有校验直接执行,导致攻击者可以执行任意系统命令,控制服务器。
- 例子:接口需要执行ping命令,用户输入IP地址
127.0.0.1; rm -rf /,如果直接拼接到系统命令中执行,就会执行删除根目录的命令 - 危害:完全控制服务器,删除数据、窃取数据、安装木马
- 防范方法:
- 尽量不要执行系统命令,如果必须执行,禁止把用户输入拼接到命令中
- 使用安全的函数执行命令,参数分开传递,不要用shell解析
- 对用户输入进行严格的过滤和校验,禁止包含|&;等特殊字符
- 运行服务的用户权限最小化,不要用root权限运行
加密算法基础
加密算法是网络安全的基础,用来保证数据的保密性、完整性、身份认证。
对称加密算法
加密和解密使用同一个密钥:
- 常见算法:AES、DES、3DES、SM4(国密)
- 优点:加密解密速度快,效率高,适合大量数据加密
- 缺点:密钥分发困难,需要安全地把密钥传给对方
- 适用场景:大数据量加密、本地数据加密
非对称加密算法
加密和解密使用不同的密钥,分为公钥和私钥,公钥公开,私钥自己保存:
- 常见算法:RSA、ECC、SM2(国密)
- 用法:
- 公钥加密,私钥解密:用来加密传输数据,只有私钥持有者能解密
- 私钥签名,公钥验签:用来做身份认证和防篡改,私钥签名的内容只有对应的公钥能验证
- 优点:安全性高,不需要传输私钥,解决密钥分发问题
- 缺点:加密解密速度慢,只适合小数据量加密
- 适用场景:密钥交换、数字签名、身份认证
哈希算法(摘要算法)
将任意长度的数据转换为固定长度的摘要,是单向的,不能从摘要反推出原始数据:
- 常见算法:MD5(不安全)、SHA-1(不安全)、SHA-256、SHA-512、SM3(国密)
- 特点:
- 相同的输入一定得到相同的输出
- 不同的输入几乎不可能得到相同的输出(抗碰撞)
- 单向不可逆
- 用途:数据完整性校验、密码存储、数字签名
- 注意:MD5和SHA-1已经被破解,不要用于安全相关的场景,密码存储应该用慢哈希算法(bcrypt、scrypt、PBKDF2),而不是普通的哈希算法
数字签名
数字签名用来验证数据的完整性和发送者的身份:
- 原理:发送方对数据的哈希值用私钥签名,接收方用公钥验证签名是否合法
- 作用:
- 身份认证:确认数据是私钥持有者发送的
- 不可否认:发送方不能否认发送过该数据
- 完整性:数据没有被篡改过
HTTPS与TLS/SSL协议
HTTPS就是HTTP + TLS/SSL,在HTTP和TCP之间加了一层TLS加密层,保证通信的安全。
TLS握手过程
- 客户端Hello:客户端发送支持的TLS版本、加密套件、随机数给服务器
- 服务器Hello:服务器选择双方都支持的加密套件和TLS版本,返回服务器的数字证书、服务器生成的随机数
- 客户端验证证书:客户端验证证书的合法性(是否是可信CA签发、是否过期、域名是否匹配),验证通过后生成预主密钥,用服务器公钥加密后发送给服务器
- 服务器解密预主密钥:服务器用私钥解密得到预主密钥,双方根据之前的随机数和预主密钥生成相同的会话密钥
- 握手完成:双方通知对方后续使用会话密钥加密通信,握手完成,后续的HTTP数据都用会话密钥对称加密传输
数字证书
数字证书用来证明网站的身份,由可信的CA(证书颁发机构)签发:
- 证书包含:网站域名、公钥、有效期、CA签名等信息
- 证书链:根CA签发中级CA证书,中级CA签发用户证书,形成证书链,客户端通过信任的根证书来验证证书的合法性
- 注意:不要使用自签名证书,客户端不信任,存在中间人攻击风险,应该使用可信CA签发的证书
HTTPS的作用
- 保密性:传输的数据都是加密的,第三方无法窃听内容
- 完整性:数据传输过程中被篡改会被检测到
- 身份认证:验证网站的真实身份,防止钓鱼网站和中间人攻击
常见安全设备和机制
- 防火墙:位于内外网之间,根据规则过滤网络流量,禁止非法访问,分为网络层防火墙和应用层防火墙
- WAF(Web应用防火墙):专门防护Web应用的攻击,比如XSS、SQL注入、CSRF、CC攻击等
- 入侵检测系统(IDS)/入侵防御系统(IPS):检测网络中的入侵行为,发现攻击及时报警或阻断
- VPN(虚拟专用网络):在公网上建立加密的专用通道,远程访问内部网络时使用,保证通信安全
- 零信任架构:默认不信任任何内部或外部的用户和设备,每次访问都需要验证授权,是现在安全架构的发展方向
网络安全最佳实践
开发阶段
- 最小权限原则:所有系统、数据库、服务的权限最小化,只给需要的最小权限,不要用root/管理员权限运行服务
- 输入校验:所有用户输入都要做严格的校验和过滤,永远不要信任用户的输入
- 不要硬编码敏感信息:密码、密钥、Token等敏感信息不要硬编码在代码和配置文件中,应该用加密的配置中心或者环境变量存储
- 密码安全:用户密码不要明文存储,要用bcrypt等慢哈希算法加盐存储,不要用MD5、SHA1
- 输出转义:所有用户输入输出到页面、日志、数据库的地方都要做对应的转义,避免注入攻击
- HTTPS全站加密:所有网站和接口都用HTTPS,不要用明文HTTP传输敏感信息
- 漏洞扫描:代码上线前做安全扫描,定期做渗透测试,及时修复安全漏洞
运行阶段
- 定期更新补丁:操作系统、应用、依赖库的安全补丁要及时更新,修复已知漏洞
- 日志和监控:完善安全日志和监控,及时发现异常访问和攻击行为
- 访问控制:敏感接口、后台管理系统加IP白名单、二次认证,限制访问权限
- 定期备份:数据定期备份,异地存储,防止被攻击后数据丢失
- 安全培训:开发和运维人员定期做安全培训,提升安全意识
思考问题
- XSS和CSRF攻击的原理是什么?如何防范这两种攻击?
- SQL注入的原理是什么?为什么预编译SQL能防止SQL注入?
- 对称加密和非对称加密各有什么优缺点?HTTPS握手过程中是怎么结合使用这两种加密方式的?
- 为什么要使用慢哈希算法存储用户密码,而不是普通的SHA-256哈希?