mirror of
https://github.com/github/codeql.git
synced 2025-12-18 09:43:15 +01:00
271 lines
9.8 KiB
Java
271 lines
9.8 KiB
Java
package com.example;
|
|
|
|
import java.io.InputStream;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.Paths;
|
|
import java.net.URI;
|
|
import java.net.URL;
|
|
import java.net.URISyntaxException;
|
|
|
|
import javax.servlet.http.HttpServlet;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.ServletOutputStream;
|
|
import javax.servlet.ServletException;
|
|
import javax.servlet.ServletConfig;
|
|
import javax.servlet.ServletContext;
|
|
|
|
import io.undertow.server.handlers.resource.FileResourceManager;
|
|
import io.undertow.server.handlers.resource.Resource;
|
|
import org.jboss.vfs.VFS;
|
|
import org.jboss.vfs.VirtualFile;
|
|
|
|
public class UnsafeResourceGet extends HttpServlet {
|
|
private static final String BASE_PATH = "/pages";
|
|
|
|
@Override
|
|
// BAD: getResource constructed from `ServletContext` without input validation
|
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
ServletConfig cfg = getServletConfig();
|
|
ServletContext sc = cfg.getServletContext();
|
|
|
|
// A sample request /fake.jsp/../WEB-INF/web.xml can load the web.xml file
|
|
URL url = sc.getResource(requestUrl);
|
|
|
|
InputStream in = url.openStream();
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
|
|
// GOOD: getResource constructed from `ServletContext` with input validation
|
|
protected void doGetGood(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
ServletConfig cfg = getServletConfig();
|
|
ServletContext sc = cfg.getServletContext();
|
|
|
|
Path path = Paths.get(requestUrl).normalize().toRealPath();
|
|
if (path.startsWith(BASE_PATH)) {
|
|
URL url = sc.getResource(path.toString());
|
|
|
|
InputStream in = url.openStream();
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
}
|
|
|
|
// GOOD: getResource constructed from `ServletContext` with null check only
|
|
protected void doGetGood2(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
PrintWriter writer = response.getWriter();
|
|
|
|
ServletConfig cfg = getServletConfig();
|
|
ServletContext sc = cfg.getServletContext();
|
|
|
|
// A sample request /fake.jsp/../WEB-INF/web.xml can load the web.xml file
|
|
URL url = sc.getResource(requestUrl);
|
|
if (url == null) {
|
|
writer.println("Requested source not found");
|
|
}
|
|
}
|
|
|
|
// GOOD: getResource constructed from `ServletContext` with `equals` check
|
|
protected void doGetGood3(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
ServletContext sc = request.getServletContext();
|
|
|
|
if (requestUrl.equals("/public/crossdomain.xml")) {
|
|
URL url = sc.getResource(requestUrl);
|
|
|
|
InputStream in = url.openStream();
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
// BAD: getResourceAsStream constructed from `ServletContext` without input validation
|
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestPath = request.getParameter("requestPath");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
// A sample request /fake.jsp/../WEB-INF/web.xml can load the web.xml file
|
|
InputStream in = request.getServletContext().getResourceAsStream(requestPath);
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
|
|
// GOOD: getResourceAsStream constructed from `ServletContext` with input validation
|
|
protected void doPostGood(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestPath = request.getParameter("requestPath");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
if (!requestPath.contains("..") && requestPath.startsWith("/trusted")) {
|
|
InputStream in = request.getServletContext().getResourceAsStream(requestPath);
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
// BAD: getResource constructed from `Class` without input validation
|
|
protected void doHead(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
// A sample request /fake.jsp/../../../WEB-INF/web.xml can load the web.xml file
|
|
// Note the class is in two levels of subpackages and `Class.getResource` starts from its own directory
|
|
URL url = getClass().getResource(requestUrl);
|
|
|
|
InputStream in = url.openStream();
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
|
|
// GOOD: getResource constructed from `Class` with input validation
|
|
protected void doHeadGood(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
Path path = Paths.get(requestUrl).normalize().toRealPath();
|
|
if (path.startsWith(BASE_PATH)) {
|
|
URL url = getClass().getResource(path.toString());
|
|
|
|
InputStream in = url.openStream();
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
// BAD: getResourceAsStream constructed from `ClassLoader` without input validation
|
|
protected void doPut(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestPath = request.getParameter("requestPath");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
ServletConfig cfg = getServletConfig();
|
|
ServletContext sc = cfg.getServletContext();
|
|
|
|
// A sample request /fake.jsp/../../../WEB-INF/web.xml can load the web.xml file
|
|
// Note the class is in two levels of subpackages and `ClassLoader.getResourceAsStream` starts from its own directory
|
|
InputStream in = getClass().getClassLoader().getResourceAsStream(requestPath);
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
|
|
// GOOD: getResourceAsStream constructed from `ClassLoader` with input validation
|
|
protected void doPutGood(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestPath = request.getParameter("requestPath");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
ServletConfig cfg = getServletConfig();
|
|
ServletContext sc = cfg.getServletContext();
|
|
|
|
if (!requestPath.contains("..") && requestPath.startsWith("/trusted")) {
|
|
InputStream in = getClass().getClassLoader().getResourceAsStream(requestPath);
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
}
|
|
|
|
// BAD: getResource constructed from `ClassLoader` without input validation
|
|
protected void doPutBad(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestUrl = request.getParameter("requestURL");
|
|
ServletOutputStream out = response.getOutputStream();
|
|
|
|
// A sample request /fake.jsp/../../../WEB-INF/web.xml can load the web.xml file
|
|
// Note the class is in two levels of subpackages and `ClassLoader.getResource` starts from its own directory
|
|
URL url = getClass().getClassLoader().getResource(requestUrl);
|
|
|
|
InputStream in = url.openStream();
|
|
byte[] buf = new byte[4 * 1024]; // 4K buffer
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(buf)) != -1) {
|
|
out.write(buf, 0, bytesRead);
|
|
}
|
|
}
|
|
|
|
// BAD: getResource constructed using Undertow IO without input validation
|
|
protected void doPutBad2(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestPath = request.getParameter("requestPath");
|
|
|
|
try {
|
|
FileResourceManager rm = new FileResourceManager(VFS.getChild(new URI("/usr/share")).getPhysicalFile());
|
|
Resource rs = rm.getResource(requestPath);
|
|
|
|
VirtualFile overlay = VFS.getChild(new URI("EAP_HOME/modules/"));
|
|
// Do file operations
|
|
overlay.getChild(rs.getPath());
|
|
} catch (URISyntaxException ue) {
|
|
throw new IOException("Cannot parse the URI");
|
|
}
|
|
}
|
|
|
|
// GOOD: getResource constructed using Undertow IO with input validation
|
|
protected void doPutGood2(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
String requestPath = request.getParameter("requestPath");
|
|
|
|
try {
|
|
FileResourceManager rm = new FileResourceManager(VFS.getChild(new URI("/usr/share")).getPhysicalFile());
|
|
Resource rs = rm.getResource(requestPath);
|
|
|
|
VirtualFile overlay = VFS.getChild(new URI("EAP_HOME/modules/"));
|
|
String path = rs.getPath();
|
|
if (path.startsWith("/trusted_path") && !path.contains("..")) {
|
|
// Do file operations
|
|
overlay.getChild(path);
|
|
}
|
|
} catch (URISyntaxException ue) {
|
|
throw new IOException("Cannot parse the URI");
|
|
}
|
|
}
|
|
}
|