提问人:AngelsandDemons 提问时间:10/11/2011 最后编辑:Antti Haapala -- Слава УкраїніAngelsandDemons 更新时间:10/3/2019 访问量:49792
JSF 中的 CSRF、XSS 和 SQL 注入攻击防护
CSRF, XSS and SQL Injection attack prevention in JSF
问:
我有一个基于 JSF 构建的 Web 应用程序,将 MySQL 作为数据库。我已经在我的应用程序中实现了防止 CSRF 的代码。
现在,由于我的底层框架是 JSF,我想我不必处理 XSS 攻击,因为它已经由 处理了。我没有在任何视图页面中使用任何 JavaScript。即使我使用,我真的需要实现代码来防止 XSS 攻击吗?UIComponent
对于 DB,我们在所有 DB 交互中使用预处理语句和存储过程。
还有什么需要处理来防止这 3 种常见攻击吗? 我已经浏览了OWASP网站和他们的备忘单。
我是否需要处理任何其他潜在的攻击媒介?
答:
我没有在任何视图页面中使用任何 JavaScript。即使我使用,我也确实需要实现代码来绕过 XSS 攻击。
即使您在页面中不使用 JavaScript,也可能容易受到 XSS 的攻击。当您合并攻击者控制的内容而未对其进行正确编码时,就会发生 XSS。
任何时候你做类似的事情
response.write("<b>" + x + "</b>")
如果攻击者可能导致包含包含 JavaScript 的 HTML,则容易受到 XSS 的攻击。x
解决方案通常是不编写大量代码。通常,解决方案是对攻击者控制的任何其他值进行编码,然后再将它们包含在生成的 HTML 中。$x
response.write("<b>" + escapePlainTextToHtml(x) + "</b>")
过滤或清理输入有助于提供额外的保护层。
<shameless-plug>
您还可以使用自动编码输出的模板语言来防止 XSS。
Closure Template 就是这样一种 Java 选项。
上下文自动转义的工作原理是增强闭包模板,以根据每个动态值出现的上下文正确编码每个动态值,从而防御攻击者控制的值中的 XSS 漏洞。
编辑
由于您使用的是 JSF,因此应该阅读 JSF 中的 XSS 缓解:
转义输出文本
<h:outputText/>
默认情况下,转义属性设置为 True。通过使用此标记显示输出,您可以缓解大多数 XSS 漏洞。<h:outputLabel/>
SeamTextParser 和
<s:formattedText/>
如果你想允许用户使用一些基本的 html 标签来自定义他们的输入,JBoss Seam 提供了一个标签,允许用户指定的一些基本的 html 标签和样式。
<s:formattedText/>
评论
response.write(foo)
XSS的
JSF 被设计为具有内置的 XSS 防护。您可以使用任何 JSF 组件安全地重新显示所有用户控制的输入(请求标头(包括 cookie!)、请求参数(也包括保存在 DB 中的参数!)和请求正文(上传的文本文件等)。
<h:outputText value="#{user.name}" />
<h:outputText value="#{user.name}" escape="true" />
<h:inputText value="#{user.name}" />
etc...
请注意,当您在 Facelets 上使用 JSF 2.0 时,您可以在模板文本中使用 EL,如下所示:
<p>Welcome, #{user.name}</p>
这也将被隐式转义。你不一定需要这里。<h:outputText>
仅当您使用以下命令显式取消转义用户控制的输入时:escape="false"
<h:outputText value="#{user.name}" escape="false" />
那么你就有一个潜在的 XSS 攻击漏洞!
如果您想将用户控制的输入重新显示为 HTML,其中您只想允许 HTML 标记的特定子集,如 、 、 等,那么您需要通过白名单清理输入。HTML 解析器 Jsoup 在这方面非常有用。<b>
<i>
<u>
itemLabelEscaped
Mojarra < 2.2.6 中的错误
2.2.6 之前的旧 Mojarra 版本存在一个错误,即当提供 via 而不是 or as 值时,错误地将标签呈现为未转义(问题 3143)。换言之,如果您通过 将用户控制的数据重新显示为项目标签,那么您就有一个潜在的 XSS 漏洞。如果升级到至少 Mojarra 2.2.6 不是一个选项,那么您需要显式设置 attribute to 以防止这种情况发生。<f:selectItems itemLabel>
List<T>
<f:selectItems var>
List<SelectItem>
SelectItem[]
List<T>
itemLabelEscaped
true
<f:selectItems value="#{bean.entities}" var="entity" itemValue="#{entity}"
itemLabel="#{entity.someUserControlledProperty}" itemLabelEscaped="true" />
CSRF的
JSF 2.x 在使用服务器端状态保存时,已经以隐藏字段的形式内置了 CSRF 预防。在 JSF 1.x 中,这个值非常弱,而且太容易预测了(实际上它从来都不是用来预防 CSRF 的)。在 JSF 2.0 中,通过使用长而强大的自动生成值而不是相当可预测的序列值,对此进行了改进,从而使其成为一种强大的 CSRF 预防。javax.faces.ViewState
在 JSF 2.2 中,这甚至得到了进一步的改进,使其成为 JSF 规范的必需部分,以及一个可配置的 AES 密钥来加密客户端状态,以防启用客户端状态保存。另请参阅 JSF 规范问题 869 和在其他会话中重用 ViewState 值 (CSRF)。JSF 2.2 中的新功能是 <protected-views>
对 GET 请求的 CSRF 保护。
只有当您使用无状态视图时,或者应用程序中的某个位置存在 XSS 攻击漏洞时,您才有一个潜在的 CSRF 攻击漏洞。<f:view transient="true">
SQL注入
这不是 JSF 的责任。如何防止这种情况取决于你使用的持久性 API(原始 JDBC、现代 JPA 或良好的 Hibernate),但归根结底,你永远不应该像这样将用户控制的输入连接到 SQL 字符串中
String sql = "SELECT * FROM user WHERE username = '" + username + "' AND password = md5(" + password + ")";
String jpql = "SELECT u FROM User u WHERE u.username = '" + username + "' AND u.password = md5('" + password + "')";
想象一下,如果最终用户选择以下名称,会发生什么情况:
x'; DROP TABLE user; --
如果适用,应始终使用参数化查询。
String sql = "SELECT * FROM user WHERE username = ? AND password = md5(?)";
String jpql = "SELECT u FROM User u WHERE u.username = ?1 AND u.password = md5(?2)";
在纯 JDBC 中,您需要使用 PreparedStatement
来填充参数值,而在 JPA(和 Hibernate)中,Query
对象也为此提供了 setter。
评论
escape="false"
String safe = Jsoup.clean(unsafe, Whitelist.basic());
<s:token>
the current Oracle JDBC driver escapes input for prepared statements and parameterized stored procedures.
当使用未转义的值(例如来自html文本编辑器)时,您可能会受到讨厌的XSS攻击。在这种情况下,我使用JSF转换器,它使用Jsoup从文本中删除javascript,使HTML保持不变。转换器也可用于清理用户输入。你可以像这样使用它:<h:outputText escape="false">
<h:outputText value="{bean.value}" escape="false" converter="htmlSanitizingConverter"/>
而转换器本身:
/**
* Prevents from XSS attack if output text is not escaped.
*/
@FacesConverter("htmlSanitizingConverter")
public class HtmlSanitizingConverter implements Converter {
private static final Whitelist JSOUP_WHITELIST = Whitelist.relaxed()
.preserveRelativeLinks(true)
.addAttributes(":all","style");
/*
Optionally - add support for hyperlinks and base64 encoded images.
.addTags("img")
.addAttributes("img", "height", "src", "width")
.addAttributes("a", "href")
.addProtocols("img", "src", "http", "https", "data");
*/
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
return (submittedValue != null) ? Jsoup.clean(submittedValue, JSOUP_WHITELIST) : null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return (value != null) ? Jsoup.clean(value.toString(), JSOUP_WHITELIST) : "";
}
}
注意:
当您将 JSF 与 PrimeFaces 一起使用时,请注意 - 默认情况下,旧版本(6.2 之前)不会清理用户输入。<p:textEditor>
评论
p:textEditor
p:textEditor
下一个:终极清洁/安全功能
评论