Improper Input Validation on User's Location on PUT /WhoService/putLocation Could Affect Availability/Falsify Users
Low
W
WHO COVID-19 Mobile App
Submitted None
Actions:
Reported by
spaceraccoon
Vulnerability Details
Technical details and impact analysis
## Summary:
Note: I noticed that that the team has fixed issues like an XSS that's caused only from a header value (typically OOS since it's not directly exploitable) https://github.com/WorldHealthOrganization/app/pull/855, so in the spirit of this I'm also reporting another "good-to-fix" issue.
On the WHO app, users send approximate location data to the `WhoService` API:
`/app/client/flutter/lib/pages/onboarding/location_sharing_page.dart`:
```
Future<void> _allowLocationSharing() async {
try {
await Location().requestPermission();
if (await Location().hasPermission() == PermissionStatus.granted) {
if (await Location().requestService()) {
LocationData location = await Location().getLocation();
Map jitteredLocationData = JitterLocation().jitter(
location.latitude, location.longitude,
5 /*kms refers to kilometers*/);
await WhoService.putLocation(
latitude: jitteredLocationData['lat'],
longitude: jitteredLocationData['lng']);
}
}
} catch(_) {
// ignore for now.
} finally {
_complete();
}
}
```
Which in turn translates to a call to `https://staging.whocoronavirus.org/WhoService/putDeviceToken`:
```
curl --request POST \
--url 'https://hackerone.whocoronavirus.org/WhoService/putLocation' \
--header 'content-type: application/json' \
--header 'who-client-id: ██████████' \
--header 'who-platform: ios' \
--data '{
"latitude": 22222222,
"longitude": "9999999"
}'
```
This returns a `200 OK` response. On the server side, we see that it uses the following logic:
```
@Override public Void putLocation(PutLocationRequest request) throws IOException {
Client client = Client.current();
client.latitude = request.latitude;
client.longitude = request.longitude;
S2LatLng coordinates = S2LatLng.fromDegrees(request.latitude, request.longitude);
client.location = S2CellId.fromLatLng(coordinates).id();
ofy().save().entities(client);
return new Void();
}
```
There is no validation on `request.latitude, request.longitude` before it is stored into the Google App Engine datastore. This is because the `S2LatLng.fromDegrees` (which transforms the values into a `S2LatLng` object) from the `s2-geometry-library-java` library specifically does not validate these values because, according to their comments at https://github.com/google/s2-geometry-library-java/blob/master/src/com/google/common/geometry/S2LatLng.java:
```
Like the rest of the "geometry" package, the
intent is to represent spherical geometry as a mathematical abstraction, so
functions that are specifically related to the Earth's geometry (e.g.
easting/northing conversions) should be put elsewhere.
```
Thus, even these values:
```
"latitude": 22222222,
"longitude": "9999999"
```
Are accepted and stored in the database even though they are technically non-existent coordinates on earth.
To reproduce, just run this request with different `who-client-id` UUID you generated yourself and impossible `latitude` and `longitude`.
```
curl --request POST \
--url 'https://hackerone.whocoronavirus.org/WhoService/putLocation' \
--header 'content-type: application/json' \
--header 'who-client-id: ████████' \
--header 'who-platform: ios' \
--data '{
"latitude": 22222222,
"longitude": "9999999"
}'
```
## Impact
An attacker can exploit this to affect the Availability or Integrity of the analytics data by injecting false location values and falsifying user data. A fix for this would be to implement a quick lat lng validator that is specifically meant to validate Earth geometry, instead of the `S2LatLng` class.
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Submitted
Weakness
Improper Input Validation