How I got access to 38M+ DigiLocker accounts

ashish gahlot
5 min readJun 1, 2020

NOTE: The vulnerability has been patched.

Impact

Backstory

So the story starts when my father wanted to upload all my personal documents to DigiLocker as through that we don’t have to carry our original documents to trains or airports for verification. There are currently 389 different types of documents that are officially supported by DigiLocker (Aadhaar Card, Driving License, etc.,) but of course, you can upload more documents as the given locker space is 1GB allocated to each user. I was little skeptical doing this because the history has shown that there have been numerous instances when the Aadhaar document along with other documents have been leaked because of improper security implementation.

Analysis

So I started to have a look how the authentication mechanism is implemented.

We can either sign in if we already have an account or we can create our new account. Let’s start with our already registered account.

As we can see it from the above picture that we can login by using our Aadhaar/Mobile/Username. The OTP it sent to the mobile number which was registered with Aadhaar which is a six digit number. After entering the OTP, we have to provide the six digit PIN which we have set during the signup process.

The request/response in burp suite looks like this:

Sign in request
Correct PIN gives back the username
Incorrect PIN response
Incorrect PIN cannot request the Aadhaar profile

After entering our PIN we land at the main dashboard of our locker.

During this sign in process I first tried to bypass the OTP and PIN verification but did not succeed. After that I went forward with the signup process.

The request in burp looks like this:

In this process it asks us to enter the Aadhaar Number and it you are already registered then it will show this:

When we input a correct PIN we get the following response:

Here I have observed from my limited experiments (by taking Aadhaar Numbers from my family of course ;) ) that the username can be a GUID, a phone number or a combination of letters and numbers which are similar to Facebook username that can be used to identify and find you.

Now the thing is I don’t remember writing anything related to username in Aadhaar form and what I was getting was a username which I generally use at places. And it surely it is picking up from the Aadhaar data as it does not as for such detail during the signup process. If someone remembers such detail, please let me know :).

If you don’t have a saved session in your computer, before asking the PIN, it also asks you the OTP that is sent to your mobile.

OTP during sign up process

NOTE: We are still using a registered Aadhaar number but it also works for unregistered profiles.

Now we type in a random OTP and have a look at the response.

Random OTP
OTP verification request
OTP verification response

Now if we remember from the sign in response it looked like this:

{"status":"success","username":"xxxxxxxx"}

Let’s edit the response and send it.

We now land at a page which asks for setting a new PIN instead of typing in our previously set PIN. This not only changes the previous PIN of the user but also gives complete access to the Locker.

When we set the PIN the POST request looks like this:

POST /signup/set_pin HTTP/1.1
Host: accounts.digitallocker.gov.in
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-type: application/x-www-form-urlencoded
Content-Length: 38
Origin: https://accounts.digitallocker.gov.in
Connection: close
Referer: https://accounts.digitallocker.gov.in/signup
Cookie: SRVNAME=S4; fpdglckr=; DLOCKER=<redacted>
&pin=xxxxxx&txn=<username>&flow=signup

So we can just write a python script to craft the above request and by just knowing the username we can change the password of ANY USER ;).

Extra Weirdness

As we remember when we bypass the OTP and modify the response it looked like this:

What happens if we don’t enter a username and just send

{"status":"success"}

Well, something weird happens, the POST request then look like this:

POST /signup/set_pin HTTP/1.1
Host: accounts.digitallocker.gov.in
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-type: application/x-www-form-urlencoded
Content-Length: 38
Origin: https://accounts.digitallocker.gov.in
Connection: close
Referer: https://accounts.digitallocker.gov.in/signup
Cookie: SRVNAME=S4; fpdglckr=; DLOCKER=<redacted>
&pin=xxxxxx&txn=undefined&flow=signup

And a very specific profile just opens. I tried it a number of times thinking that there may be more undefined usernames in the database but it looks like there was only one.

Disclosure

  • 2020/05/16: Reported technical details to DigiLocker
  • 2020/05/18: DigiLocker fixes PIN bypass
  • 2020/06/01: DigiLocker fixes OTP bypass

Credits

Thank you my friend Osanda for proof reading :)

--

--