rburgst/okhttp-digest

Missing nonce in challenge

emauro opened this issue · 18 comments

Hi,

I am receiving several reports of this problem. See stack trace below. Is it my fault?

java.lang.IllegalArgumentException: missing nonce in challenge
at com.burgstaller.okhttp.digest.DigestAuthenticator.authenticateWithState(DigestAuthenticator.java:170)
at com.burgstaller.okhttp.digest.DigestAuthenticator.authenticate(DigestAuthenticator.java:148)
at com.burgstaller.okhttp.DispatchingAuthenticator.authenticate(DispatchingAuthenticator.java:45)
at com.burgstaller.okhttp.CachingAuthenticatorDecorator.authenticate(CachingAuthenticatorDecorator.java:30)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.followUpRequest(RetryAndFollowUpInterceptor.java:283)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:153)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at com.burgstaller.okhttp.AuthenticationCacheInterceptor.intercept(AuthenticationCacheInterceptor.java:37)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at com.xxxxxxx.xxxxxx.singleton.HTTPClient$1.intercept(HTTPClient.java:64)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
at okhttp3.RealCall.access$100(RealCall.java:33)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:120)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)

Sounds like you are talking to a faulty server that sends a Digest challenge without a nonce, which would IMHO be illegal. Is there any way that you could capture a HTTP trace?

We have more than 100.000 sessions per day and we have just a few dozen reports, so I don't think it is the server. Also, older versions of the app, using a different lib for http (async-http) and the iOS version do not show the problem. I cannot reproduce it so I will not be able to capture a HTTP trace. I have other stack traces if you need. Let me know if you need any other info.

Some more info. Analysing the log files I noticed that the error happens after some calls, i.e., it is not the first call. Here a different stack trace, with a different error message. Perhaps it is related.

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.burgstaller.okhttp.digest.DigestAuthenticator.createDigestHeader(DigestAuthenticator.java:289)
at com.burgstaller.okhttp.digest.DigestAuthenticator.authenticateWithState(DigestAuthenticator.java:190)
at com.burgstaller.okhttp.digest.DigestAuthenticator.authenticate(DigestAuthenticator.java:148)
at com.burgstaller.okhttp.DispatchingAuthenticator.authenticate(DispatchingAuthenticator.java:45)
at com.burgstaller.okhttp.CachingAuthenticatorDecorator.authenticate(CachingAuthenticatorDecorator.java:30)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.followUpRequest(RetryAndFollowUpInterceptor.java:283)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:153)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at com.burgstaller.okhttp.AuthenticationCacheInterceptor.intercept(AuthenticationCacheInterceptor.java:37)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at com.xxxxxxx.xxxxxxx.singleton.HTTPClient$1.intercept(HTTPClient.java:64)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
at okhttp3.RealCall.access$100(RealCall.java:33)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:120)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

I am 99% certain that your server is sometimes not sending out a nonce which IMHO is not legal

https://tools.ietf.org/html/rfc2617#section-3.2.1

I can add some more logging so that the exception would also print out the WWW-authenticate header which would clarify this issue.

one more thing, are you using the authenticator on multiple threads in parallel? I can see an issue if you are running multiple threads and there is a race between the first one (for the caching) and the subsequent one.

I have added some preliminary improvements for multi-threaded operation.

Indeed, it is possible that sometimes multiple threads can be running making requests. If you add some logging I can generate a new build and upload it to the store.

I haven't released a new version yet but if you can build the lib yourself you can try the current master, this should add some concurrency protection so it should work better.

I am trying to add the master to gradle but it always fail. Checking JitPack there is a report informing that there is an error in the build script.

the build works fine on the CI environment. Are you sure you are building with gradlew?

I am using the following line in my gradle file.

compile 'com.github.rburgst:okhttp-digest:master-SNAPSHOT'

Jitpack log shows an error when I build my project.

That won't work as I don't release snapshots to bintray. I will release a version for you.

Thanks!

done, please upgrade to 1.8 and let me know if it fixes the problem.

The new build was released and till now no more reports. So I think it solved the problem. Thank you very much!

In the last 24 hours I haven't received any report. In the previous version I received more than 3000 reports. I just received with the new version one report, but with a different message (null object reference). Do you want the stack trace?

sure thing.

ava.lang.NullPointerException: Attempt to invoke virtual method 'byte[] java.lang.String.getBytes(java.lang.String)' on a null object reference
at com.burgstaller.okhttp.digest.DigestAuthenticator.getBytes(DigestAuthenticator.java:452)
at com.burgstaller.okhttp.digest.DigestAuthenticator.createDigestHeader(DigestAuthenticator.java:335)
at com.burgstaller.okhttp.digest.DigestAuthenticator.authenticateWithState(DigestAuthenticator.java:197)
at com.burgstaller.okhttp.DispatchingAuthenticator.authenticateWithState(DispatchingAuthenticator.java:55)
at com.burgstaller.okhttp.AuthenticationCacheInterceptor.intercept(AuthenticationCacheInterceptor.java:32)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at com.xxxxxxxxx.xxxxx.singleton.HTTPClient$1.intercept(HTTPClient.java:64)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:170)
at okhttp3.RealCall.access$100(RealCall.java:33)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:120)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)