Race condition in repackaged Base64 breaks auths at random
envgap__auth0__java-jwt-69
01 / FAILURE SIGNATURE
As reported upstream
No identifying execution failure has been captured.
Not a benchmark task.
- The project already builds and runs before the fix, so there is nothing to repair.
02 / ENVIRONMENT RECIPE
- Base commit
217af05d16d62e462f5fa4456c090c1af9e1a51e- Manifest
pom.xml- Reproduce
Awaiting issue-specific recipe- Run under trace
Awaiting a meaningful runtime command
03 / ORIGINAL ISSUE TEXT
auth0/java-jwt #69 · read the original issue
After updating our auth0 libs to pull in some important fixes, we started having random authentication failures that would not reproduce.
Turns out that `JWTVerifier.decodeAndParse()` was failing with IOException from time to time.
Diagnosis: the base64 decoder used is not thread safe. For some reason you repackaged a buggy commons-codec.
PS: This took me almost a whole day to nail down and it's a blocker for us.
Proof of concept:
```
import com.auth0.jwt.internal.org.apache.commons.codec.binary.Base64;
public class Poc {
public static void main(String... args) throws Exception {
final int threads = 2;
String[] tokens = new String[] {
"eyJyb2xlcyI6WyIqIiwiY29tcGFueS4wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiXSwiY29tcGFueUlkIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIiwidXNlcklkIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtNzU3MzY1NzIwMDAwIiwidXNlcm5hbWUiOiJyb290IiwiZW1haWwiOiJyb290LWRldkB0aWVycmEuaW8iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInVzZXJfaWQiOiJhdXRoMHw1NzkwYTcyNTYzMjkyYjY5NmZlMjEwZWUiLCJpc3MiOiJodHRwczovL3RpZXJyYS1pb3QuYXV0aDAuY29tLyIsInN1YiI6ImF1dGgwfDU3OTBhNzI1NjMyOTJiNjk2ZmUyMTBlZSIsImF1ZCI6Im9SdkJHVFRQV0JFekVDNTU5aUFXRGt6M3MyMWNVNkJ3IiwiZXhwIjoxNDcxNjI5MDc0LCJpYXQiOjE0NzE1OTMwNzR9",
"eyJyb2xlcyI6WyIqIiwiY29tcGFueS4wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiXSwiY29tcGFueUlkIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwIiwidXNlcklkIjoiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtNzU3MzY1NzIwMDAwIiwidXNlcm5hbWUiOiJyb290IiwiZW1haWwiOiJ4QHRpZXJyYS5pbyIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwidXNlcl9pZCI6ImF1dGgwfDU3OTBhNzI1NjMyOTJiNjk2ZmUyMTBlZiIsImlzcyI6Imh0dHBzOi8vdGllcnJhLWlvdC5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NTc5MGE3MjU2MzI5MmI2OTZmZTIxMGVlIiwiYXVkIjoib1J2QkdUVFBXQkV6RUM1NTlpQVdEa3ozczIxY1U2QnciLCJleHAiOjE0NzE2MjkwNzQsImlhdCI6MTQ3MTU5MzA3NH0="
};
final Base64 decoder = new Base64(true);
for (int i = 0; i < threads; i++) {
final String b64String = tokens[i % tokens.length];
final String expected = new String(decoder.decode(b64String), "UTF-8"); // no concurrency here
(new Thread() {
@Override
public void run() {
System.err.println("Starting thread");
try {
while (true) {
final String jsonString = new String(decoder.decode(b64String), "UTF-8");
if (!expected.equals(jsonString)) {
System.err.println("BUG: got <" + jsonString + ">, expected + <" + expected + ">");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.exit(1);
}
}).start();
}
}
}
```
04 / LABELS
Labels from the report text only; not yet run
No supported category has been assigned.
Label rules and the text that matched
[]