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();
}
}