快捷搜索:   nginx

抵御跨站脚本攻击 关注上下文转义功能

自动转义主要是为一般用途的模板系统开发的,也就是那些不完全清楚其运行内容的结构和编程语言的模板系统。这些模板系统通常能够为web应用程序提供最低限度的支持,可能仅限于一些基本的转义功能,开发者可以利用这些基本的转义功能帮助转义返回到web应用程序的不安全内容。那些具有一定规模和复杂度的web应用程序使用这些模板系统可能会增加XSS攻击的风险,为什么会这样呢?请参考下面的简化模板,这个模板中双大括号{{和}}中间的占位符(变量)被运行内容取代,而这是不安全的。

<body>
  <span style="color:{{USER_COLOR}};">
    Hello {{USERNAME}}, view your <a href="{{USER_ACCOUNT_URL}}">Account</a>.
  </span>
  <script>
    var id = {{USER_ID}}; // some code using id, say:
    // alert("Your user ID is: " + id);
  </script>
</body>

  在这个模板中,使用了4个变量

  USER_NAME 中被插入的是普通HTML文本,因此可以通过HTML转义进行安全转义。

  USER_ACCOUNT_URL被插入的是HTML属性(URL),因此除了HTML转义外,还需要验证URL方案(文本和图片等)是安全的。通过只允许安全白名单列表的URL方案,可以避免javascript: pseudo-URLs,单靠HTML转义使不能抵御的。

  USER_COLOR 被插入的是CSS范围内,因此需要一个能同时抵御脚本和其他CSS中的危险架构(如那些expression() 或者url()中存在的危险结构等)的转义。

  USER_ID 被插入的是Javascript变量,可能是没有位于引号中的数字,因此需要一种迫使其为数字的转义(通常Javascript-escape功能没有这个功能),否则可能会导致任意js执行程序。其他变量也可能被强迫转化为其他数字类型,包括数组和对象等。

  这些变量的插入都要求不同的转义方法并将导致不同的XSS攻击。在上面的例子中,我们排除了很多大家可能感兴趣的情况,如风格标签、HTML属性(如onmouseover)以及对是否位于引号内的属性值问题等。

  Auto-Escape

  上面的例子表明,必须正确理解插入变量的内容,并选择安全合适的转义功能。对于更大规模和更复杂的web应用程序,主要有以下两个XSS相关的问题:

  1. 开发者忘记向某个变量运用转义功能

  2. 开发者为插入的变量运用了错误的转义功能

  考虑到大型web应用程序模板和可能存在的不信任内容的数量之多,适当的转义过程变得很复杂并且容易出错,并且从安全测试角度来看,很难执行有效的审计。而Auto-Escape就能解决开发者和模板系统存在的复杂性问题,从而减少随之而来的跨站脚本攻击威胁。

  部署问题

  Auto-Escape功能设计目的在于使模板系统web应用程序的上下文感知,从而能够自动运用合适的转义功能,主要通过以下三个步骤来实现:

  1. 首先需要确定可能返回不信任内容的不同的context,并为每个context提供合适的转义功能。例如,我们并不知道需要支持HTML标签名称自身内的变量插入(而不是HTML属性),所以我们没有提供任何支持,加上其他因素的作用,包括现有转义功能和向后兼容性的有效性等,其结果是,某一部分工作需要依赖于模板系统的。

  2. 我们开发自身的解析器来解析HTML和Javascript模板,这种解析器能够查询必要的信息内容以进行适当的转义。该解析器是从性能角度考虑的,并在流模式运行,其设计目的在于简化程序,因为浏览器可能不会那么严格。

  3. 我们向解析过程加入一个额外的步骤,而模板系统已经开始执行变量。这个步骤主要是激活HTML/Javascript解析器,查询每种变量的context,然后将转义规则运用于每个变量使用的转义功能。根据模板系统的不同,这个步骤可能尽在首次使用模板的时候使用。

  这个简单的机制表明,其实有些变量是安全的,不需要被转义的,这种方法用于已经通过源代码的其他方式转义的变量或者包含信任标记的变量等。

  现状

  C++Google Ctemplate和ClearSilver模板系统中都包含Auto-Escape功能,前者已经发布一段时间了,并且而在继续开发,后者预计很快也将发布,这个功能将帮助更多人抵御跨站脚本攻击。

顶(0)
踩(0)

您可能还会对下面的文章感兴趣:

最新评论