BY白羊 2025-06-24 15:52 采纳率: 14.3%
浏览 9
已结题

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

CNAS_33 跨站脚本缺陷

应该是writeResponseBody方法写入数据时需要先处理一下,求各位指点怎么处理可以在代码扫描时,扫不出问题

  • 缺陷详细信息描述
    缺陷详细信息
    缺陷名称: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();
        }
    }

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2025-06-24 15:52
    关注

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

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

    你遇到的问题是 CNAS_33 跨站脚本缺陷,指的是在 writeResponseBody 方法中写入数据时没有对输入数据进行验证,可能会导致攻击者注入恶意脚本。

    解决方案:

    1. writeResponseBody 方法中对输入数据进行验证和过滤,例如使用 StringEscapeUtils.escapeHtml() 方法对 HTML 字符串进行转义。
    2. 使用 Request 对象的 getParameter() 方法获取参数值,并使用 StringEscapeUtils.escapeHtml() 方法对其进行转义。
    3. 在写入数据时使用 HttpServletResponse 对象的 setCharacterEncoding() 方法设置字符编码,并使用 StringEscapeUtils.escapeHtml() 方法对 HTML 字符串进行转义。

    示例代码:

    import org.apache.commons.lang3.StringEscapeUtils;
    
    // ...
    
    public void writeResponseBody(HttpServletResponse response) {
        String data = request.getParameter("data");
        data = StringEscapeUtils.escapeHtml(data);
        response.getWriter().write(data);
    }
    

    通过这些步骤,你可以在代码扫描时避免 CNAS_33 跨站脚本缺陷的检测。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月24日
  • 创建了问题 6月24日