WEB应用安全之输入验证

WEB2.0的普及,丰富了各类WEB产品。WEB交互能力的增强,也滋生出种类繁多的安全威胁,用户输入便成了万恶之源,不仅威胁用户信息安全,也给服务器、操作系统,甚至整个局域网带来灾难,因此,验证用户输入是WEB应用必不可少的安全防范举措。
1 输入为何需要验证
输入验证一般基于两个方面的原因:一是为了保证业务功能的合理性,二是为了保证用户数据、应用程序及内部系统和网络的安全。
1.1 业务层面
从业务的有效性和合理性来说,用户提交的参数都需要进行验证。在业务层面可能要求用户名只能包含大小写字母、数字,长度必须小于12位等;密码必须同时包含字母、数字、特殊字符,且长度必须大于8位等;金额必须在(0~1000]之间……诸如此类,我们的应用程序都需进行检测。可以想象,在金融类系统中,如果不对金额进行有效性检查,在转账类业务中,如果提交转账金额-10000¥,那是不是等同于对方给我转了10000¥呢。
1.2 安全层面
从另一个安全层面来说,输入验证则显得尤为重要,而这一点恰恰容易被开发者所忽略,众多的WEB漏洞中,无不因输入引起。如果你的应用中涉及如下功能,那么就得考虑是否有相应的验证和防护措施。
类型
功能
安全威胁
说明
输入

服务器端
响应
输入作为响应body的一部分
XSS

XXE
XML作为参数传递
输入作为响应header的一部分
CRLF

输入作为邮件的一部分
SMTP注入

响应中包含输入指定的文件
目录遍历

重定向至输入指定的网页
任意重定向

输入

服务器端
执行代码
输入嵌入SQL语句中
SQL注入

输入嵌入XPath表达式
XPath注入

输入嵌入LDAP语句
LDAP注入

输入作为应用代码执行
OS命令注入

文件上传
后门

输入

服务端
API参数
服务器端包含输入指定的文件
文件包含

服务器端请求输入的网址
服务器端HTTP重定向

不同应用之间通过输入参数互相调用
SOAP注入
使用SOAP
JSON注入
使用JSON
XML注入
使用XML
HTTP参数注入

……

表1-1功能和安全威胁对照表
2 哪些输入要素需要验证
上面已经提到如果不验证输入带来的威胁,那到底哪些输入需要验证呢?这就得先了解信任边界。
2.1 信任边界
信任边界是以组件或者功能单元进行区分,在信任边界外的所有输入均需验证。下图展示了一个典型的信任边界验证的例子(各个组件在执行操作前,均需输入验证):
WEB应用安全之输入验证 - tuchengju - tuchengju的博客
图2-1 信任边界确认
(1) 应用程序收到用户提交的输入。表单处理程序确认每个输入仅包含的合法字符、特殊长度限制,应转义或者过滤任何已知的攻击特征。
(2) 应用程序执行SQL查询。为防止SQL注入, DAO执行查询前,应用程序应对用户输入中包含的可用于攻击数据库的所有字符转义。
(3) 将用户提交的某些输入数据提交给SOAP服务,进一步获取相关数据。为防止SOAP注入,SAOP查询组件需要对用户提交数据中的任何XML元字符进行适当编码。
(4) 应用程序在用户的浏览器中显示响应数据。为防止跨站脚本攻击,输出组件需对植入返回页面中的任何用户提交数据执行HTML编码。
2.2 输入来源
在WEB应用中,输入来源基本可分为两类:一类由用户提交,另一类则来自于共享数据。用户提交的数据主要包括:
(1) 查询参数
(2) POST参数
(3) Cookie
(4) Referer
(5) REST参数
共享数据主要包括:
(1) 共享数据库
(2) 共享文件数据
(3) 网络数据
3 如何验证输入
输入验证的方式按照输入的类型有所不同,输入的类型可归纳为两类:常规参数和文件。当然,这里不涉及业务层面的合理性验证。
3.1 常规参数的输入验证
常规参数的输入验证方法需要根据特定的功能而定,主要有如下方法:
方法
说明
备注
字符转义
对影响程序结构和逻辑,以及改变输出效果的特殊字符均需转义。
效果比较好,且不影响业务功能。
字符过滤
对影响程序结构和逻辑,以及改变输出效果的特殊字符均需过滤。
效果比较好,但特殊字符可能与业务要求冲突。
白名单
只接受特定的输入,其他均忽略。
效果非常好,但适用性低,适合需要严格检查的业务。
黑名单
不接受特定的输入,其他均接受。
效果差,特别针对XSS等此类变种很多的安全威胁。
映射
建立映射关系,外部使用映射对象,而非直接使用源数据
效果非常好,但适用性低,适合需严格检查且不希望泄露源数据的业务。
表3-1 常规参数输入验证方法
如下针对各类安全威胁,列举了行之有效的参数输入验证方法:
类型
安全威胁
输入验证方法
输入

