🛡️ Sentinel: [HIGH] Fix XSS in status_dashboard.html (#913)

* 🛡️ Sentinel: [HIGH] Fix XSS in status_dashboard.html

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>

* fix: address status dashboard xss review nits

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Co-authored-by: Christian Krakau-Louis <christian@Christians-Mac-mini-7.local>
This commit is contained in:
Christian Krakau-Louis
2026-06-01 05:40:53 +02:00
committed by GitHub
parent 98252e06c3
commit 425805ab23
2 changed files with 19 additions and 36 deletions
+15 -6
View File
@@ -393,6 +393,16 @@ const i18nStrings = {
configureNow: {{ _("status.configure_now") | tojson }},
};
function escapeHtml(str) {
if (!str) return '';
return String(str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
document.addEventListener('DOMContentLoaded', function() {
// Modal elements
const resultModal = document.getElementById('resultModal');
@@ -469,9 +479,8 @@ document.addEventListener('DOMContentLoaded', function() {
const isSensitive = sensitiveKeys.some(sKey => key.toLowerCase().includes(sKey));
if (isSensitive && value !== 'Not set' && value !== '') {
valueCell.textContent = value.slice(4) + '********' + value.slice(-4);
// For better readability, we can also use HTML to mask the middle part of the string
valueCell.innerHTML = value.slice(0, 4) + '<span class="text-gray-400">********</span>' + value.slice(-4);
valueCell.innerHTML = escapeHtml(value.slice(0, 4)) + '<span class="text-gray-400">********</span>' + escapeHtml(value.slice(-4));
} else {
valueCell.textContent = value;
}
@@ -586,9 +595,9 @@ document.addEventListener('DOMContentLoaded', function() {
if (data.status === 'success') {
// If there's token info, we need to handle it specially
if (data.token_info && data.token_info.expires_in_human) {
let message = data.message || 'Connection successful';
let message = escapeHtml(data.message || 'Connection successful');
message += `<br><br><div class="bg-blue-50 p-3 rounded mt-2">
<span class="font-medium">${i18nStrings.tokenValidFor}</span> ${data.token_info.expires_in_human}
<span class="font-medium">${i18nStrings.tokenValidFor}</span> ${escapeHtml(data.token_info.expires_in_human)}
</div>`;
modalTitle.textContent = i18nStrings.testSuccessful;
@@ -647,12 +656,12 @@ document.addEventListener('DOMContentLoaded', function() {
.then(data => {
if (data.status === 'success') {
// Create successful message
let message = data.message || 'Connection successful';
let message = escapeHtml(data.message || 'Connection successful');
// Add token expiration info if available (especially for Google Drive)
if (data.token_info && data.token_info.expires_in_human) {
message += `<br><br><div class="bg-blue-50 p-3 rounded mt-2">
<span class="font-medium">${i18nStrings.tokenValidFor}</span> ${data.token_info.expires_in_human}
<span class="font-medium">${i18nStrings.tokenValidFor}</span> ${escapeHtml(data.token_info.expires_in_human)}
</div>`;
// Show the message with HTML