Azure Functions中用MultipartStream应对CVE-2023-24998需特殊配置吗?
解决方案
1. 必须针对MultipartStream添加限制
CVE-2023-24998的核心是未限制多部件请求中的部件数量,攻击者可以构造包含大量空部件的请求,耗尽服务端CPU或内存资源。 FileUploadBase#setFileCountMax是上层FileUpload/ServletFileUpload封装类的配置项,直接使用底层MultipartStream时不会自动生效,因此需要自行在代码中添加部件计数和限制逻辑。
2. 具体实现代码
在遍历MultipartStream部件的循环中加入计数器,当超过预设的最大部件数时抛出异常并终止请求处理:
@FunctionName("HttpTrigger-Java") public HttpResponseMessage run( @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request, final ExecutionContext context) { String contentType = request.getHeaders().get("content-type"); // 先校验content-type格式 if (contentType == null || !contentType.startsWith("multipart/form-data")) { return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Invalid content type").build(); } String body = request.getBody().orElseThrow(() -> new IllegalArgumentException("Request body cannot be empty")); InputStream in = new ByteArrayInputStream(body.getBytes()); // 健壮解析boundary,处理带引号的情况 String boundary = null; String[] contentTypeParts = contentType.split(";"); for (String part : contentTypeParts) { part = part.trim(); if (part.startsWith("boundary=")) { boundary = part.substring("boundary=".length()).replace("\"", ""); break; } } if (boundary == null) { return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Missing boundary in content-type").build(); } int bufSize = 1024; MultipartStream multipartStream = new MultipartStream(in, boundary.getBytes(), bufSize, null); // 配置最大允许的部件数量,根据业务需求调整,示例设为100 final int MAX_PART_COUNT = 100; int partCount = 0; try { boolean nextPart = multipartStream.skipPreamble(); while (nextPart) { partCount++; if (partCount > MAX_PART_COUNT) { throw new IOException("Exceeded maximum allowed part count: " + MAX_PART_COUNT); } String header = multipartStream.readHeaders(); System.out.println("\nHeaders:\n" + header); System.out.println("Body:"); multipartStream.readBodyData(System.out); System.out.println(""); nextPart = multipartStream.readBoundary(); } return request.createResponseBuilder(HttpStatus.OK).body("Success").build(); } catch (IOException | IllegalArgumentException e) { context.getLogger().severe("Multipart request processing failed: " + e.getMessage()); return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body(e.getMessage()).build(); } }
3. 额外优化建议
- 升级到Commons FileUpload 1.5+版本:虽然直接用MultipartStream无法使用
setFileCountMax,但1.5版本修复了其他潜在安全问题,同时优化了MultipartStream的内部实现。 - 添加请求体大小限制:在Azure Functions的函数配置中设置请求体大小上限,或在代码中校验body长度,避免超大请求耗尽内存。
- 健壮性优化:原代码中直接分割
content-type获取boundary的方式存在格式兼容问题,建议改用遍历解析的方式处理带引号或空格的边界值。
内容的提问来源于stack exchange,提问作者ng.newbie
相关产品推荐
相关产品推荐

