Part 1 — MySejahtera is a Perfectly Good App With No Exploits
Part 2 — MySejahtera is a Perfectly Good App With No Exploits — Part 2
Final — MySejahtera is a Perfectly Good App With No Exploits — Final (Dual Fix Ver )
The series was supposed to be over, I promised myself to stop looking for more exploits with “MySejahtera”. But trust me, this exploit came to me, and it is kinda BIG.
So I was travelling back to Malaysia via flight. While being processed by personnel from the Ministry of Health (The frontliners), all travellers were asked to open “MySejahtera” or use a QR Code scanner to scan the typical “MySejahtera QR Code”.
The QR Code links to something like this:
Nothing out of the ordinary, just the usual information about yourself, mode of transportation and vaccination status.
Once checked in, the travellers were then asked to line up to show the frontline our documents (Like pre-departure PCR, whether you're going to home quarantine) and get our lovely pink tag (denoting we’re “Person Under Surveillance” aka “Under Quarantine).
The interesting thing I noticed is, there are no computers, the frontliners did not use any gadgets. But my status in “MySejahtera” had turned from the usual “Low Risk No Symptom” to “Person Under Surveillance (PUS)”.
I did play around with the QR Code check-in APIs before, there is no validation on the server-side, you can submit check-in to locations that don’t exist.
I quickly open up the link and check what are the APIs call made during the submission. The call was made to
with the following schema:
The name
, contact
, userStatus
and tenant
seems interesting, my wild guess is that:
name
is the name registered in “MySejahtera”contact
is either the phone number or email address used to register for “MySejahtera”userStatus
could be aenum
of status that exists on server-sidetenant
is the unique id for the check-in location
I created a few dummy “MySejahtera” account using email to test if this particular API call change the status on the app. After a couple of minutes of tinkering, Tadaa:
The worse thing about this? There is absolutely ZERO server-side validation. Forget about the schema we talked about earlier, just send contact
and it will work. And as we know, contact
can be in the form of phone numbers, some bad actor could’ve just enumerated the number so everyone become “PUS”
A simple server-side validation and admin portal where authorised personnel approve the change of status would’ve avoided this exploit.
Benefits of being “PUS”? You can legitimately tell your boss you can’t go to the office for the next 7 days😎.
Now, everyone can become “PUS” like me with a simple curl
.
Update 1: Apparently tenant
and createDate
will trigger “Home Surveillance Order”.
Update 2: The endpoint had been taken down. While checking the qrscan
page.
The TRAVELLER
and TRAVEL_QUARANTINE
endpoint was always there.
In theory, one does not need to get the QR Code at the port of entry. Just simply call
https://mysejahtera.malaysia.gov.my/qrscan/?formType=TRAVELLER
and within the JS code, you will be able to know the exact API that was used for this exploit.
As of 7/11/2021, /clockinTraveller
and clockinTravellerQuarantine
had been removed and will return NOT FOUND 404
. But you will be able to get the successful check-in page as that was just a render on Frontend which doesn’t depend on a successful response from the backend.
As reported in the news
https://malaysia.news.yahoo.com/complaints-health-ministry-says-sorry-014832037.html