Web安全
名词定义
窃听者:在网络中通过抓包、劫持等方式能够获取用户请求数据的Hacker
窃密者:通过非正常手段可获取到用户数据的Hacker
攻击者:具有一定计算机网络基础能够通过工具或者自主开发工具实现特殊目的的Hacker
摘要算法:消息摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名、数据完整性校验等功能。
由于其不可逆性,有时候会被用做敏感信息的加密。加密算法:加密(英语:Encryption)是将明文信息改变为难以读取的密文内容,使之不可读的过程。只有拥有解密方法的对象,经由解密过程,才能将密文还原为正常可读的内容。加密算法即加密的方法。
TOP 1 访问越权
- 未进行最小权限校验
通常由于未对用户个人/设备等隐私数据的访问、修改进行应该权限检查而出现的越权访问;普通用户通过伪造请求访问管理员才能访问的数据等
⚔️
原请求:curl 'http://example.com/getUserInfo' -H 'accessToken:abc' -d '{"uid":123}'
返回123用户的信息修改后的请求:
curl 'http://example.com/getUserInfo' -H 'accessToken:abc' -d '{"uid":321}'
返回321用户的信息普通用户伪造请求:
curl 'http://example.com/getAdminUserList'
🛡️
- 针对有用户属性资源(如用户信息、用户上传的非公开图片、用户个人资产等)的请求需校验当前请求用户的权限
- 针对有设备属性资源(如打印请求、打印历史记录等)的请求需校验当前请求用户是否有该设备权限
- 对于后台类资源请求需校验用户管理员权限
- 重放攻击
网络中存在窃听者将获取到的用户请求数据用于重复请求获取敏感信息
⚔️
原请求:
curl 'http://example.com/resetPassword' -H 'accessToken:abc' -d '{"smsCode":1234}'
请求后用户可进入用户密码重置流程重复请求:
curl 'http://example.com/resetPassword' -H 'accessToken:abc' -d '{"smsCode":1234}'
请求后窃听者可进入用户密码重置流程🛡️
- 每个请求添加请求时间,对于过期的请求直接拦截
- 可在分发给用户的token中关联用户IP、设备等信息,对于IP、设备更换的请求直接拦截(在移动网络中用户的IP可能随时变动会导致影响普通用户使用,需要注意业务是否需要如此高的风险等级)
- 篡改请求
由于未对完整的请求参数进行签名,导致窃听者获取到用户请求后可以通过修改请求参数实现不同的目的
⚔️
原请求:
curl 'http://example.com/transferMoney' -H 'accessToken:abc' -H 'sign:abcd' -H 'requestTime:1024' -d '{"toAccount":123,"money":100}'
(其中sign仅对requestTime、accessToken做签名)修改后的请求:
curl 'http://example.com/transferMoney' -H 'accessToken:abc' -H 'sign:abcd' -H 'requestTime:1024' -d '{"toAccount":321,"money":100000}'
🛡️
- 对所有的请求参数进行签名而不是部分参数(如sign(requestParam,body))
- 对于有需要参与签名的参数使用body而不是header传输(header包含其他非业务参数无法做统一签名)
敏感数据泄漏
通常出现在用户的密码、人脸信息、签名信息等敏感信息在网络传输过程中或存储过程中未进行妥善的脱敏处理;加密算法未添加合适的随机因子导致密钥可被计算
⚔️
泄露用户密码的请求:
curl 'http://example.com/login' -d '{"username":"test","password":"1234"}'
明文存储用户密码:
INSERT INTO user (id, uid, password, name) VALUES (null, 100000, '123456', 'test');
简单哈希存储用户密码:
INSERT INTO user (id, uid, password, name) VALUES (null, 100000, md5('123456'), 'test');
AES加密过程使用固定的iv:
mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $screct_key, $str, MCRYPT_MODE_CBC, "");
包含用户敏感信息(如身份证照片)的图片、文件直接存放在公网:https://pic3.zhimg.com/50/v2-3df337b968a9898a176a2f0bf8e0630d_720w.jpg
包含用户鉴权信息的URL请求:
curl 'http://example.com/getUserInfo?sessionId=abc'
🛡️
- 在开放网络中使用https而非http
- 网络传输可只传输用户密码哈希后的值如:
curl 'http://example.com/login' -d '{"username":"test","password":md5("1234")}'
- 存表的用户密码等不需要解密的敏感数据加盐哈希后存表可以避免数据库数据泄露后被彩虹表破解密码
- 包含用户敏感信息的图片、文件应存在私有空间中,公网连接应有实效性,对于没有实时性展示用途的图片、文件还应进行数据加密后存储,使用时临时解密
- 浏览器、服务端日志等通常都会主动记录用户请求的URL,避免将用户鉴权信息通过URL的方式传递,减少用户鉴权信息暴露风险
注入
- SQL注入
通过改变既定的SQL语义实现对数据库的非法访问或控制
⚔️
$column = array_get($requestParam, "column", "*"); $clientId = array_get($requestParam, "clientId"); $obj = new Dao(); $client = $obj->getRow("id", $column, "clientId=?", $clientId); return $client;
🛡️
- 使用参数绑定及对用户输入的参数进行校验和过滤,避免用户
- 本地开发时使用工具检测(如SQL注入工具:sqlmap)
安全设计缺陷
- 不安全的第三方请求
对于第三方请求未进行加密或有效鉴权,导致本应提供给特定第三方使用的服务或接口被攻击者滥用。通常通过为每个第三方颁发一套加密、签名信息(如:应用ID、应用密钥),安全性要求较低的请求可通过特定算法计算所有请求参数的签名值再作为附加请求参数请求,安全性要求适中的请求则通过通用对称加密算法加密数据请求,安全性要求高的请求则通过非对称加密算法协商出对称加密密钥后通过对称加密请求。
- 重要请求未多重验证
对于重要请求(如:余额支付、取现、敏感信息修改、更换设备登录等)未进行多重校验。通常通过人脸、短信、隐私信息校验、辅助校验的方式进行多重用户身份验证避免用户账号被盗产生损失。
- 重要数据通过外部传入
重要的信息通过外部直接传入,后端未做任何校验直接使用
⚔️
通过入参控制支付金额的请求:
curl 'http://example.com/pay' -d '{"orderId":1, "money":10}'
🛡️
- 外部入参只传递非必要信息,重要数据由服务端内部自行获取:
curl 'http://example.com/pay' -d '{"orderId":1}'
订单支付金额由服务端内部查询
业务安全
垃圾内容(文本/图片)
对于用户无任何价值或包含发布者特殊目的的内容
⚔️
垃圾内容通常包括:广告、黄赌毒、涉政言论等
🛡️
通常可以通过人工审核、机器审核(机器学习算法)、关键字匹配等方式对垃圾内容进行过滤或内容替换
脚本攻击
攻击者出于某种特殊目的模拟普通用户使用脚本批量调用关键接口
⚔️
通常容易被攻击的接口:短信验证码、登录、注册、秒杀等
🛡️
通常通过增加请求前验证(如:图形验证码、人机识别系统)的方式进行机器调用拦截,对于秒杀等能够获得较大利益的场景可通过提前预约的方式进行事前验证,避免攻击者利用打码平台等人工绕过验证。
信息泄露
用户敏感信息在管理后台、请求日志、用户信息页面等明文展示或请求的接口中明文返回
⚔️
用户的敏感信息:如用户姓名、手机号、身份证号、地址、打印文件路径等
🛡️
针对需要展示用户敏感信息的场景对所展示的数据做脱敏处理,确实需要展示的可通过多重验证后展示
敏感操作
对于可能存在法律风险的操作
⚔️
敏感操作通过包括:网络借贷、重要信息(如:个人征信、银行流水等)授权等
🛡️
对敏感操作进行存证,存证方式如:人脸、电子签名、第三方电子签约等,对于存在法律风险的操作法院一般会要求提供由第三方作为公证的存证(即数据不可自己保存又作为自证证据,因为数据可能被篡改的)。
参考文献
- 《OWASP Top 10:2021》 Open Web Application Security Project (OWASP) 是致力于提高软件安全性的非营利基金会