Misconfigured or malicious servers can easily crash an openid based app
sonashannon opened this issue · 0 comments
Checklist:
- [x ] I am using the latest release
- [x ] I searched for existing GitHub issues
- [x ] I read the documentation
- [ x] I verified the client configuration matches the information in the identity provider (or I am using dynamic client registration)
- [x ] I am either using a custom URI scheme or
https
with App Links for client redirect. - I can reproduce the issue in the demo app (optional)
Configuration
- Version: latest
- Integration: java
- Identity provider: custom
Issue Description
The specific error is as follows:
- Create a misconfigured server that returns a blank refresh_token.
- Use openID to call the token endpoint
- App crashes with this trace:
E/AndroidRuntime(17080): java.lang.IllegalArgumentException: refresh token must not be empty if defined
E/AndroidRuntime(17080): at net.openid.appauth.Preconditions.checkArgument(Preconditions.java:116)
E/AndroidRuntime(17080): at net.openid.appauth.Preconditions.checkNotEmpty(Preconditions.java:68)
E/AndroidRuntime(17080): at net.openid.appauth.Preconditions.checkNullOrNotEmpty(Preconditions.java:89)
E/AndroidRuntime(17080): at net.openid.appauth.TokenResponse$Builder.setRefreshToken(TokenResponse.java:305)
E/AndroidRuntime(17080): at net.openid.appauth.TokenResponse$Builder.fromResponseJson(TokenResponse.java:222)
E/AndroidRuntime(17080): at net.openid.appauth.AuthorizationService$TokenRequestTask.onPostExecute(AuthorizationService.java:688)
E/AndroidRuntime(17080): at net.openid.appauth.AuthorizationService$TokenRequestTask.onPostExecute(AuthorizationService.java:579)
E/AndroidRuntime(17080): at android.os.AsyncTask.finish(AsyncTask.java:771)
E/AndroidRuntime(17080): at android.os.AsyncTask.access$900(AsyncTask.java:199)
E/AndroidRuntime(17080): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
E/AndroidRuntime(17080): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(17080): at android.os.Looper.loopOnce(Looper.java:226)
E/AndroidRuntime(17080): at android.os.Looper.loop(Looper.java:313)
E/AndroidRuntime(17080): at android.app.ActivityThread.main(ActivityThread.java:8751)
E/AndroidRuntime(17080): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(17080): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
E/AndroidRuntime(17080): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
I/Process (17080): Sending signal. PID: 17080 SIG: 9
The problem appears to be here at around line 688 of AuthorizationService:
TokenResponse response;
try {
response = new TokenResponse.Builder(mRequest).fromResponseJson(json).build();
} catch (JSONException jsonEx) {
mCallback.onTokenRequestCompleted(null,
AuthorizationException.fromTemplate(
GeneralErrors.JSON_DESERIALIZATION_ERROR,
jsonEx));
return;
}
Note that the catch block is only catching json exceptions. The IllegalArgumentException is never caught.
But this raises a bigger problem with the whole onPostExecute() function. Shouldn't the whole thing be wrapped with a try-catch block? The way it works now is any exception thrown that is not caught by the specialized try-catch blocks will crash the app. It permits malicious servers to bring down apps using openid at will. That should never happen.