首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

安全编程 验证输入(2)

安全编程 验证输入(2)

本帖最后由 look_w 于 2018-4-19 12:23 编辑

电子邮件地址许多程序必须接收电子邮件地址, 但是处理所有可能的合法电子邮件地址(如 RFC 2882 和 822 所指定的)令人惊讶的困难。JeffreyFiedl 的用于检查电子邮件地址的“短”正则表达式有 4,724 个字符长,即使是这样还是没有包括所有的情况。不过,大多数的程序可以是非常严格的,只接收一个特别受限子集的电子邮件以正常地工作。在大多数情况下,只要程序可以接收正常的"name@domain"格式的因特网地址(像“”),拒绝像“JohnDoe <>”这个在技术上合法的地址是没问题的。Viega 和 Messier 2003年出版的书中有可以完成这项检查的子例程。
Cookies网络应用程序经常为重要的数据使用 cookie。如我以后将要讲到的那样,不要忘记用户可以任意地重新设置 cookie 的值和形式,这一点很重要。不过,有一个重要的验证窍门现在有必要一提。如果您接收一个 cookie 值,检查它的域值是不是您所期望的(比如,您的一个站点)。否则,一个(可能已经被击垮)相关的站点可能被插入到用于欺骗的 cookie 中。如果您对此关心,可以参考 IETF RFC 2965 ,可以得到关于这种攻击的详细说明(在 中有相关链接)。      
HTML有时候您的程序要从一个不信任的用户处得到数据并把它传给其他的用户。如果第二个用户的程序有可能被这些数据破坏掉,那么您有责任保护第二个用户。使用看起来可信任的中间媒介传输恶意数据的攻击被称为“交叉站点恶意内容”攻击。
这个问题对于网络应用来说尤其是一个难题,比如那些允许用户添加当场连续评述的社区"黑板"。在这种情况下,攻击者可以尝试添加包含恶意代码脚本、图片标签的 HTML 格式的评述;目的是让其他用户的浏览器运行在察看本文的时候去执行那些恶意的代码。由于攻击者通常是试图添加恶意的脚本,因些这种变化被称为"交叉站点脚本攻击"(XSS 攻击)。
通常来说避免这种攻击的最好的办法是验证您所接收的 HTML 没有包括这种恶意的脚本。同样,您要做的是把您所知道的安全的列出来,然后禁止其他。
通常,在 HTML 中您至少可以接收下面这些以及它们的结束标签:        
  • <p> (段落)
  • <b> (加粗)
  • <i> (斜体字)
  • <em> (强调)
  • <strong> (特别强调)
  • <pre> (预定义文本)
  • <br> (强制断行 -- 注意它不需要关闭标签)
记住 HTML 标签是不区分大小写的。除非您检查过了属性的类型和它的值,否则不要接收任何属性;有很多支持 Javascript 等的属性可能会给您的用户带来麻烦。
您当然可以扩展这个集合,但是要小心。特别需要注意的是任何让用户立即加载另一个文件的标签,比如 image 标签――那些标签非常适合 XSS 攻击。
另外一个问题是您需要确认攻击者无法任意打乱文件的其余部分,特别是,您要确保任何评述或者片段看起来不能像正式的内容。一个方法是保证任何 XML 或 HTML 命令完全对称(任何打开的都要关闭)。这在 XML 术语中称为"格式良好的"数据。如果您正在接收标准 HTML,您可能不需要为段落标记(<p>)做这些,因为它们不是对称的。
在许多情况下您可能要接收 <a> (超级链接),还可能需要属性“href”。如果您必须这样做,您必须要验证您链接到的 URI/URL――这是我们的下一个话题。        
URI/URL技术上讲,超文本链接可以是任何“统一资源标识符”(URI),不过现在大多数人只知道一种特定的 URI,那就是“统一资源定位符”(URL)。许多用户将盲目地点击指向一个URI 的超级链接,并假定不会因为显示它而带来麻烦。作为一个开发者,您的任务是确保用户的期望不会落空。
尽管 URI 提供了很大的灵活性,可是如果您接收到了一个来自攻击者的 URI,您需要在把它转给任何其他人之前检查它。攻击者可以在 URI 中加入很多古怪的东西来迷惑用户。例如,攻击者可以引入一些查询,而导致用户去做不愿去做的事情,并且他们可以让用户误以为是要浏览另一个网站而不是他们确实在访问的。 不幸的是,很难给出一个适用于所有情况的单一模式。不过,一个可以防止大多数攻击,同时可以允许大多数有用的链接通过的(对于公共的网站而言)最安全的模式是:        
^(http|ftp|https)://[-A-Za-z0-9._/]+$
一个更为复杂的模式是:
^(http|ftp|https)://[-A-Za-z0-9._]+(\/([A-Za-z0-9\-\_\.\!\~\*\'\(\)\%\?]+))*/?$
如果您的需要更复杂,您就需要更复杂的模式来检查数据;可以在我的书中(在 中列出了)查找一些其他方法。      
数据文件复杂的数据文件和数据结构通常由众多的小的组件构成。只需要把这个文件或者结构分解,并检查每一部分。如果这些组件之间的有特定的依赖关系,那就一并检查它们。在开始时,编写这些代码可能会有一点无聊,不过它对于可靠性确实有好处:如果您拒绝了那些非法数据,许多不可思议的问题马上就会消失。
结束语显然,有很多种不同的数据需要去检查。但是这些数据是在何处进入到您的程序的?答案在各种情况下不尽相同;实际上,您的程序可能会通过您所没有想到的途径得到攻击者的数据。我将在下一部分讨论这个问题。
返回列表