mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
161 lines
8.4 KiB
Java
161 lines
8.4 KiB
Java
import java.io.IOException;
|
|
import java.net.URI;
|
|
import java.net.http.HttpClient;
|
|
import java.net.http.HttpRequest;
|
|
import java.util.regex.Pattern;
|
|
import java.util.regex.Matcher;
|
|
|
|
import javax.servlet.ServletException;
|
|
import javax.servlet.http.HttpServlet;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
public class SanitizationTests extends HttpServlet {
|
|
private static final String VALID_URI = "http://lgtm.com";
|
|
private HttpClient client = HttpClient.newHttpClient();
|
|
|
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
try {
|
|
|
|
URI uri = new URI(request.getParameter("uri")); // $ Source
|
|
// BAD: a request parameter is incorporated without validation into a Http
|
|
// request
|
|
HttpRequest r = HttpRequest.newBuilder(uri).build(); // $ Alert
|
|
client.send(r, null); // $ Alert
|
|
|
|
// GOOD: sanitisation by concatenation with a prefix that prevents targeting an arbitrary host.
|
|
// We test a few different ways of sanitisation: via string conctentation (perhaps nested),
|
|
// via a stringbuilder (for which we consider appends done in the constructor, chained onto
|
|
// the constructor and applied in subsequent statements) and via String.format.
|
|
String safeUri3 = "https://example.com/" + request.getParameter("uri3");
|
|
HttpRequest r3 = HttpRequest.newBuilder(new URI(safeUri3)).build();
|
|
client.send(r3, null);
|
|
|
|
String safeUri4 = "https://example.com/" + ("someprefix" + request.getParameter("uri4"));
|
|
HttpRequest r4 = HttpRequest.newBuilder(new URI(safeUri4)).build();
|
|
client.send(r4, null);
|
|
|
|
StringBuilder safeUri5 = new StringBuilder();
|
|
safeUri5.append("https://example.com/").append(request.getParameter("uri5"));
|
|
HttpRequest r5 = HttpRequest.newBuilder(new URI(safeUri5.toString())).build();
|
|
client.send(r5, null);
|
|
|
|
StringBuilder safeUri5a = new StringBuilder("https://example.com/");
|
|
safeUri5a.append(request.getParameter("uri5a"));
|
|
HttpRequest r5a = HttpRequest.newBuilder(new URI(safeUri5a.toString())).build();
|
|
client.send(r5a, null);
|
|
|
|
StringBuilder safeUri5b = (new StringBuilder("https://example.com/")).append("dir/");
|
|
safeUri5b.append(request.getParameter("uri5b"));
|
|
HttpRequest r5b = HttpRequest.newBuilder(new URI(safeUri5b.toString())).build();
|
|
client.send(r5b, null);
|
|
|
|
StringBuilder safeUri5c = (new StringBuilder("prefix")).append("https://example.com/dir/");
|
|
safeUri5c.append(request.getParameter("uri5c"));
|
|
HttpRequest r5c = HttpRequest.newBuilder(new URI(safeUri5c.toString())).build();
|
|
client.send(r5c, null);
|
|
|
|
String safeUri6 = String.format("https://example.com/%s", request.getParameter("uri6"));
|
|
HttpRequest r6 = HttpRequest.newBuilder(new URI(safeUri6)).build();
|
|
client.send(r6, null);
|
|
|
|
String safeUri7 = String.format("%s/%s", "https://example.com", request.getParameter("uri7"));
|
|
HttpRequest r7 = HttpRequest.newBuilder(new URI(safeUri7)).build();
|
|
client.send(r7, null);
|
|
|
|
String safeUri8 = String.format("%s%s", "https://example.com/", request.getParameter("uri8"));
|
|
HttpRequest r8 = HttpRequest.newBuilder(new URI(safeUri8)).build();
|
|
client.send(r8, null);
|
|
|
|
String safeUri9 = String.format("http://%s", "myserver.com") + "/" + request.getParameter("uri9");
|
|
HttpRequest r9 = HttpRequest.newBuilder(new URI(safeUri9)).build();
|
|
client.send(r9, null);
|
|
|
|
// BAD: cases where a string that would sanitise is used, but occurs in the wrong
|
|
// place to sanitise user input:
|
|
String unsafeUri3 = request.getParameter("baduri3") + "https://example.com/"; // $ Source
|
|
HttpRequest unsafer3 = HttpRequest.newBuilder(new URI(unsafeUri3)).build(); // $ Alert
|
|
client.send(unsafer3, null); // $ Alert
|
|
|
|
String unsafeUri4 = ("someprefix" + request.getParameter("baduri4")) + "https://example.com/"; // $ Source
|
|
HttpRequest unsafer4 = HttpRequest.newBuilder(new URI(unsafeUri4)).build(); // $ Alert
|
|
client.send(unsafer4, null); // $ Alert
|
|
|
|
StringBuilder unsafeUri5 = new StringBuilder();
|
|
unsafeUri5.append(request.getParameter("baduri5")).append("https://example.com/"); // $ Source
|
|
HttpRequest unsafer5 = HttpRequest.newBuilder(new URI(unsafeUri5.toString())).build(); // $ Alert
|
|
client.send(unsafer5, null); // $ Alert
|
|
|
|
StringBuilder unafeUri5a = new StringBuilder(request.getParameter("uri5a")); // $ Source
|
|
unafeUri5a.append("https://example.com/");
|
|
HttpRequest unsafer5a = HttpRequest.newBuilder(new URI(unafeUri5a.toString())).build(); // $ Alert
|
|
client.send(unsafer5a, null); // $ Alert
|
|
|
|
StringBuilder unsafeUri5b = (new StringBuilder(request.getParameter("uri5b"))).append("dir/"); // $ Source
|
|
unsafeUri5b.append("https://example.com/");
|
|
HttpRequest unsafer5b = HttpRequest.newBuilder(new URI(unsafeUri5b.toString())).build(); // $ Alert
|
|
client.send(unsafer5b, null); // $ Alert
|
|
|
|
StringBuilder unsafeUri5c = (new StringBuilder("https")).append(request.getParameter("uri5c")); // $ Source
|
|
unsafeUri5c.append("://example.com/dir/");
|
|
HttpRequest unsafer5c = HttpRequest.newBuilder(new URI(unsafeUri5c.toString())).build(); // $ Alert
|
|
client.send(unsafer5c, null); // $ Alert
|
|
|
|
String unsafeUri6 = String.format("%shttps://example.com/", request.getParameter("baduri6")); // $ Source
|
|
HttpRequest unsafer6 = HttpRequest.newBuilder(new URI(unsafeUri6)).build(); // $ Alert
|
|
client.send(unsafer6, null); // $ Alert
|
|
|
|
String unsafeUri7 = String.format("%s/%s", request.getParameter("baduri7"), "https://example.com"); // $ Source
|
|
HttpRequest unsafer7 = HttpRequest.newBuilder(new URI(unsafeUri7)).build(); // $ Alert
|
|
client.send(unsafer7, null); // $ Alert
|
|
|
|
String unsafeUri8 = String.format("%s%s", request.getParameter("baduri8"), "https://example.com/"); // $ Source
|
|
HttpRequest unsafer8 = HttpRequest.newBuilder(new URI(unsafeUri8)).build(); // $ Alert
|
|
client.send(unsafer8, null); // $ Alert
|
|
|
|
String unsafeUri9 = request.getParameter("baduri9") + "/" + String.format("http://%s", "myserver.com"); // $ Source
|
|
HttpRequest unsafer9 = HttpRequest.newBuilder(new URI(unsafeUri9)).build(); // $ Alert
|
|
client.send(unsafer9, null); // $ Alert
|
|
|
|
String unsafeUri10 = String.format("%s://%s:%s%s", "http", "myserver.com", "80", request.getParameter("baduri10")); // $ Source
|
|
HttpRequest unsafer10 = HttpRequest.newBuilder(new URI(unsafeUri10)).build(); // $ Alert
|
|
client.send(unsafer10, null); // $ Alert
|
|
|
|
// GOOD: sanitisation by regexp validation
|
|
String param10 = request.getParameter("uri10");
|
|
if (param10.matches("[a-zA-Z0-9_-]+")) {
|
|
HttpRequest r10 = HttpRequest.newBuilder(new URI(param10)).build();
|
|
client.send(r10, null);
|
|
}
|
|
|
|
String param11 = request.getParameter("uri11");
|
|
validate(param11);
|
|
HttpRequest r11 = HttpRequest.newBuilder(new URI(param11)).build();
|
|
client.send(r11, null);
|
|
|
|
String param12 = request.getParameter("uri12");
|
|
if (Pattern.matches("[a-zA-Z0-9_-]+", param12)) {
|
|
HttpRequest r12 = HttpRequest.newBuilder(new URI(param12)).build();
|
|
client.send(r12, null);
|
|
}
|
|
|
|
Pattern pattern = Pattern.compile("[a-zA-Z0-9_-]+");
|
|
String param13 = request.getParameter("uri13");
|
|
Matcher matcher = pattern.matcher(param13);
|
|
if (matcher.matches()) {
|
|
HttpRequest r13 = HttpRequest.newBuilder(new URI(param13)).build();
|
|
client.send(r13, null);
|
|
}
|
|
} catch (Exception e) {
|
|
// TODO: handle exception
|
|
}
|
|
}
|
|
|
|
private void validate(String s) {
|
|
if (!s.matches("[a-zA-Z0-9_-]+")) {
|
|
throw new IllegalArgumentException("Invalid ID");
|
|
}
|
|
}
|
|
}
|