【发布时间】:2015-02-18 02:31:00
【问题描述】:
在play framework 2 文档中,我只能找到方法@Html 来转义html。 其他情况如何处理?
【问题讨论】:
-
这是一个非常广泛的问题。您应该在此处说明您的具体问题以及您的尝试。
标签: playframework xss
在play framework 2 文档中,我只能找到方法@Html 来转义html。 其他情况如何处理?
【问题讨论】:
标签: playframework xss
一般来说,Play Framework 在使用内置模板时默认提供了很好的 XSS 保护(请参阅文档中的 Escaping 部分)。 @Html 方法则相反,禁用转义以呈现原始的、受信任的 HTML。
【讨论】:
我在我的 Web 应用程序中创建了一个简单的特征 XssFilter,并在我的后端使用它,如下所示:
import java.util.regex.Pattern;
trait XssFilter {
def filter(input: String): String = {
var value: String = input;
if (value != null) {
// NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
// avoid encoded attacks.
// value = ESAPI.encoder().canonicalize(value);
// Avoid null characters
value = value.replaceAll("", "");
// Avoid anything between script tags
var scriptPattern: Pattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE)
value = scriptPattern.matcher(value).replaceAll("");
// Avoid anything in a src='...' type of expression
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Remove any lonesome </script> tag
scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Remove any lonesome <script ...> tag
scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid eval(...) expressions
scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid expression(...) expressions
scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid javascript:... expressions
scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid vbscript:... expressions
scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
value = scriptPattern.matcher(value).replaceAll("");
// Avoid onload= expressions
scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
value = scriptPattern.matcher(value).replaceAll("");
}
return value;
}
}
并像这样使用:
case class FormHelper(requestBody: AnyContent) extends XssFilter {
def getAsFormUrlEncoded(key: String): String = {
var ret = ""
requestBody.asFormUrlEncoded.get.get(key) match {
case None => {
requestBody.asFormUrlEncoded.get.get(key + "[]") match {
case None => ret = ""
case s: Some[Seq[String]] => {
ret = s.get.mkString(",")
}
}
}
case s: Some[Seq[String]] => ret = s.get.head
}
filter(ret)
//requestBody.asFormUrlEncoded.get(key)(0)
}
}
最后在你的控制器代码中:
val fh = FormHelper(request.body)
val transId: String = fh.getAsFormUrlEncoded("transId")
【讨论】:
根据 Play Framework 1.2.4 文档:您可以使用标志
future.escapeInTemplates=true ,在 application.conf 设置中帮助你阻止跨站脚本攻击。
来自文档:
强烈建议启用此选项。当您确实需要在模板中插入未转义的 HTML 时,可以使用字符串上的 raw() 方法来完成。但是,如果字符串来自用户输入,则需要确保首先对其进行清理。 在清理用户输入时,总是更喜欢白名单(只允许安全标签列表)而不是黑名单(禁止不安全标签列表并允许所有其他标签)。
【讨论】: