Case Study : CVE-2020–15957 vulnerability discovery in DP-3T COVID-19 contact tracing backend server
As COVID-19 expanded across the globe to hit most nations, wider interest in tracing real-life contacts through Bluetooth are quickly emerging. These include MIT’s SafePaths, Enigma’s SafeTrace or Covid Watch to name a few.
What digital beacons will apps use to trace proximity contacts? Current designs rely on a low power wireless technology known as BLE aka Bluetooth Low Energy which was introduced with Bluetooth 4.0. For tracing apps to work, the Smartphones must continuously broadcast BLE (Bluetooth Low Energy) signals and interoperate between phones regardless of their make. Most Smartphones are either on Apple iOS or Google Android. During normal times Androids and iPhones, being conduits to content, don’t play well together. But these are not normal times. Apple and Google announced a joint effort in contact tracing and published a preliminary specification. Unsurprisingly, it includes a section on privacy.
With great power comes great responsibility
Given the security and data requirement challenges shared by all impacted nations, a Pan-European initiative called PEPP-PT was set up to provide guidance in line with GDPR. PEPP-PT is a non-profit based in Switzerland with more than 130 members across eight European countries, including scientists, technologists, and experts from well-known international research institutions and companies.
It has spawned initiatives such as Decentralized Privacy-Preserving Proximity Tracing or DP-3T which is one possible protocol for supporting decentralized proximity tracing. In the US, PACT is a comparable protocol which will be available through the SafePaths app and seems to have benefitted from earlier work on Private Kit.
What is DP3T — Decentralized Privacy-Preserving Proximity Tracing?
DP-3T is a privacy-friendly, decentralized solution that reveals minimal information to the back-end server and relies a lot on end-to-end encryption.
In this architecture most of the computation needed will be done inside mobile phones and not on a central backend server. Every phone will be broadcasting and storing “bluetooth low energy” beacons: small 16-byte unique strings found around the ether. Now and then phones will process what they have collected to trace and proof the proximity of devices, therefore the proximity is limited by how far these bluetooth signals can reach.
The proximity tracing process is supported by a back-end server that shares infection information with the app running on each phone, but by means of cryptography it will not know who is who nor will be able to track people.
Its four phases are illustrated below:
- The installation includes set up of an application on a mobile phone which acts as a digital (EphIDs) dispenser and local storage unit.
- In step two, normal operations, the app does two things: it broadcasts EphIDs to other phones running the app and checks for news with the backend server.
- The third step addresses the handling of new known patients. They receive a token from a health authority and voluntarily use it to push their EphIDs to the backend server. The data is retained for a limited period of time.
- The fourth step describes the actual tracing. Apps retrieve published infection data and check encounters against locally stored graphs.
As our phones collect and share breadcrumb data from our proximity networks, privacy concerns arise. Privacy from snoopers, privacy from contacts and privacy from backend operators. There are several ways to define privacy itself. One example is through differential privacy. Differential privacy is an information-theoretical criterion in the context of statistical and machine learning analysis (i.e. where loads of data is captured.) It enables the collection, analysis, and sharing of statistical estimates such as averages or synthetic data, while preventing individual re-identification or record linkage.
These protocols are still work-in-progress and Apps assumed to be based on voluntary use.
Discovery of CVE-2020–15957
When dp3t-sdk-backend is configured to check a JWT before uploading/publishing keys, it was possible to skip the signature check by providing a JWT token with
This vulnerability would have permitted an attacker to upload his secret keys to the DP-3T backend server without authorization, which can lead users of the contact tracing app to mistakenly think that they have already been exposed to the virus.
This vulnerability was acknowledged and patched by the development team of dp3t, with associated CVE ID — CVE-2020–15957.
The patch consists on changing the
parseClaimsJws(String), to force the JWT to be signed as indicated in this change request https://github.com/DP-3T/dp3t-sdk-backend/pull/208/commits/e967592bf131442b9d9916aefac2f4e42eaddd32
Dp3t-sdk-backend is a sprint boot based java web application based on
- Java 11+ and Spring Boot 2.2.6
- JJWT (JSON Web Token for Java and Android)
- Spring Security OAuth
- .. amongst other dependencies
The twitter verse was in an uproar after the announcement and a set of interesting opinions followed
“JWT is fine and it’s your fault if you use it wrong” and other bullshit some security people will tell you.
“100% agree with this thread. It isn’t enough to design systems that can be used safely, you have to design systems that can’t be used unsafely”
To figure out what is the right way, one would have to comb through docs published by the committers of specific library, revised READMEs in the repo, advisories, blogs, stackoverflow etc . To illustrate the point, refer to the screenshot below from JJWT’s README file.
JJWT is a pure Java implementation based exclusively on the JWT, JWS, JWE, JWK and JWA RFC specifications and open source under the terms of the Apache 2.0 License. The library was created by Okta’s Senior Architect, Les Hazlewood and is supported and maintained by a community of contributors.
Despite of the fact that committers of JJWT library did their part by emphasizing use of
parseClaimsJws instead of
parse, yet CVE-2020–15957 happened
Added “are” to correct grammar (#605) · jwtk/jjwt@5c5f1b8
Java JWT: JSON Web Token for Java and Android. Contribute to jwtk/jjwt development by creating an account on GitHub.
So what is JWT and why is it relevant to DP3T ?
JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
JWT tokens consist of 3 parts separated by a period ( . ).
These parts are:
The header, called the JOSE header (JSON Object Signing and Encryption) specifies the algorithm used to sign and encrypt the token. Most JWTs are just signed and not encrypted. The most common algorithms are:
- HS256 (HMAC + SHA256)
- RS256 (RSASSA-PKCS1-v1_5 + SHA256)
- ES256 (ECDSA + P-256 + SHA256)
- iss (issuer),
- exp (expiration time),
- aud (audience),
- and others (optional)
"name": "Mark Spencer",
"sub": "Dispatch Payload",
The last part of the token is the signature. For HS256, this is calculated as follows:
HMAC-SHA256( base64urlEncoding(header) + '.' + base64urlEncoding(payload), secret)
Andre Cirne wrote a detailed blog post where he explains the vulnerability and substantiates it with a POC as well.
JWT Security Patterns
As practitioners become aware of software security’s importance, they are increasingly adopting and evolving a set of best practices to address the problem.
Such best practices are defined by experienced architects within an organization or by subject matter experts in the developer community.
It is therefore important to take certain security countermeasures into consideration when designing, testing, and releasing your JWT based authorization schemes
- The “none” algorithm. JWT specification allows for a “none” algorithm. Tokens using the “none” algorithm are considered as already verified by some implementations. To create such a token, set the algorithm in the decoded header to “none” and use an empty string as the signature. A past consequence of this vulnerability is CVE-2018–1000531 and CVE-2020–15957
- Use a random complicated key (
JWT Secret) to make brute forcing the token very hard.
- Don’t extract the algorithm from the header. Force the algorithm in the backend (
- Make token expiration (
RTTL) as short as possible.
- Don’t store sensitive data in the JWT payload
- Validate the incoming JWT token. You should do it, even if you’re working on an internal network — where the Authorization Server, the Client and the Resource Server aren’t connected through the Internet.
- Check the Issuer claim. if the token contains the
issclaim you should always confirm that any cryptographic keys used to sign or encrypt the token actually belong to the issuer.
- Check the Audience claim. An ID Token must contain the client ID in the
audclaim (though it can also contain other audiences)
- Verify Expiration, issued time and clock skew. the
expclaim, containing the expiration time, is not the only time-based claim that can be used for verification. The
nbfclaim contains a "not-before" time. The token should be rejected if the current time is before the time in the
nbfclaim. Another time-based claim is
iat- issued at. You can use this claim to reject tokens which you deem too old to be used with your resource server.
- Don’t use JWTs for sessions. JWTs where never considered for use with sessions, and using them in such a way may actually lower the security posture of your applications.
It’s not as simple to keep track of these security patterns for a specific component like JWT as there are many such libraries in the ecosystem and each of them adhere to their own implementation patterns. The problem exasperates when we are speaking of multiple open source components that we dependent on as we architect our applications. Each of these evolve/upgrade/deprecate in their own course of time.
Can such best practices be codified as a specification defined in adherence to how an open source framework or library should be used by its consumer?
Formulating Security-As-Code verification using ShiftLeft NG-SAST
While writing bug-free code is difficult it is even harder to prove that it is bug-free. Hence we define and continually evolve such a best practice driven security specification for OSS software (libraries/frameworks) authored and driven by expert-led communities/researchers and thereafter use such a specification to measure its adherence or lack thereof from an application standpoint.
Purpose-Built Developer Workflows in ShiftLeft’s NextGen Static Analysis
With our new release of NextGen Static Analysis (NG SAST), we’ve created a security workflow for developers that embodies the above lessons. It’s an automated security feedback loop with every pull request. The experience is similar to unit testing in that developers get immediate and accurate results all without leaving their development environment.
To learn more about ShiftLeft and how NG SAST can increase productivity and security in your organization, please:
- Request a demo here: https://go.shiftleft.io/request-a-demo
- Create a free account here: https://www.shiftleft.io/register
- Register for our “Making Security More Efficient for Developers” webinar here: https://go.shiftleft.io/webinar-making-security-more-efficient-for-developers