服务器端
响应
XSS
纯文本的参数:输出时转义<、>、&、{、}、#、”、’、;、/、[、]为HTML实体,对于DOM型XSS,则需确保JS在使用参数前,转义这些特殊字符。
富文本的参数:
1、 格式化输入,保证所有数据均可被识别和标准化;
2、 采用白名单的机制,明确允许出现哪些标签、哪些属性,对不允许出现的标签和属性值进行干扰或移除;
3、 对特定的属性值进行检查,比如:url必须以http://或https://开头,或者以/开头等。
4、 对标签内的特殊字符(<、>、”、’等)采用HTML实体转义。
XXE
优选方案:在解析XML时,不解析外部实体。
CRLF
移除%0D%0A或者其他形式的回车换行符。
SMTP注入
移除%0D%0A或者其他形式的回车换行符。
正文中不允许仅包含.的消息行。
目录遍历
对输入解码和规范化,拒绝包含、/以及空字符的请求。
检查是否请求相应目录、相应后缀的文件。
或者使用白名单指定允许访问的文件列表,拒绝其他文件的访问。
任意重定向
对输入解码和规范化,检查重定向地址是否在合法域内。
输入

服务器端
执行代码
SQL注入
参数化查询。
XPath注入
仅允许字母数字。
拒绝包含(、)、=、’、[、]、:、,、*、/,以及所有空白符的请求。
LDAP注入
仅允许字母数字。
拒绝包含(、)、;、,、*、|、&、=,以及空字符的请求。
OS命令注入
避免直接调用操作系统命令。
白名单限制允许调用的系统命令,拒绝白名单之外的命令执行。
输入

服务端
API参数
文件包含
白名单限制允许包含的文件,拒绝白名单之外的文件包含。
服务器端HTTP重定向
建立重定向地址的强随机映射表,外部提交随机字符,应用程序则根据随机字符匹配重定向地址,拒绝无法映射的重定向。
SOAP注入
解码后转义<、>、/ 为<、>、&#47。
XML注入
解码后转义<、>、/ 为<、>、&#47。
JSON注入
解码后转义’、”、、{、}、[、]为’、”、\、{、}、[、]。
HTTP参数注入
解码后转义&为%26
表3-2 常见安全威胁输入验证方法
3.2 文件上传的输入验证
文件上传时,如果验证不当,则很可能被用于上传恶意文件,也就是说,服务器以及内部网络可能完全沦陷。一般地,需对上传文件执行如下检查:
(1) 文件类型:最好使用endWith检查上传文件名中的文件类型。
(2) 文件头:检查二进制文件的文件头是否为白名单文件类型的文件头。
(3) 文件格式:检查文件的格式是否为白名单文件类型的格式。

以上只是简单总结WEB应用常见安全威胁的一般输入验证方法,在具体的项目开发过程中,还需要有针对性的调整验证策略。希望此文能给各位开发、测试人员以及白帽子们有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值