Skip to content

Repository files navigation

Java Transparent Proxy

A lightweight HTTP/HTTPS proxy library with pluggable interceptors and full MITM HTTPS support.

Features

  • HTTP Proxy — Full HTTP/1.1 proxy
  • HTTPS Interception — Man-in-the-Middle mode with on-the-fly certificate generation
  • HTTPS Pass-through — Secure tunneling via CONNECT (no decryption)
  • Pluggable Interceptors — Chain-of-responsibility for inspecting/modifying requests and responses
  • Certificate Authority — Auto-generated CA with per-hostname server certificates (BouncyCastle)

Usage

Basic HTTP Proxy

HttpProxyproxy = newHttpProxy();
proxy.start(8080);
// Option 1: Configure a specific HttpClientHttpClientclient = HttpClient.newBuilder()
.proxy(proxy.asProxySelector())
.build();
// Option 2: Set as system default for all HttpClient instancesProxySelector.setDefault(proxy.asProxySelector());
HttpClientclient = HttpClient.newHttpClient(); // Uses system defaultHttpResponse<String> response = client.send(
HttpRequest.newBuilder().uri(URI.create("http://example.com")).build(),
HttpResponse.BodyHandlers.ofString());
proxy.stop();

Intercepting Requests

HttpProxyproxy = newHttpProxy();
// Log all requestsproxy.addInterceptor((request, chain) -> {
System.out.println(request.getMethod() + " " + request.getUri());
returnchain.proceed(request);
});
// Add a custom headerproxy.addInterceptor((request, chain) -> {
ProxyRequestmodified = request.withHeader("X-Proxy", "tproxy");
returnchain.proceed(modified);
});
proxy.start(8080);

Modifying Responses

proxy.addInterceptor((request, chain) -> {
ProxyResponseresponse = chain.proceed(request);
// Rewrite response bodyStringbody = newString(response.getBody());
Stringmodified = body.replace("server", "proxy");
returnresponse.withBody(modified.getBytes());
});

Mocking Responses

proxy.addInterceptor((request, chain) -> {
if (request.getUri().getPath().equals("/api/users")) {
returnnewProxyResponse(200,
Headers.of("Content-Type", "application/json"),
"{\"users\":[]}".getBytes());
}
returnchain.proceed(request);
});

HTTPS Interception (MITM)

Enable MITM mode to decrypt, inspect, and modify HTTPS traffic:

HttpProxyproxy = newHttpProxy();
proxy.enableHttpsInterception();
// Interceptors now see decrypted HTTPS requestsproxy.addInterceptor((request, chain) -> {
System.out.println("HTTPS: " + request.getUri()); // visible!returnchain.proceed(request);
});
proxy.start(8080);

On first run, the proxy generates a CA certificate (tproxy-ca.crt) and keystore (tproxy-ca.p12). Clients must trust this CA. For HttpClient:

CertificateFactorycf = CertificateFactory.getInstance("X.509");
CertificatecaCert;
try (FileInputStreamfis = newFileInputStream("tproxy-ca.crt")) {
caCert = cf.generateCertificate(fis);
}
KeyStoretrustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
trustStore.setCertificateEntry("tproxy-ca", caCert);
TrustManagerFactorytmf = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContextsslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
HttpClientclient = HttpClient.newBuilder()
.proxy(proxy.asProxySelector())
.sslContext(sslContext)
.build();

HTTPS Pass-through

Without MITM enabled (the default), HTTPS tunnels through encrypted. Interceptors cannot see the content:

HttpProxyproxy = newHttpProxy();
proxy.start(8080); // HTTPS passes through unmodified

How MITM Works

  1. Client sends CONNECT example.com:443 to the proxy
  2. InterceptingConnectHandler (extends Jetty's ConnectHandler) redirects the tunnel to a local SSL-terminating connector
  3. CertificateGeneratingKeyManager reads the SNI hostname from the TLS ClientHello and generates a certificate signed by the proxy's CA
  4. After SSL termination, the decrypted HTTP request flows through the normal servlet handler and interceptor chain
  5. The proxy forwards the request to the real server using a trust-all HttpClient

Building

./mvnw compile # Compile
./mvnw test# Run tests (38 tests)
./mvnw package # Package JAR

Requirements

  • Java 21+
  • Maven 3.6+

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Security Warning: This tool performs man-in-the-middle HTTPS interception. Use only for educational and testing purposes in controlled environments where you have proper authorization.

About

A lightweight HTTP/HTTPS proxy library with pluggable interceptors and full MITM HTTPS support

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages