browserup / browserup-proxy

BrowserUp Proxy is a free utility to watch, test, and manipulate web application network traffic and performance.
https://browserup.com
Apache License 2.0
164 stars 41 forks source link

Use the CONNECT method URI as host fallback making the proxy HTTP/1.0 compatible #371

Open candrews opened 3 years ago

candrews commented 3 years ago

When a request is made for proxy interception using the CONNECT method but not including a host header, then a NullPointerException is thrown in com.browserup.bup.mitm.manager.ImpersonatingMitmManager.getHostnameImpersonatingSslContext(String, SSLSession) because the hostnameToImpersonate is null.

As a fallback, use the CONNECT URI as a host.

Here's an example stack trace:

An exception was thrown by org.littleshoot.proxy.impl.ConnectionFlow$$Lambda$447/0x000000080049cd70.operationComplete()
com.browserup.bup.mitm.exception.MitmException: Error creating SSLEngine for connection to client to impersonate upstream host: null
    at com.browserup.bup.mitm.manager.ImpersonatingMitmManager.clientSslEngineFor(ImpersonatingMitmManager.java:241)
    at org.littleshoot.proxy.impl.ProxyToServerConnection$7.execute(ProxyToServerConnection.java:950)
    at org.littleshoot.proxy.impl.ConnectionFlow.doProcessCurrentStep(ConnectionFlow.java:142)
    at org.littleshoot.proxy.impl.ConnectionFlow.processCurrentStep(ConnectionFlow.java:132)
    at org.littleshoot.proxy.impl.ConnectionFlow.advance(ConnectionFlow.java:99)
    at org.littleshoot.proxy.impl.ConnectionFlowStep.onSuccess(ConnectionFlowStep.java:74)
    at org.littleshoot.proxy.impl.ConnectionFlow.lambda$doProcessCurrentStep$1(ConnectionFlow.java:147)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:578)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:552)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:491)
    at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:184)
    at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:95)
    at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:30)
    at org.littleshoot.proxy.impl.ConnectionFlow.doProcessCurrentStep(ConnectionFlow.java:142)
    at org.littleshoot.proxy.impl.ConnectionFlow.lambda$processCurrentStep$0(ConnectionFlow.java:130)
    at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
    at io.netty.util.concurrent.PromiseTask.run(PromiseTask.java:106)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.NullPointerException: null
    at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:878)
    at com.google.common.cache.LocalCache.get(LocalCache.java:3950)
    at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4848)
    at com.browserup.bup.mitm.manager.ImpersonatingMitmManager.getHostnameImpersonatingSslContext(ImpersonatingMitmManager.java:256)
    at com.browserup.bup.mitm.manager.ImpersonatingMitmManager.clientSslEngineFor(ImpersonatingMitmManager.java:237)
    ... 22 common frames omitted

The request causing this error was simply:

CONNECT REDACTEDs:443 HTTP/1.0

without any HTTP headers.

candrews commented 3 years ago

@kiturutin (or anyone else), can you please review this MR?