Pro*_*Pro 3 java xss cross-site esapi fortify
我正在我们的代码中主要在JSPS中修复跨站点脚本问题.
以下是原始代码
//scriplet code
<% String userId = request.getParameter("sid");
...%>
Run Code Online (Sandbox Code Playgroud)
他们拥有相同的Jsp
<input type = hidden name = "userID" value = "<%= userId %>" />
Run Code Online (Sandbox Code Playgroud)
我已经进行了更改,在lib和ESAPI.properties中包含esapi-2.1.0.jar,在classpath中包含validation.properties.然后在下面更改scriplet代码以修复上面的代码
//scriplet code
<% String userId = ESAPI.encoder().encodeForHTML(request.getParameter("sid"));
...%>
Run Code Online (Sandbox Code Playgroud)
我认为这可以解决问题但是当我使用Fortify扫描我的代码时,这些行再次突出显示为有XSS问题.如果你们对如何处理这个问题有任何想法,请帮忙.谢谢.
-------更新
非常感谢@avgvstvs.这是非常有见地的.Follwd指导方针,不确定我是不是很想念.代码 -
String userSID=ESAPI.encoder().encodeForHTMLAttribute(request.getHeader("janus_sid")); session.setAttribute("username",userSID);<input type=hidden name="USERNAME" value="<%= userSID %>"
Run Code Online (Sandbox Code Playgroud)
对于另一个varibale调试,下面是用法
String debugFlag = ESAPI.encoder().encodeForJavaScript(request.getParameter("debug"));var debugFlag = "<%= debugFlag%>";if(debugFlag == "y"){
document.title= title + " (" + host + ")";
defaultAppTitle = title + " (" + host + ")";
}
Run Code Online (Sandbox Code Playgroud)
最新的Fortify扫描仍然将它们列为漏洞:-(
你需要问的第一个问题应该是"我将这个值交给了什么代码解释器?"
不幸的是,防止XSS不是基于配方的任务,从它的外观来看 - 你的应用程序正在使用scriptlet,除了糟糕的Java实践之外,使Fortify等静态代码扫描工具更难以为你提供准确的结果.JSP在运行时编译,但Fortify仅扫描源.您应该注意到将来的任务/故事应该归档到JSTL的重构脚本 - 您将在以后感谢我.那么你可以使用esapi taglibs来处理这些用例.Fortify可以很好地扫描纯Java代码,而taglibs可以帮助你.
ESAPI.encoder().encodeForHTML(userId)只会在有问题的变量放在标签之间的用例中保护您免受XSS的侵害,例如<span><%= userId %></span> 您不具备这种情况.
ESAPI.encoder().encodeForHTMLAttribute(userId)是你想要的特定的,狭隘的用例.这是因为转义规则在Html属性中与在标记中放置的数据不同.这应该可以解决你的问题.
如果该值将由JavaScript专门使用,那么您需要 ESAPI.encoder().encodeForJavaScript(userId)
如果该值将是可渲染的,则HTML将被发送到javascript函数,该函数将呈现您的标记,就像element.innerHTML = “<HTML> Tags and markup”;您想要的那样<%=Encoder.encodeForJS(Encoder.encodeForHTML(userId))%>
这只是一些例子,这里还有一些例子- 但我的答案最重要的是:你需要知道应用程序中每个变量的完整数据流,并始终编码适当的输出上下文.在安全领域,"上下文"意味着"数据正在传递给新的代码解释器".如果你很好地实现这种理解,你将不再需要Fortify!:-)
====增加了复杂性====
在您的评论中,您注意到该值后来被JavaScript使用.因此,在这种情况下,正确的解决方案可能是分叉两个不同的变量,每个变量都设置为正确的编码.对于HTML属性案例:
userId
对于Javascript案例:
ESAPI.encoder().encodeForHTML(userId)
然后适当地使用这些值.如果您使用了JSTL/taglibs,则可以在正确的位置使用正确的esapi taglib,而不是分成两个单独的scriptlet变量.
===还有一件事===
来自对OP的评论:
我们有一个初始的scriptlet声明:
<span><%= userId %></span>
它稍后在javascript函数中使用:
ESAPI.encoder().encodeForHTMLAttribute(userId)
只是要指出,如上所述,ESAPI.encoder().encodeForJavaScript(userId)变量在初始化时停止为原始文本.实际上,javascript的编码变为:
String escapedHtmlUserId = ESAPI.encoder().encodeForHTMLAttribute(userId);
Run Code Online (Sandbox Code Playgroud)
如果javascript将使用*.innerHTML()或*.outerHTML()呈现HTML,这很好.否则,请注意输入已从其原始状态更改.
另外,请注意一些JavaScript可以撤消您已完成的操作,并确保您的JavaScript没有做类似的事情.
==========更多添加代码,更多问题========
所以我们已经跟踪了所有的数据路径,我们已经仔细检查过我们的JSP没有被包含在一个不同的JSP中,这个JSP为我们引入了新的上下文来防范,在这一点上我闻到了"误报,"但如果我是你,我会联系惠普支持并提出错误的问题.除非我能够访问完整的源代码,否则我不太了解您的应用程序的具体内容对您真正有用.因为你正在处理scriptlet - Fortify无法跟踪从变量实例化到最终输出的完整数据路径,所以它很快就会失败,所以它至少可以警告你到目前为止发现了什么.
谢谢你的帮助.最后找出了一个防止XSS问题并通过Fortify静态代码分析的解决方案.我已经将ESAPI与Anitsamy库一起使用了.以下是所需的3个主要更改.
实施Anitsamy过滤器
添加新的过滤器并覆盖请求方法getParameter,getParameterValues以去除请求中的任何可疑标记.过滤器加载策略文件,我们在其中定义规则
一个.需要从请求中删除的标签(标签等)
湾 常用属性的正则表达式,如href,align等.
过滤器的实现示例在http://barrypitman.com/2011/04/14/using-input-validation-XSS/
使用ESAPI库执行输入验证
String reportName = request.getParameter("reportName");
ESAPI.validator().getValidInput("Report Name",
reportName, "ReportNamePattern", 100, false);
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,
执行输出编码
正如@avgvstvs所指出的,输出编码也是必须的.
如果要在HTML中使用reportName字段,则下面是如何编码
<tr> <th> Report : <%=ESAPI.encoder().encodeForHTML(reportName)%> </th> </tr>
Run Code Online (Sandbox Code Playgroud)
如果要在javascript代码中使用reportName字段,则下面是如何编码
var reportName = "<%= ESAPI.encoder().encodeForJavaScript(reportName)%>";
Run Code Online (Sandbox Code Playgroud)
如果要在HTML属性中使用reportName字段,则下面是如何编码
<input type=hidden name="USERNAME" value="<%=ESAPI.encoder().encodeForHTMLAttribute
(reportName)%>"/>
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
19240 次 |
| 最近记录: |