Java: update qhelp

This commit is contained in:
Jami Cogswell
2023-12-01 12:14:27 -05:00
parent 09bc21dbd3
commit c331393cfd
6 changed files with 25 additions and 132 deletions

View File

@@ -1,21 +0,0 @@
//BAD: no path validation in Spring resource loading
@GetMapping("/file")
public String getFileContent(@RequestParam(name="fileName") String fileName) {
ClassPathResource clr = new ClassPathResource(fileName);
File file = ResourceUtils.getFile(fileName);
Resource resource = resourceLoader.getResource(fileName);
}
//GOOD: check for a trusted prefix, ensuring path traversal is not used to erase that prefix in Spring resource loading:
@GetMapping("/file")
public String getFileContent(@RequestParam(name="fileName") String fileName) {
if (!fileName.contains("..") && fileName.hasPrefix("/public-content")) {
ClassPathResource clr = new ClassPathResource(fileName);
File file = ResourceUtils.getFile(fileName);
Resource resource = resourceLoader.getResource(fileName);
}
}

View File

@@ -1,18 +0,0 @@
// BAD: no URI validation
URL url = request.getServletContext().getResource(requestUrl);
url = getClass().getResource(requestUrl);
InputStream in = url.openStream();
InputStream in = request.getServletContext().getResourceAsStream(requestPath);
in = getClass().getClassLoader().getResourceAsStream(requestPath);
// GOOD: check for a trusted prefix, ensuring path traversal is not used to erase that prefix:
// (alternatively use `Path.normalize` instead of checking for `..`)
if (!requestPath.contains("..") && requestPath.startsWith("/trusted")) {
InputStream in = request.getServletContext().getResourceAsStream(requestPath);
}
Path path = Paths.get(requestUrl).normalize().toRealPath();
if (path.startsWith("/trusted")) {
URL url = request.getServletContext().getResource(path.toString());
}

View File

@@ -1,11 +0,0 @@
// BAD: no URI validation
String returnURL = request.getParameter("returnURL");
RequestDispatcher rd = sc.getRequestDispatcher(returnURL);
rd.forward(request, response);
// GOOD: check for a trusted prefix, ensuring path traversal is not used to erase that prefix:
// (alternatively use `Path.normalize` instead of checking for `..`)
if (!returnURL.contains("..") && returnURL.hasPrefix("/pages")) { ... }
// Also GOOD: check for a forbidden prefix, ensuring URL-encoding is not used to evade the check:
// (alternatively use `URLDecoder.decode` before `hasPrefix`)
if (returnURL.hasPrefix("/internal") && !returnURL.contains("%")) { ... }

View File

