BY白羊 2025-06-24 16:05 采纳率: 14.3%
浏览 8

CNAS代码扫描出使用未经验证的输入数据构建 Web 页面缺陷

CNAS_33 跨站脚本缺陷

应该是writeResponseBody方法写入数据时需要先处理一下,主要针对于PDF二进制字节流写入数据时的处理,求各位指点怎么处理可以在代码扫描时,扫不出问题

  • 缺陷详细信息描述
    缺陷详细信息
    缺陷名称:CNAS_33 跨站脚本
    缺陷详解:
    使用未经验证的输入数据构建 Web 页面。
    缺陷说明: 在第(638)行将来自外界的值[body]输出,如果其中包含元字符或源代码中的值,那么 Web 浏览器就会像显示 HTTP 响应那样执行代码,攻击者可以创建恶意的 URL,然后采用电子邮件或社交工程的欺骗手段诱使受害者访问此 URL 的链接,从而将恶意内容带到受害者电脑中。
    代码片段:
    636 private static void writeResponseBody(HttpServletResponse response, byte[] body) throws IOException {
    637 try (OutputStream outputStream = response.getOutputStream()) {
    638 outputStream.write(body);
    639 outputStream.flush();
    640 }

  • 代码展示

    public static void handleResponsePdf2(HttpServletResponse response, ResponseEntity<byte[]> responseEntity, long forwardStartTime) throws IOException {
        // 设置响应头
        HttpHeaders headers = responseEntity.getHeaders();
        headers.forEach((name, values) -> values.forEach(value -> response.addHeader(name, value)));
 
        // 根据内容类型设置合适的MediaType
        String contentType = headers.getContentType() != null ? headers.getContentType().toString() : null;
        byte[] body = Objects.requireNonNull(responseEntity.getBody());
 
        if (MediaType.APPLICATION_PDF_VALUE.equalsIgnoreCase(contentType)) {
            response.setContentType(MediaType.APPLICATION_PDF_VALUE);
            writeResponseBody(response, body);
        } else if ("text/html".equalsIgnoreCase(contentType)
                || "text/css".equalsIgnoreCase(contentType)
                || "text/javascript".equalsIgnoreCase(contentType)
                || "application/javascript".equalsIgnoreCase(contentType)) {
 
            // 对于文本类型的内容,进行清理或转义
            response.setCharacterEncoding("UTF-8");
            String content = new String(body, StandardCharsets.UTF_8);
            // 进行 HTML 转义
            String sanitizedContent = HtmlUtils.htmlEscape(content);
            // 设置为纯文本,防止浏览器解析脚本
            response.setContentType("text/plain;charset=UTF-8");
 
            try (OutputStream outputStream = response.getOutputStream()) {
                outputStream.write(sanitizedContent.getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
            }
        }else {
            // 对于其他类型的内容,直接写入
            response.setContentType("application/octet-stream");
            writeResponseBody(response, body);
        }
 
        // 设置响应状态码
        HttpStatus statusCode = responseEntity.getStatusCode();
        if (statusCode != null) {
            response.setStatus(statusCode.value());
        } else {
            response.setStatus(200); // 默认状态码
        }
    }
 
    /**
     * 将字节数组写入响应体
     */
    private static void writeResponseBody(HttpServletResponse response, byte[] body) throws IOException {
        try (OutputStream outputStream = response.getOutputStream()) {
            outputStream.write(body);
            outputStream.flush();
        }
    }
 

  • 写回答

5条回答 默认 最新

  • 阿里嘎多学长 2025-06-24 16:05
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    CNAS代码扫描出使用未经验证的输入数据构建 Web 页面缺陷

    你遇到的问题是 CNAS_33 跨站脚本缺陷,具体来说是指在 writeResponseBody 方法中写入数据时,需要对 PDF 二进制字节流进行处理,以避免在代码扫描时扫出问题。

    解决方案:

    1. 使用 StringEscapeUtils.escapeHtml() 方法对 PDF 字节流进行 HTML 转义,以避免在写入响应体时注入恶意代码。
    2. 使用 Base64 编码对 PDF 字节流进行编码,以避免在写入响应体时注入恶意代码。
    3. 在 writeResponseBody 方法中使用 ResponseWriter 对象来写入响应体,而不是直接写入字节流。

    示例代码:

    import org.apache.commons.lang3.StringEscapeUtils;
    import org.springframework.http.HttpOutputMessage;
    import org.springframework.http.server.ServletServerHttpResponse;
    
    public void writeResponseBody(HttpOutputMessage httpOutputMessage) {
        ServletServerHttpResponse response = (ServletServerHttpResponse) httpOutputMessage.getResponse();
        byte[] pdfBytes = ...; // 获取 PDF 字节流
        String pdfBase64 = Base64.encodeBase64String(pdfBytes);
        response.getWriter().write(StringEscapeUtils.escapeHtml(pdfBase64));
    }
    

    通过这些方法,可以避免在代码扫描时扫出问题,并且确保响应体中的数据安全。

    评论

报告相同问题?

问题事件

  • 创建了问题 6月24日