diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java index dfcfdf21be..bfbf0d6eea 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/Oauth2Filter.java @@ -40,6 +40,18 @@ public class Oauth2Filter implements Filter { @Override public void init(FilterConfig filterConfig) {} + private void sendResponse(ServletResponse servletResponse, int code, List lines) throws IOException { + HttpServletResponse response = ((HttpServletResponse) servletResponse); + response.setContentType("text/plain"); + response.setStatus(code); + PrintWriter w = response.getWriter(); + for (String line : lines) { + w.println(line); + } + w.close(); + return; + } + /** * The original request from git will not contain the Authorization header. * @@ -57,8 +69,16 @@ public class Oauth2Filter implements Filter { ServletResponse servletResponse, FilterChain filterChain ) throws IOException, ServletException { + String requestUri = ((Request) servletRequest).getRequestURI(); + if (requestUri.startsWith("/project")) { + Log.info("[{}] Invalid request URI", requestUri); + sendResponse(servletResponse,400, Arrays.asList( + "Invalid Project ID (must not have a '/project' prefix)" + )); + return; + } String project = Util.removeAllSuffixes( - ((Request) servletRequest).getRequestURI().split("/")[1], + requestUri.split("/")[1], ".git" ); // Reject v1 ids, the request will be rejected by v1 anyway diff --git a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java index b45b27be7a..f150585f0f 100644 --- a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java +++ b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/application/WLGitBridgeIntegrationTest.java @@ -865,6 +865,32 @@ public class WLGitBridgeIntegrationTest { wlgb.stop(); } + @Test + public void cannotCloneProjectWithSlash() throws IOException, GitAPIException, InterruptedException { + int gitBridgePort = 33886; + int mockServerPort = 3886; + + MockSnapshotServer server = new MockSnapshotServer(mockServerPort, getResource("/canCloneARepository").toFile()); + server.start(); + server.setState(states.get("canCloneARepository").get("state")); + GitBridgeApp wlgb = new GitBridgeApp(new String[] { + makeConfigFile(gitBridgePort, mockServerPort) + }); + + wlgb.run(); + Process gitProcess = runtime.exec("git clone http://127.0.0.1:" + gitBridgePort + "/project/1234abcd", null, dir); + assertNotEquals(0, gitProcess.waitFor()); + + List actual = Util.linesFromStream(gitProcess.getErrorStream(), 0, ""); + assertEquals(Arrays.asList( + "Cloning into '1234abcd'...", + "remote: Invalid Project ID (must not have a '/project' prefix)", + "fatal: unable to access 'http://127.0.0.1:33886/project/1234abcd/': The requested URL returned error: 400" + ), actual); + + wlgb.stop(); + } + private String makeConfigFile( int port, int apiPort