@@ -1,38 +1,17 @@
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
public class UrlForward extends HttpServlet {
private static final String VALID_FORWARD = "https://cwe.mitre.org/data/definitions/552.html";
@Controller
public class UrlForward {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletConfig cfg = getServletConfig();
ServletContext sc = cfg.getServletContext();
@GetMapping("/bad1")
public ModelAndView bad1(String url) {
return new ModelAndView(url);
}
// BAD: a request parameter is incorporated without validation into a URL forward
sc.getRequestDispatcher(request.getParameter("target")).forward(request, response);
@GetMapping("/bad2")
public void bad2(String url, HttpServletRequest request, HttpServletResponse response) {
try {
request.getRequestDispatcher("/WEB-INF/jsp/" + url + ".jsp").include(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@GetMapping("/good1")
public void good1(String url, HttpServletRequest request, HttpServletResponse response) {
try {
request.getRequestDispatcher("/index.jsp?token=" + url).forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// GOOD: the request parameter is validated against a known fixed string
if (VALID_FORWARD.equals(request.getParameter("target"))) {
sc.getRequestDispatcher(VALID_FORWARD).forward(request, response);
}
}
}

View File

@@ -5,66 +5,32 @@
<overview>
<p>Constructing a server-side redirect path with user input could allow an attacker to download application binaries
(including application classes or jar files) or view arbitrary files within protected directories.</p>
<p>Directly incorporating user input into a URL forward request without validating the input
can cause file information disclosure by allowing an attacker to access unauthorized URLs.</p>
</overview>
<recommendation>
<p>Unsanitized user provided data must not be used to construct the path for URL forwarding. In order to prevent
untrusted URL forwarding, it is recommended to avoid concatenating user input directly into the forwarding URL.
Instead, user input should be checked against allowed (e.g., must come within <code>user_content/</code>) or disallowed
(e.g. must not come within <code>/internal</code>) paths, ensuring that neither path traversal using <code>../</code>
or URL encoding are used to evade these checks.
</p>
<p>To guard against untrusted URL forwarding, it is advisable to avoid putting user input
directly into a forwarded URL. Instead, maintain a list of authorized
URLs on the server; then choose from that list based on the user input provided.</p>
</recommendation>
<example>
<p>The following examples show the bad case and the good case respectively.
The <code>bad</code> methods show an HTTP request parameter being used directly in a URL forward
without validating the input, which may cause file leakage. In the <code>good1</code> method,
ordinary forwarding requests are shown, which will not cause file leakage.
<p>The following example shows an HTTP request parameter being used directly in a URL forward
without validating the input, which may cause file information disclosure.
It also shows how to remedy the problem by validating the user input against a known fixed string.
</p>
<sample src="UrlForward.java" />
<p>The following examples show an HTTP request parameter or request path being used directly in a
request dispatcher of Java EE without validating the input, which allows sensitive file exposure
attacks. It also shows how to remedy the problem by validating the user input.
</p>
<sample src="UnsafeServletRequestDispatch.java" />
<p>The following examples show an HTTP request parameter or request path being used directly to
retrieve a resource of a Java EE application without validating the input, which allows sensitive
file exposure attacks. It also shows how to remedy the problem by validating the user input.
</p>
<sample src="UnsafeResourceGet.java" />
<p>The following examples show an HTTP request parameter being used directly to retrieve a resource
of a Java Spring application without validating the input, which allows sensitive file exposure
attacks. It also shows how to remedy the problem by validating the user input.
</p>
<sample src="UnsafeLoadSpringResource.java" />
</example>
<references>
<li>File Disclosure:
<a href="https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.file_disclosure_spring">Unsafe Url Forward</a>.
</li>
<li>Jakarta Javadoc:
<a href="https://jakarta.ee/specifications/webprofile/9/apidocs/jakarta/servlet/servletrequest#getRequestDispatcher-java.lang.String-">Security vulnerability with unsafe usage of RequestDispatcher</a>.
</li>
<li>Micro Focus:
<a href="https://vulncat.fortify.com/en/detail?id=desc.dataflow.java.file_disclosure_j2ee">File Disclosure: J2EE</a>
</li>
<li>CVE-2015-5174:
<a href="https://vuldb.com/?id.81084">Apache Tomcat 6.0/7.0/8.0/9.0 Servletcontext getResource/getResourceAsStream/getResourcePaths Path Traversal</a>
</li>
<li>CVE-2019-3799:
<a href="https://github.com/mpgn/CVE-2019-3799">CVE-2019-3799 - Spring-Cloud-Config-Server Directory Traversal &lt; 2.1.2, 2.0.4, 1.4.6</a>
<li>OWASP:
<a href="https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html">Unvalidated Redirects and Forwards Cheat Sheet</a>.
</li>
</references>
</qhelp>

View File

@@ -1,16 +1,14 @@
/**
* @name URL forward from a remote source
* @description URL forward based on unvalidated user-input
* may cause file information disclosure or
* redirection to malicious web sites.
* may cause file information disclosure.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.5
* @precision high
* @id java/unvalidated-url-forward
* @tags security
* external/cwe/cwe-552
* external/cwe/cwe-601
*/
import java