Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions sqli/static/js/materialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,11 @@
}var f,
d = function () {
if (r.documentMode) return r.documentMode;for (var e = 7; e > 4; e--) {
var t = r.createElement("div");if (t.innerHTML = "<!--[if IE " + e + "]><span></span><![endif]-->", t.getElementsByTagName("span").length) return t = null, e;
var t = r.createElement("div");
// Ensure e is a valid number between 4-11 (common IE versions)
if (typeof e !== 'number' || e < 4 || e > 11) return a;
t.textContent = "<!--[if IE " + e + "]><span></span><![endif]-->";
if (t.getElementsByTagName("span").length) return t = null, e;
}return a;
}(),
g = function () {
Expand Down Expand Up @@ -803,7 +807,7 @@
var e;if (a) if (a.forEach) a.forEach(b, c);else if (a.length !== d) for (e = 0; e < a.length;) {
b.call(c, a[e], e, a), e++;
} else for (e in a) {
a.hasOwnProperty(e) && b.call(c, a[e], e, a);
Object.prototype.hasOwnProperty.call(a, e) && b.call(c, a[e], e, a);
}
}function n(a, b, c) {
for (var e = Object.keys(b), f = 0; f < e.length;) {
Expand Down Expand Up @@ -1023,7 +1027,9 @@
vb = "pointermove pointerup pointercancel";a.MSPointerEvent && (ub = "MSPointerDown", vb = "MSPointerMove MSPointerUp MSPointerCancel"), p(wb, ab, { handler: function (a) {
var b = this.store,
c = !1,
d = a.type.toLowerCase().replace("ms", ""),
d = a.type.split(" ").map(function(word) {
return word.replace(/^MSPointer/i, "pointer").toLowerCase();
}).join(" "),
e = sb[d],
f = tb[a.pointerType] || a.pointerType,
g = f == J,
Expand Down Expand Up @@ -2847,7 +2853,22 @@

// Create Text span
if (allowHtml) {
tooltipText = $('<span></span>').html(tooltipText);
// Sanitize HTML content to prevent XSS
var sanitizeHTML = function(html) {
var div = document.createElement('div');
div.textContent = html;
// Only allow safe tags and attributes
var sanitized = div.innerHTML
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove script tags
Comment on lines +2861 to +2862

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
<script
, which may cause an HTML element injection vulnerability.

Copilot Autofix

AI 9 months ago

To fix the problem, we need to ensure that the sanitization process is thorough and handles all potential cases of unsafe content. One effective way to achieve this is to apply the regular expression replacements repeatedly until no more replacements can be performed. This ensures that all instances of the targeted patterns are removed, even if they are nested or obfuscated.

We will modify the sanitizeHTML function to repeatedly apply the regular expression replacements until the input no longer changes. This approach will ensure that all unsafe content is fully sanitized.

Suggested changeset 1
sqli/static/js/materialize.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/sqli/static/js/materialize.js b/sqli/static/js/materialize.js
--- a/sqli/static/js/materialize.js
+++ b/sqli/static/js/materialize.js
@@ -2860,11 +2860,15 @@
             // Only allow safe tags and attributes
-            var sanitized = div.innerHTML
-              .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove script tags
-              .replace(/javascript:/gi, '') // Remove javascript: URLs
-              .replace(/onerror=/gi, '')  // Remove onerror handlers
-              .replace(/onload=/gi, '')   // Remove onload handlers
-              .replace(/onclick=/gi, '')   // Remove onclick handlers
-              .replace(/onmouseover=/gi, '') // Remove mouseover handlers
-              .replace(/data-/gi, 'data-safe-'); // Namespace data attributes
-            return sanitized;
+            var sanitized;
+            do {
+              sanitized = div.innerHTML;
+              div.innerHTML = sanitized
+                .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove script tags
+                .replace(/javascript:/gi, '') // Remove javascript: URLs
+                .replace(/onerror=/gi, '')  // Remove onerror handlers
+                .replace(/onload=/gi, '')   // Remove onload handlers
+                .replace(/onclick=/gi, '')   // Remove onclick handlers
+                .replace(/onmouseover=/gi, '') // Remove mouseover handlers
+                .replace(/data-/gi, 'data-safe-'); // Namespace data attributes
+            } while (sanitized !== div.innerHTML);
+            return div.innerHTML;
           };
EOF
@@ -2860,11 +2860,15 @@
// Only allow safe tags and attributes
var sanitized = div.innerHTML
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove script tags
.replace(/javascript:/gi, '') // Remove javascript: URLs
.replace(/onerror=/gi, '') // Remove onerror handlers
.replace(/onload=/gi, '') // Remove onload handlers
.replace(/onclick=/gi, '') // Remove onclick handlers
.replace(/onmouseover=/gi, '') // Remove mouseover handlers
.replace(/data-/gi, 'data-safe-'); // Namespace data attributes
return sanitized;
var sanitized;
do {
sanitized = div.innerHTML;
div.innerHTML = sanitized
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove script tags
.replace(/javascript:/gi, '') // Remove javascript: URLs
.replace(/onerror=/gi, '') // Remove onerror handlers
.replace(/onload=/gi, '') // Remove onload handlers
.replace(/onclick=/gi, '') // Remove onclick handlers
.replace(/onmouseover=/gi, '') // Remove mouseover handlers
.replace(/data-/gi, 'data-safe-'); // Namespace data attributes
} while (sanitized !== div.innerHTML);
return div.innerHTML;
};
Copilot is powered by AI and may make mistakes. Always verify output.
.replace(/javascript:/gi, '') // Remove javascript: URLs
.replace(/onerror=/gi, '') // Remove onerror handlers
.replace(/onload=/gi, '') // Remove onload handlers
.replace(/onclick=/gi, '') // Remove onclick handlers
.replace(/onmouseover=/gi, '') // Remove mouseover handlers
.replace(/data-/gi, 'data-safe-'); // Namespace data attributes
Comment on lines +2861 to +2868

Check failure

Code scanning / CodeQL

Incomplete URL scheme check High

This check does not consider data: and vbscript:.

Copilot Autofix

AI 9 months ago

To fix the problem, we need to extend the URL scheme check to include data: and vbscript: schemes in addition to javascript:. This will ensure that any URL starting with these schemes is sanitized to prevent code injection. The best way to fix this is to modify the sanitizeHTML function to include these additional checks.

We will update the sanitizeHTML function to replace data: and vbscript: schemes in addition to javascript:. This change will be made in the file sqli/static/js/materialize.js on line 2863.

Suggested changeset 1
sqli/static/js/materialize.js

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/sqli/static/js/materialize.js b/sqli/static/js/materialize.js
--- a/sqli/static/js/materialize.js
+++ b/sqli/static/js/materialize.js
@@ -2863,2 +2863,4 @@
               .replace(/javascript:/gi, '') // Remove javascript: URLs
+              .replace(/data:/gi, '') // Remove data: URLs
+              .replace(/vbscript:/gi, '') // Remove vbscript: URLs
               .replace(/onerror=/gi, '')  // Remove onerror handlers
EOF
@@ -2863,2 +2863,4 @@
.replace(/javascript:/gi, '') // Remove javascript: URLs
.replace(/data:/gi, '') // Remove data: URLs
.replace(/vbscript:/gi, '') // Remove vbscript: URLs
.replace(/onerror=/gi, '') // Remove onerror handlers
Copilot is powered by AI and may make mistakes. Always verify output.
return sanitized;
};
tooltipText = $('<span></span>').html(sanitizeHTML(tooltipText));
} else {
tooltipText = $('<span></span>').text(tooltipText);
}
Expand Down Expand Up @@ -3066,7 +3087,7 @@
var style = '';

for (var a in obj) {
if (obj.hasOwnProperty(a)) {
if (Object.prototype.hasOwnProperty.call(obj, a)) {
style += a + ':' + obj[a] + ';';
}
}
Expand Down Expand Up @@ -3119,7 +3140,7 @@

ripple.className = ripple.className + ' waves-notransition';
ripple.setAttribute('style', convertStyle(rippleStyle));
ripple.className = ripple.className.replace('waves-notransition', '');
ripple.className = ripple.className.replace(/waves-notransition/g, '');

// Scale the ripple
rippleStyle['-webkit-transform'] = scale;
Expand Down Expand Up @@ -3441,7 +3462,7 @@

// Insert as text;
} else {
toast.innerHTML = this.message;
toast.textContent = this.message;
}

// Append toasft
Expand Down Expand Up @@ -4725,7 +4746,7 @@

if (val.length >= options.minLength) {
for (var key in data) {
if (data.hasOwnProperty(key) && key.toLowerCase().indexOf(val) !== -1) {
if (Object.prototype.hasOwnProperty.call(data, key) && key.toLowerCase().indexOf(val) !== -1) {
// Break if past limit
if (count >= options.limit) {
break;
Expand Down Expand Up @@ -8586,9 +8607,10 @@
svgSupported = 'SVGAngle' in window && function () {
var supported,
el = document.createElement('div');
el.innerHTML = '<svg/>';
var svg = document.createElementNS(svgNS, "svg");
el.appendChild(svg);
supported = (el.firstChild && el.firstChild.namespaceURI) == svgNS;
el.innerHTML = '';
el.innerHTML = ''; // This clear is still safe as it's just emptying the element
return supported;
}();

Expand Down Expand Up @@ -8923,7 +8945,7 @@
} else {
this.amOrPm = 'PM';
}
value[1] = value[1].replace("AM", "").replace("PM", "");
value[1] = value[1].replace(/AM/g, "").replace(/PM/g, "");
}
if (value[0] === 'now') {
var now = new Date(+new Date() + this.options.fromnow);
Expand Down