summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfishystock <215427190+fishystock@users.noreply.github.com>2026-08-07 18:58:17 -0400
committerfishystock <215427190+fishystock@users.noreply.github.com>2026-08-07 19:54:02 -0400
commit65a993fe06abaadcbcb23f6c239db36eb6471954 (patch)
tree1eb3c2446d828594f91d85b6de815c85b1eea2e0
parent8118f7aa5c705382cfa5216a284929d7e1d6f0c8 (diff)
security: fix stored xss on calendar api
-rw-r--r--templates/themes/calendar/calendar.html14
-rw-r--r--templates/themes/calendar/calendarpost.php6
2 files changed, 19 insertions, 1 deletions
diff --git a/templates/themes/calendar/calendar.html b/templates/themes/calendar/calendar.html
index 12113dcd..4b5c99ae 100644
--- a/templates/themes/calendar/calendar.html
+++ b/templates/themes/calendar/calendar.html
@@ -55,6 +55,20 @@
} else {
event.allDay = false;
}
+
+ var _url = new URL(event.url, window.location.href);
+ var _scheme = _url.protocol.toLowerCase();
+
+ // Replace stored javascript/data URI attempts
+ if(_scheme === 'javascript:' || _scheme === 'data:') {
+ event.url = "#removed";
+ }
+
+ // Only accept #a-zA-Z to avoid CSS injection.
+ if (/^[#a-zA-Z]+$/.test(event.color) == false) {
+ event.color = "#removed";
+ }
+
element.find('.fc-title').append("<br/>" + event.description);
element.css('background-color',event.color);
},
diff --git a/templates/themes/calendar/calendarpost.php b/templates/themes/calendar/calendarpost.php
index ac2c1a72..7ad9377a 100644
--- a/templates/themes/calendar/calendarpost.php
+++ b/templates/themes/calendar/calendarpost.php
@@ -51,7 +51,11 @@ $method = $_SERVER['REQUEST_METHOD'];
} elseif ($method == 'GET') {
// Method is GET
$query = query("SELECT * FROM calendar_events ORDER BY id") or error(db_error());
- echo json_encode($query->fetchAll(PDO::FETCH_ASSOC), JSON_THROW_ON_ERROR);
+
+ header('Content-Type: application/json; charset=utf-8');
+ header('X-Content-Type-Options: nosniff');
+
+ echo json_encode($query->fetchAll(PDO::FETCH_ASSOC), JSON_THROW_ON_ERROR);
}
?>