检索到的数据库数据上的跨脚本错误

Cross scripting error on the Retrieved Database data

我在执行更新后的语句中看到一个跨脚本注入错误。我如何清理输出以消除跨脚本错误.. 我有一个简单的代码片段,它使用 PreparedStatement 来 运行 a select 和 returns 在前端 GUI 屏幕上检索到的值。

XSS漏洞消息:"The tainted data originated from an earlier call to java.sql.ResultSetMetaData.getColumnName. "

Java代码:

        Connection conn = null;
        Statement stmt = null;
        PreparedStatement pstmt = null;
        try {
            List alist= new ArrayList();
            pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
            int count = rs.getMetaData().getColumnCount();
            for (int i = 1; i <= count; i++) {
                 alist.add(rs.getMetaData().getColumnName(i))   //Flaw seems to point to this.
            }

        }catch(Exception e){
        //close connections
        }
        return alist;

完整的 Veracode 缺陷: 攻击向量: javax.servlet.jsp.JspWriter.print

模块数受影响:1

说明: 对 javax.servlet.jsp.JspWriter.print() 的调用包含跨站点脚本 (XSS) 漏洞。该应用程序使用不受信任的输入填充 HTTP 响应,允许攻击者嵌入恶意内容,例如 Javascript 代码,这些代码将在受害者浏览器的上下文中执行。 XSS 漏洞通常被用来窃取或操纵 cookie、修改内容的呈现以及破坏机密信息,并且会定期发现新的攻击向量。 print() 的第一个参数包含来自变量 getHtml() 的污染数据。受污染的数据源自之前对 java.sql.ResultSetMetaData.getColumnName 的调用。受污染的数据被定向到 javax.servlet.jsp.JspWriter.

返回的输出流中

我不知道为什么 ResultSetMetaData 对象调用 servlet 方法,但如果我理解正确的话,它用于在 servlet 中打印某些内容。但是因为你 ResultSetMetaData 中的所有数据都来自你数据库的元数据(不可能包括 java 脚本代码或其他 XSS 风险),所以在这种情况下应该保存。

ResultSetMetaData 是常用的 class(并且使用了很长时间)所以我真的不认为这是当前 java 版本中的问题。

所以我不确定如何解决这个问题,但我很确定这不是问题,因为不可能添加任何恶意软件代码(java脚本或 sql 注入代码)在你的数据库的元数据中。

所以,我终于能够找出问题所在。

我的查询是:

SELECT COLUMN_A, COLUMN_A||'-'||COLUMN_B FROM SOME_TABLE WHERE COLUMN_C IS NULL;

我做了一些事情...

1) 为我的专栏添加别名并使用 rs.getMetaData().getcolumnlabel(i) 而不是 rs.getMetaData().getColumnName(i)。这确保从输出结果集名称中消除管道或连字符。

2) 在传递给准备语句的变量上使用 OWASP 的 ESAPI.encoder().encodeForHTML(unsafeString) 而不是使用 Encode.forHtml(escapeHtml)StringEscapeUtils.escapeHtml(escapeHtml)

|| 的输出行为和 - 当通过各种转义函数传递它们时。 输入:String unsafeString ="<'HELLO'-||>";

输出:

Encode.forHtml(unsafeString)&lt;&#39;HELLO&#39;-||&gt; StringEscapeUtils.escapeHtml(unsafeString)&lt;'HELLO'-||&gt; ESAPI.encoder().encodeForHTML(unsafeString)&lt;&#x27;HELLO&#x27;-&#x7c;&#x7c;&gt; ESAPI.encoder().decodeForHTML(safeString from above line)is <'HELLO'-||>

如果将输出发送到 jsp 以在 html 上渲染,则您不必执行 decodeStep..