Skip to content

Commit

Permalink
Fixed mis-detection of browser proxy requests over HTTPS
Browse files Browse the repository at this point in the history
  • Loading branch information
tomakehurst committed Jul 25, 2023
1 parent 5637a00 commit e21394e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.github.tomakehurst.wiremock.jetty;

import static com.github.tomakehurst.wiremock.common.Exceptions.throwUnchecked;
import static com.github.tomakehurst.wiremock.jetty11.HttpsProxyDetectingHandler.IS_HTTPS_PROXY_REQUEST_ATTRIBUTE;

import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -82,7 +83,7 @@ public static Socket getTlsSocket(Response response) {
public static boolean isBrowserProxyRequest(HttpServletRequest request) {
if (request instanceof Request) {
Request jettyRequest = (Request) request;
return "https".equals(jettyRequest.getHttpURI().getScheme())
return Boolean.TRUE.equals(request.getAttribute(IS_HTTPS_PROXY_REQUEST_ATTRIBUTE))
|| "http".equals(jettyRequest.getMetaData().getURI().getScheme());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2023 Thomas Akehurst
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.tomakehurst.wiremock.jetty11;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.AbstractHandler;

public class HttpsProxyDetectingHandler extends AbstractHandler {

public static final String IS_HTTPS_PROXY_REQUEST_ATTRIBUTE = "wiremock.isHttpsProxyRequest";

private final ServerConnector mitmProxyConnector;

public HttpsProxyDetectingHandler(ServerConnector mitmProxyConnector) {
this.mitmProxyConnector = mitmProxyConnector;
}

@Override
public void handle(
String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
final int httpsProxyPort = mitmProxyConnector.getLocalPort();
if (request.getLocalPort() == httpsProxyPort) {
request.setAttribute(IS_HTTPS_PROXY_REQUEST_ATTRIBUTE, true);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ protected HandlerCollection createHandler(
super.createHandler(options, adminRequestHandler, stubRequestHandler);

if (options.browserProxySettings().enabled()) {
handler.prependHandler(new HttpsProxyDetectingHandler(mitmProxyConnector));
handler.prependHandler(new ManInTheMiddleSslConnectHandler(mitmProxyConnector));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2021 Thomas Akehurst
* Copyright (C) 2013-2023 Thomas Akehurst
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,6 +28,7 @@
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.http.HttpClientFactory;
import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
import com.google.common.io.Resources;
import java.io.FileInputStream;
import java.io.IOException;
Expand Down Expand Up @@ -299,6 +300,29 @@ public void proxyingFailsWhenTargetServiceRequiresClientCertificatesAndProxyDoes
assertThat(response.getCode(), is(500));
}

@Test
void doesNotTreatPlainHttpsRequestAsBrowserProxyRequest() throws Exception {
proxy =
new WireMockServer(
wireMockConfig().dynamicPort().dynamicHttpsPort().enableBrowserProxying(true));
proxy.start();
proxy.stubFor(get("/no-proxying-thanks").willReturn(ok("proxyless")));

httpClient = HttpClientFactory.createClient();

String url = "https://localhost:" + proxy.httpsPort() + "/no-proxying-thanks";
HttpGet get = new HttpGet(url);
int status = httpClient.execute(get, HttpResponse::getCode);
assertThat(status, is(200));

ServeEvent serveEvent =
proxy.getAllServeEvents().stream()
.filter(event -> event.getRequest().getUrl().equals("/no-proxying-thanks"))
.findFirst()
.get();
assertThat(serveEvent.getRequest().isBrowserProxyRequest(), is(false));
}

private String url(String path) {
return String.format("https://localhost:%d%s", wireMockServer.httpsPort(), path);
}
Expand Down

0 comments on commit e21394e

Please sign in to comment.