使用Checkmarx遇XXE/SSRF报错:InputStream读取方法问题咨询
getStringFromInputStream Hey there! Let's break down why your method is triggering those Checkmarx alerts and how to resolve them. First, let's unpack the root causes:
Why Are These Alerts Firing?
Checkmarx flags this method because it processes an InputStream that could originate from untrusted sources. Here's the breakdown:
- XXE (XML External Entity): If this input stream carries XML content (like from a user-uploaded file or external API), and downstream code parses this XML without disabling external entities, attackers could inject malicious XML to access local files or internal systems.
- SSRF (Server-Side Request Forgery): If the input stream is opened from a URL controlled by an attacker (e.g., code that fetches content from a user-provided URL), your server could be tricked into making requests to internal services or restricted networks.
Your method itself just reads text from the stream, but Checkmarx identifies it as a "risky sink" because it lacks safeguards against these upstream vulnerabilities.
Step-by-Step Fixes
1. Guard Against XXE (If Handling XML Content)
If this method might process XML data, ensure any XML parsing (either in this method or upstream) uses a secure parser that disables external entities and DTDs. Here's how to configure a safe XML parser:
// Example: Secure XML parsing upstream before passing to your method DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // Disable DTDs and external entities dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); dbf.setFeature("http://xml.org/sax/features/external-general-entities", false); dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); dbf.setXIncludeAware(false); dbf.setExpandEntityReferences(false); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(yourInputStream); // Convert parsed XML to string before passing to getStringFromInputStream (if needed)
2. Block SSRF at the Source
If your input stream comes from a URL (e.g., code that calls URL.openStream()), add strict validation to restrict which URLs your server can access:
// Example: Validate URLs upstream before opening the stream String userProvidedUrl = ...; // From user input URL url = new URL(userProvidedUrl); // Allow only trusted protocols if (!Set.of("http", "https").contains(url.getProtocol())) { throw new IllegalArgumentException("Unsupported protocol"); } // Allow only pre-approved domains Set<String> allowedDomains = Set.of("your-internal-service.com", "trusted-partner.com"); if (!allowedDomains.contains(url.getHost())) { throw new IllegalArgumentException("Unauthorized domain"); } // Now open the stream safely InputStream safeStream = url.openStream(); String content = getStringFromInputStream(safeStream);
3. Harden the getStringFromInputStream Method
Even if the stream is safe, adding safeguards to your method will help Checkmarx recognize it as secure:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.text.Normalizer; public static String getStringFromInputStream(InputStream is) throws IOException { // Limit input size to prevent DoS attacks final int MAX_CONTENT_SIZE = 1024 * 1024; // 1MB, adjust as needed BufferedReader br = null; StringBuilder sb = new StringBuilder(); String line; try { // Explicitly set charset to avoid encoding-based vulnerabilities br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); while ((line = br.readLine()) != null) { // Check if adding this line would exceed the max size if (sb.length() + line.length() > MAX_CONTENT_SIZE) { throw new IOException("Input exceeds maximum allowed size"); } sb.append(Normalizer.normalize(line, Normalizer.Form.NFC)); sb.append(System.lineSeparator()); } return sb.toString().trim(); } finally { // Ensure resources are closed properly if (br != null) { br.close(); } is.close(); } }
Final Notes
Checkmarx's alerts highlight potential risks, not definite vulnerabilities. By adding validation at the source of the input stream and hardening your processing method, you'll address both XXE and SSRF concerns. Be sure to retest these changes with Checkmarx to confirm the alerts are resolved!
内容的提问来源于stack exchange,提问作者Tuss

