Returning from my vacation abroad, I had to fill out a COVID declaration form on the Israeli Health Ministry website. Something looked weird when I filled it out on my mobile: It was too quick to indicate that I’m vaccinated, and this output came up even with a typo in my passport number. Hence I decided to take a closer look at that form’s APIs.
One of the endpoints there took in an ID number, first name, last name, passport number and session ID, and returned my vaccination status with an expiry date.
How One AI-Driven Media Platform Cut EBS Costs for AWS ASGs by 48%
That API endpoint was off; as it turns out, I could redact all fields except my (or any) ID number and still get the vaccination status back. Meaning, all I needed in order to know someone’s vaccine status was their ID number.
In Israel, ID numbers are considered a very weak and hardly-private PII: Unlike social security numbers, you use your ID almost anywhere – including payment providers, point-of-sale etc. Also, databases containing data on most of Israel’s population have leaked in the past. So, theoretically, if I had that ID database, I could fetch and download the vaccine data of all Israeli citizens, one ID at a time, within a day or so. However, unlike ID numbers, vaccination status is medical information, which is obviously considered private and should be treated as such. Hence I immediately contacted the Israeli Ministry of Health to fix that endpoint.
Below are the full API requests that yielded the vaccination data.
API Response: Non-Vaccinated ID
url 'https://corona.health.gov.il/api/corona/flight/certificate/check' \
-H 'Connection: keep-alive' \
-H 'Cache-Control: no-cache' \
-H 'sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"' \
-H 'X-PHONE-NUMBER: +97250xxxxx' \
-H 'Accept-Language: he' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' \
-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
-H 'Accept: application/json' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'X-PASSPORT-NUMBER: 1231231231' \
-H 'X-USER-ID: 0xxxxxxx' \
-H 'Origin: https://corona.health.gov.il' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Referer: https://corona.health.gov.il/flights/' \
--data-raw 'IDType=1&IDNum=xxxxxxx \
--compressed
Output:
{
"CovidStatusResponse": {
"Result": {
"StatusCode": "CompletSuccessfully",
"StatusDesc": "CompletSuccessfully"
},
"ExpirationDate": null,
"CertificateEligibilityType": 0
}
}
API Response: Vaccinated IDs
curl 'https://corona.health.gov.il/api/corona/flight/certificate/check' \
-H 'Connection: keep-alive' \
-H 'Cache-Control: no-cache' \
-H 'sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"' \
-H 'X-PHONE-NUMBER: +97250xxxxx' \
-H 'Accept-Language: he' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' \
-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
-H 'Accept: application/json' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'X-PASSPORT-NUMBER: 1231231231' \
-H 'X-USER-ID: 0xxxxxxx' \
-H 'Origin: https://corona.health.gov.il' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Referer: https://corona.health.gov.il/flights/' \
--data-raw 'IDType=1&IDNum=xxxxxxxx' \
--compressed
Output:
{
"CovidStatusResponse": {
"Result": {
"StatusCode": "CompletSuccessfully",
"StatusDesc": "CompletSuccessfully"
},
"ExpirationDate": "2021-12-31T23:59:59",
"CertificateEligibilityType": 2
}
}
Notes & Conclusion
First and foremost, I want to thank gov.il’s security team for acknowledging and mitigating the vulnerability in record time.
It is important to note that we see these vulnerabilities on a daily basis, and that is also the main reason our API Security solutions use big data and anomaly detection instead of API schema validation and static rate limits. Our solutions learn how our APIs behave and trigger an automated response once we spot an anomaly. In the case I described above, the anomaly would trigger once we saw that the endpoint responded without fields that should be there according to what we learned from traffic to that endpoint.
At GlobalDots, we see API security as key component of a proper web security stack. As such, we equip our customers with the API security solutions which fit them best – and which we believe to be the spearhead of this evolving category.
Contact us for more information.