MySejahtera is a Perfectly Good App With No Exploits

MySejahtera is a Perfectly Good App With No Exploits

To those that are unfamiliar with “MySejahtera”, the official description of the app is as follows:

MySejahtera is an application developed by the Government of Malaysia to assist in monitoring COVID-19 outbreak in the country by empowering users to assess their health risk against COVID-19. This application also provides the Ministry of Health (MOH) with the necessary information to plan for early and effective countermeasures.

While I only have brief experience with the app for about 2 months when I was in Malaysia last year, I would say the app had achieved its objective given the time used to develop the app.

My issue started when I get to know that those who received the COVID-19 vaccine overseas can apply for a digital certificate via the “MySejahtera” helpdesk.

I followed the instruction and was led to the following address (web app).

I have to fill in the relevant information, like vaccination date, batch number etc. Everything seems to works fine till it doesn’t. I got this cryptic error that says my file is not a PDF file when I try to submit my request.

Initially, I thought there was something wrong with my browser, so I switched to Edge, and it got the same error. There were a couple of complaints in the Facebook group as well, where most users end up submit screenshots of their vaccination certificate.

Putting on my detective’s hat, I opened up the good old Chrome Developer Tools and dig through the code.

Okay, so now we know that validateAndSubmitVaccinationOverseasRequest() function is called when submit button is clicked.

validateAndSubmitVaccinationOverseasRequest() then calls validateUploadFile() to validate the file type.

So validateUploadFile() is checking the file type by checking the extension(suffix) part of the file name, which is what I’ll do for client-side validation as well.

And to my horror, the culprit is actually in the fileExtArr array that string of the allowed extension. So someone might have forgotten to add that “pdf” string. No biggie, a silly mistake like this happens once in a while.

Not till I realize that the developer might not have fully tested the feature that is being shipped. A simple unit test would’ve captured this way before it got to production. I’ve submitted a description of the error through the helpdesk for them to fix it.

What's Next?

What to do while waiting for the fix? Can I submit it directly through the API endpoint?

The answer is yes, it is a POST request and the endpoint is

Not the most obvious way to identify a resource per RESTful API, but I can live with this.

A simple post request, and viola! I’ve successfully submitted my request!

There are a few quirks I found out.

1. All information filled in the request is stored in content as an HTML string and it gets sent back as an email. It doesn’t make sense why the developer would do this as it creates more overhead (albeit small) for the HTTP call. It is also harder to parse this as compared to a key-value pair solution (I guess they didn’t even use this information in their backend at all).

2. You can use this endpoint to “send an email on behalf of MySejahtera”. Imagine a malicious attempt to scare people using this exploit?

Time to rickroll

3. No Authentication token is required to make the call. Only Content-Type header is required.

4. There is no rate limit imposed on the endpoint. I hope they did implement some mechanism to ignore such requests.

Load Test FTW!

If you’re curious, following is the curl command you can use to call the API Endpoint.

The information above is valid as of 16 October 2021.

Update 1: As of 18 October 2021, reCAPTCHA had been added to submit page, but PDF error remains.

Got time to add reCAPTCHA but no time to add “pdf” to array?

Also as reported in the news