如何在下载文件时修复 veracode CWE-80 XSS 问题?

问题描述

以下是我现有的 Java 基础标准代码,如您所见,我只是使用输出流下载文件

我只使用请求参数从标题获取浏览器详细信息以生成文件名,然后我再次对其进行解码。

所以现在我不明白下面的代码是如何

outputStream.write(data,read);

会导致 XSS 问题吗?

那么,由于我的输出一个简单的文件,我该如何解决这个问题?

        OutputStream outputStream = httpResponse.getoutputStream();
        InputStream fileInputStream = generateInputStreamObj(user,attachmentObj,false,httpRequest,servletContext,ipAddress);

        String userAgent = httpRequest.getHeader("User-Agent");
        String encodedFileName = generateFileName(userAgent,attachmentObj);

        int downloadBufferSize = Integer.parseInt(CacheManagement.getInstance().getSystemPropertyByAlias().get("DOWNLOAD_BUFFER_SIZE").getPropertyValue());

        httpResponse.setContentType("application/x-download");
        httpResponse.setHeader("Content-Length",String.valueOf(attachmentObj.getDocumentSize()));
        httpResponse.setHeader("Content-disposition","attachment; filename=\"" + encodedFileName + "\"");
        httpResponse.setBufferSize(downloadBufferSize);

        bufferInputStream = new BufferedInputStream(fileInputStream);
        byte[] data = new byte[downloadBufferSize];
        int readed = 0;
        while ((readed = bufferInputStream.read(data)) != -1)
        {
            outputStream.write(data,readed);
        }

我检查了堆栈溢出和 Veracode 的答案,但对我没有帮助。

** 如果您将此问题设为减号,请发表评论。我查看了 stackoverflow 和 veracode 社区的答案,但没有回答我的问题。

解决方法

Veracode 可能看到您没有进行任何编码并认为这可能是 XSS 问题。

然而,在这种情况下,不需要编码,因为它是下载文件,而不是生成 HTML 数据。结果不会被浏览器解释为带有这些内容类型和标题的 HTML,因此这是一个误报。

,

转换

< → &lt;

> → &gt;

' → &#39;

" → &quot;

& → &amp;

代码:

public static final String stringToHtmlString(String s){
   StringBuffer sb = new StringBuffer();
   int n = s.length();
   for (int i = 0; i < n; i++) {
      char c = s.charAt(i);
      switch (c) {
         case '<': sb.append("&lt;"); break;
         case '>': sb.append("&gt;"); break;
         case '&': sb.append("&amp;"); break;
         case '"': sb.append("&quot;"); break;
         default:  sb.append(c); break;
      }
   }
   return sb.toString();
}