JSF中的CSRF、XSS和SQL注入攻击预防
我有一个基于JSF构建的web应用程序,MySQL作为DB。我已经在我的应用程序中实现了防止CSRF的代码 既然我的底层框架是JSF,我想我不必处理XSS攻击,因为它已经被JSF中的CSRF、XSS和SQL注入攻击预防,jsf,xss,sql-injection,csrf,owasp,Jsf,Xss,Sql Injection,Csrf,Owasp,我有一个基于JSF构建的web应用程序,MySQL作为DB。我已经在我的应用程序中实现了防止CSRF的代码 既然我的底层框架是JSF,我想我不必处理XSS攻击,因为它已经被UIComponent处理过了。我没有在任何视图页面中使用任何JavaScript。即使我使用了,我真的需要实现代码来防止XSS攻击吗 对于DB,我们在所有DB交互中使用准备好的语句和存储过程 为了防止这3种常见的攻击,还需要处理其他任何事情吗? 我已经通过该网站和他们的 我需要处理任何其他潜在的攻击载体吗 我没有在任何视图页
UIComponent
处理过了。我没有在任何视图页面中使用任何JavaScript。即使我使用了,我真的需要实现代码来防止XSS攻击吗
对于DB,我们在所有DB交互中使用准备好的语句和存储过程
为了防止这3种常见的攻击,还需要处理其他任何事情吗?
我已经通过该网站和他们的
我需要处理任何其他潜在的攻击载体吗
我没有在任何视图页面中使用任何JavaScript。即使我使用do,我也确实需要实现代码来绕过XSS攻击
即使在页面中不使用JavaScript,您也可能容易受到XSS的攻击。当您合并由攻击者控制的内容而未对其进行正确编码时,就会发生XSS
任何时候你做类似的事情
response.write("<b>" + x + "</b>")
过滤或消毒输入有助于提供额外的保护层
您还可以使用自动编码输出的模板语言来防止XSS
是Java的一种选择
上下文自动转义通过增加闭包模板来根据出现的上下文对每个动态值进行正确编码,从而防御攻击者控制的值中的XSS漏洞
编辑
由于您使用的是JSF,您应该阅读以下内容:
转义输出文本
和
默认情况下,转义属性设置为True。通过使用此标记显示输出,您可以减轻大多数XSS漏洞
SeamTextParser和
如果您希望允许用户使用一些基本html标记来定制他们的输入,JBoss Seam提供了一个
标记,允许用户指定一些基本html标记和样式
XSS
JSF被设计为具有内置XSS预防功能。您可以使用任何JSF组件安全地重新显示所有用户控制的输入(请求头(包括cookie!)、请求参数(也包括保存在DB中的参数!)和请求正文(上传的文本文件等))
等
请注意,在Facelets上使用JSF 2.0时,可以在模板文本中使用EL,如下所示:
欢迎,#{user.name}
这也将被隐式转义。这里不一定需要
仅当使用escape=“false”
显式取消用户控制输入时:
那么你就有了一个潜在的XSS攻击漏洞
如果要将用户控制的输入重新显示为HTML,其中只允许HTML标记的特定子集,如
,
,
,等等,则需要通过白名单对输入进行清理。HTML解析器在这方面非常有用
itemLabelEscaped
Mojarra中的bug<2.2.6
2.2.6之前较旧的Mojarra版本存在一个缺陷,
通过
提供列表而不是列表
或选择项[]
作为值()时,
错误地将标签呈现为不可替换。换句话说,如果您正在通过列表
将用户控制的数据重新显示为项目标签,则可能存在XSS漏洞。如果升级到至少Mojarra 2.2.6不是一个选项,那么您需要显式地将itemLabelEscaped
属性设置为true
,以防止出现这种情况
CSRF
在使用服务器端状态保存时,JSF2.x已经在表单中的javax.faces.ViewState
隐藏字段中内置了CSRF预防。在JSF1.x中,这个值非常弱,而且太容易预测(实际上它从来没有打算作为CSRF预防)。在JSF2.0中,通过使用一个长而强的自动生成值而不是一个相当可预测的序列值,这一点得到了改进,从而使其成为一个健壮的CSRF预防
在JSF2.2中,如果启用了客户端状态保存,这甚至可以通过使其成为JSF规范的必需部分,以及用于加密客户端状态的可配置AES密钥来进一步改进。另见和。JSF2.2中的新功能是对GET请求的CSRF保护
只有当您使用的是
中的无状态视图,或者应用程序中存在XSS攻击漏洞时,才可能存在CSRF攻击漏洞
SQL注入
这不是JSF的责任。如何防止这种情况取决于您使用的持久化API(原始JDBC、现代JPA或良好的ol'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 + "')";
想象一下,如果最终用户选择以下名称,会发生什么情况:
如果适用,应始终使用参数化查询
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中,您需要使用它来填充参数值,而在JPA(和Hibernate)中,对象也提供了用于填充参数值的设置程序。当使用
和未替换的值(例如来自html文本编辑器)时,您将面临严重的XSS攻击。在这种情况下,我使用的是JSF转换器,它使用Jsoup从文本中删除javascript,而HTML保持不变。转换器也可用于净化用户输入。您可以这样使用它:
以及转换器本身:
/**
* 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之前)没有清理用户输入。@ankit,是否有一句话让您感到困惑?问题是我正在使用JSF,我想就像其他框架一样,它会自动生成HTML。所以我仍然不知道
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)";
/**
* 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) : "";
}
}