Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java XSS预防的ESAPI不起作用_Java_Xss_Fortify_Cross Site_Esapi - Fatal编程技术网

Java XSS预防的ESAPI不起作用

Java XSS预防的ESAPI不起作用,java,xss,fortify,cross-site,esapi,Java,Xss,Fortify,Cross Site,Esapi,我主要在JSP中解决代码中的跨站点脚本问题 下面是原始代码 //scriplet code <% String userId = request.getParameter("sid"); ...%> //scriplet代码 在同一个Jsp中,它们 <input type = hidden name = "userID" value = "<%= userId %>" /> 我做了一些修改,在lib中包含了esapi-2

我主要在JSP中解决代码中的跨站点脚本问题

下面是原始代码

 //scriplet code
    <% String userId = request.getParameter("sid"); 
    ...%>
//scriplet代码
在同一个Jsp中,它们

     <input type = hidden name = "userID" value = "<%= userId %>" />

我做了一些修改,在lib中包含了esapi-2.1.0.jar,在classpath中包含了esapi.properties、validation.properties。然后对scriplet代码进行以下更改以修复上述代码

      //scriplet code
    <% String userId = ESAPI.encoder().encodeForHTML(request.getParameter("sid")); 
    ...%>
//scriplet代码
我原以为这会解决这个问题,但当我使用Fortify扫描代码时,这些行再次突出显示为存在XSS问题。如果你们对如何处理这件事有任何想法,请帮忙。谢谢

-------更新

非常感谢@avgvstvs。这是非常有见地的。遵循指导原则,不确定我是否遗漏了什么。代码-

          String              userSID=ESAPI.encoder().encodeForHTMLAttribute(request.getHeader("janus_sid")); session.setAttribute("username",userSID);<input type=hidden name="USERNAME" value="<%= userSID %>"

String userSID=ESAPI.encoder().encodeForHTMLAttribute(request.getHeader(“janus_sid”);setAttribute(“用户名”,userSID) 您需要问的第一个问题应该是“我将此值传递给哪些代码解释器?”

不幸的是,防止XSS并不是一项基于配方的任务,而且从外观上看,您的应用程序使用的是Scriptlet,这使得像Fortify这样的静态代码扫描工具很难为您提供准确的结果。JSP在运行时编译,但Fortify只扫描源代码。您应该注意到,将来应该有任务/故事归档来将Scriptlet重构到JSTL——稍后您将为此感谢我。然后您可以将esapi标记库用于这些用例。Fortify在扫描纯Java代码方面做得很好,TagLib提供了这一点

  • ESAPI.encoder().encodeForHTML(userId)
    只会在有问题的变量将被放置在标记之间的用例中保护您免受XSS的攻击,例如
    您没有这种情况

  • ESAPI.encoder().encodeForHTMLAttribute(userId)
    是您在特定的狭义用例中所需要的。这是因为Html属性中的转义规则与放置在标记中的数据的转义规则不同。这应该能解决你眼前的问题

  • 如果该值将由JavaScript独占使用,则需要
    ESAPI.encoder().encodeForJavaScript(userId)

  • 如果该值将是可呈现的HTML,则发送到将呈现标记的javascript函数,如
    element.innerHTML=“Tags and markup”您想要

  • 这只是几个例子,但我的回答最重要的要点是:您需要知道应用程序中每个变量的完整数据流,并始终为适当的输出上下文编码。在安全领域,“上下文”的意思是“数据正在被传递给新的代码解释器。”如果你很好地实现了这种理解,你就不再需要加强了!:-)

    增加复杂性 在您的评论中,您注意到JavaScript稍后将使用该值。因此,在这种情况下,正确的解决方案可能是分叉两个不同的变量,每个变量都设置为正确的编码。对于HTML属性大小写:

    String escapedHtmlUserId = ESAPI.encoder().encodeForHTMLAttribute(userId);
    
    对于Javascript案例:

    String escapedJSUserId = ESAPI.encoder().encodeForJavaScript(userId);
    
    然后适当地使用这些值。如果使用JSTL/taglibs,您可以在正确的位置使用正确的esapi taglib,而不是拆分为两个单独的scriptlet变量

    还有一件事 从OP的评论中:

    我们有一个初始scriptlet声明:

    <% String userId = ESAPI.encoder().encodeForHTML(request.getParameter("sid")); 
    ...%>
    
    如果javascript将使用*.innerHTML()或*.outerHTML()呈现HTML,这是可以的。否则,只需注意输入已从原始状态更改

    另外,注意一些事实,并确保您的JavaScript没有做类似的事情

    ============更多添加的代码,更多问题========


    所以我们追踪了所有的数据路径,我们仔细检查了我们所讨论的JSP是否包含在另一个JSP中,该JSP为我们引入了新的上下文进行防御,在这一点上,我会闻到“误报”,但如果我是你,我会联系HP支持部门,并提出误报问题。我对你的应用程序的细节了解得不够,除非我有权访问完整的源代码,否则我不会在这里对你有更多的用处。因为您使用的是Scriptlet——Fortify可能无法跟踪从变量实例化到最终输出的完整数据路径,所以故障很快,因此它至少可以警告您“到目前为止”发现了什么。谢谢大家的帮助。最终找到了防止XSS问题并通过强化静态代码分析的解决方案。我已经将ESAPI与Anitsamy library一起使用。以下是所需的3个主要更改

  • 执行Anitsamy筛选器

    添加一个新的过滤器并覆盖请求方法getParameter、getParameterValues,以去除请求中的任何可疑标记。筛选器加载一个策略文件,我们在其中定义规则,如

    a。需要从请求中删除的标签(如标签等)

    b。用于诸如href、align等常见属性的正则表达式

  • 这里是实现过滤器的示例

  • 使用ESAPI库执行输入验证

     String reportName = request.getParameter("reportName");
     ESAPI.validator().getValidInput("Report Name", 
                                      reportName, "ReportNamePattern", 100, false);
    
    在上述代码中

  • “报告名称”是上下文
  • reportName是数据字段
  • ReportNamePattern是在ESAPI.properties中定义为Validator.ReportNamePattern=^[a-zA-Z]{1}[0-9]{6}$
  • 100是数据字段reportName的最大长度
  • false是一个表示不允许空值的标志
  • 执行输出编码
    正如@avgvstvs所指出的,输出编码也是必须的

    若要在HTML中使用reportName字段,下面是如何编码

    <tr> <th> Report :     <%=ESAPI.encoder().encodeForHTML(reportName)%> </th> </tr>
    
    <input type=hidden name="USERNAME" value="<%=ESAPI.encoder().encodeForHTMLAttribute
        (reportName)%>"/>       
    
    报告:
    
    若要在javascript代码中使用reportName字段,下面是如何编码

     var reportName = "<%= ESAPI.encoder().encodeForJavaScript(reportName)%>";
    
    var reportName=”“;
    
    如果要在H中使用reportName字段
    <tr> <th> Report :     <%=ESAPI.encoder().encodeForHTML(reportName)%> </th> </tr>
    
     var reportName = "<%= ESAPI.encoder().encodeForJavaScript(reportName)%>";
    
    <input type=hidden name="USERNAME" value="<%=ESAPI.encoder().encodeForHTMLAttribute
        (reportName)%>"/>