DHTMLX Gantt ist eine JavaScript-Bibliothek, die entwickelt wurde, um Gantt-Diagrammfunktionalität nahtlos in Webanwendungen zu integrieren. Sie bietet eine breite Palette an Anpassungsfunktionen, die Entwicklern ermöglichen, sie an ihre spezifischen Projektanforderungen anzupassen. Es ist jedoch wichtig zu beachten, dass DHTMLX Gantt keinen integrierten Schutz gegen Bedrohungen wie SQL-Injection, XSS oder CSRF-Angriffe bietet. Die Sicherheit Ihrer Anwendung sicherzustellen, erfordert, dass Sie die notwendigen Konfigurationen und Schutzmaßnahmen selbst implementieren. Nachfolgend finden Sie einige Empfehlungen für den effektiven Umgang mit HTML-Sanitisierung.
Cybersicherheit ist ein weites Feld, und kein einzelner Leitfaden kann alles abdecken. Das Befolgen dieser praktischen Schritte kann jedoch helfen, häufige Schwachstellen zu adressieren und Risiken zu verringern.
Das Hinzufügen eines CSP-Headers wie diesem kann die Ausführung von Inline-Skripten blockieren und das Risiko von XSS- und CSRF-Angriffen erheblich reduzieren:
Content-Security-Policy: script-src 'self'
Je nach den Anforderungen Ihrer App benötigen Sie möglicherweise eine detailliertere Richtlinie, aber das Deaktivieren von Inline-Skripten ist ein guter Ausgangspunkt.
Bevor Sie Benutzereingaben in Ihrer Datenbank speichern, stellen Sie sicher, dass die Daten ordnungsgemäß gesäubert werden, um bösartigen Inhalt zu entfernen. Anstatt beispielsweise rohe Werte direkt einzufügen:
db.query("INSERT INTO gantt_tasks(text, start_date, duration, progress, parent)"
+ " VALUES (?,?,?,?,?)",
[task.text, task.start_date, task.duration, task.progress, task.parent])
Verwenden Sie eine Bibliothek wie DOMPurify mit Node.js, um Eingaben zu reinigen:
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const DOMPurify = createDOMPurify(window);
...
db.query("INSERT INTO gantt_tasks(text, start_date, duration, progress, parent)"
+ " VALUES (?,?,?,?,?)",
[task.text, task.start_date, task.duration, task.progress, task.parent]
.map((input) => DOMPurify.sanitize(input))
Um zu verhindern, dass HTML-Markup während der Anzeige ausgeführt wird, escapen Sie HTML-Zeichen in benutzergenerierten Daten. Zum Beispiel mit der validator Bibliothek:
const validator = require('validator');
...
// GET /data
Promise.all([
db.query("SELECT * FROM gantt_tasks"),
db.query("SELECT * FROM gantt_links")
]).then(results => {
let tasks = results[0],
links = results[1];
tasks.forEach((task) => {
Object.entries(task).forEach(([key, value]) => {
if(typeof value === "string") {
task[key] = validator.escape(value); //#!
}
});
task.open = true;
task.start_date = task.start_date.format("YYYY-MM-DD hh:mm:ss");
});
links.forEach((link) => {
Object.entries(link).forEach(([key, value]) => {
if(typeof value === "string") {
link[key] = validator.escape(value); //#!
}
});
});
res.send({
tasks,
links
});
Um SQL-Injection-Angriffe zu verhindern, vermeiden Sie den Aufbau von SQL-Abfragen durch das Verketten von Zeichenfolgen. Verwenden Sie stattdessen parametrisierte Abfragen oder einen Abfrage-Builder/ORM. Wenn Sie nicht escapte oder nicht validierte Benutzereingaben in Ihren Abfragen verwenden, lohnt es sich, den Code umzuschreiben, um sicherere Praktiken zu befolgen.
Sicherheit ist ein fortlaufender Prozess. Durch die Implementierung dieser Schritte, das Einhalten der Sicherheitsrichtlinien Ihrer Organisation und die Überprüfung Ihrer Arbeit durch Spezialisten können Sie die meisten gängigen Bedrohungen adressieren.
Mit diesen Grundlagen im Hinterkopf, werfen wir einen Blick auf sicherheitsrelevante Überlegungen, die speziell für Gantt gelten.
Bei der Einbindung komplexer Tools wie Gantt auf der Client-Seite gibt es einige wichtige Punkte zu beachten:
Einige Bereiche, in denen Schwachstellen auftreten können, sind:
Der Schutz von Gantt beginnt mit der Isolierung von unbefugtem Zugriff, sei es durch kompromittierte Komponenten oder Self-XSS-Angriffe.
Wenn Angreifer Zugriff auf Konfigurationsdateien (einschließlich Gantt-Konfigurationen) erhalten, können XSS-Schutzmaßnahmen wirkungslos sein. Dieses Szenario liegt außerhalb des hier behandelten Umfangs.
Um unbefugten Zugriff auf die Gantt-Instanz zu verhindern, kapseln Sie sie innerhalb einer Funktion. Dies stellt sicher, dass die Instanz außerhalb des Funktionsbereichs nicht zugänglich ist. Zum Beispiel:
function addGantt(){
const gantt = Gantt.getGanttInstance();
}
addGantt()
Sie können die Instanz auch umbenennen, um Klarheit zu schaffen:
function addGantt(){
const protectedGantt = Gantt.getGanttInstance();
}
addGantt()
Sobald der Gantt-Zugriff gesichert ist, konzentrieren Sie sich darauf, die Dateneingabe und -anzeige sicher zu handhaben.
Dateneingabepunkte sind häufige Ziele für XSS-Angriffe. In Gantt können Daten eingegeben werden durch:
Das Aufgabenobjekt enthält verschiedene Parameter basierend auf den aktivierten Funktionen. Je mehr bearbeitbare Parameter, desto mehr Daten müssen bei der Eingabe bereinigt werden.
Hier ist ein Beispiel, das zeigt, wie Sie den Schutz vor XSS-Angriffen verstärken können, indem Sie HTML bei der Arbeit mit DHTMLX Gantt sanitisieren.
Related sample: Beispiel zur Verhinderung von XSS-Angriffen (Sicherheit, csp)
In diesem Beispiel können Sie den Namen einer Aufgabe, die Daten, die Dauer, Ressourcenzuweisungen ändern und Notizen hinzufügen. Die Anpassung des Startdatums und der Dauer ist auf die Lightbox und Inline-Editoren beschränkt. Für Inline-Editoren sind die date und number Typen explizit definiert. In der Lightbox können Sie nur die Dauer festlegen, während das Datum aus einem Dropdown ausgewählt wird.
Diese UI-Elemente sind so gestaltet, dass sie die Einfügung von bösartigem Code verhindern. Wenn Sie versuchen, die Elementtypen mit einem DOM-Inspektor zu ändern, führen ungültige Werte für Datum oder Dauer zu Fehlern, die die Funktionalität von Gantt stoppen, bis die Seite neu geladen wird. In solchen Fällen werden keine Daten an den Server gesendet, da die Daten nicht neu gezeichnet werden.
Aufgabennamen, die den string Wertetyp verwenden, können jedoch ein Schwachpunkt für XSS-Angriffe sein. Um dies anzugehen, wird die Eingabe gesäubert. Das Beispiel zeigt ein XSS-Angriffsszenario und eine Möglichkeit, es zu mildern.
Für reale Projekte ist es wichtig, eine umfassende Datenbereinigung zu implementieren. In diesem Beispiel werden die Zeichen "<" und ">" durch ihre HTML-Entitäten <
und >
ersetzt, um zu verhindern, dass HTML-Elemente im Aufgabentext angezeigt werden.
Die Ersetzungslogik wird in der Funktion sanitizeText() implementiert:
function sanitizeText(text){
// zum Testen von XSS auskommentieren
// return text
// XSS verhindern, indem HTML-Elemente deaktiviert werden
return text.split("<").join("<").split(">").join(">");
}
Diese Funktion wird in Ereignishandlern wie onLightboxSave für die Lightbox und onBeforeSave für Inline-Editoren verwendet.
Das Beispiel enthält auch benutzerdefinierte Inline-Editoren und Lightbox-Abschnitte zum Hinzufügen von Textnotizen. Die Bereinigung wird in den Funktionen dieser benutzerdefinierten Objekte angewendet, bevor Werte gerendert oder Änderungen aus DOM-Elementen abgerufen werden:
// für einen Inline-Editor:
set_value: function(value, id, column, node){
node.firstChild.value = sanitizeText(value || "");
},
get_value: function(id, column, node){
return sanitizeText(node.firstChild.value);
},
// für die Lightbox:
set_value: function(node, value, task){
node.value = sanitizeText(value || "");
},
get_value: function(node, task){
return sanitizeText(node.value);
},
Alternativ können Sie die Textnotizbereinigung mit onLightboxSave und onBeforeSave Ereignishandlern bearbeiten:
protectedGantt.attachEvent("onLightboxSave", function(id, task, is_new){
if (task.notes) {
task.notes = sanitizeText(task.notes);
}
return true;
});
protectedGantt.ext.inlineEditors.attachEvent("onBeforeSave", function(state){
if (state.columnName == "notes") {
state.newValue = sanitizeText(state.newValue);
}
return true;
});
Ressourcenzuweisungen in der Lightbox erfordern ebenfalls Aufmerksamkeit. Da Gantt Zeichenfolgenwerte zulässt, ist die Bereinigung entscheidend, um XSS-Angriffe zu verhindern. Die Funktion sanitizeResourceValues() iteriert durch Ressourcenzuweisungen und wendet sanitizeText() an:
function sanitizeResourceValues(task){
const resources = task[protectedGantt.config.resource_property];
if (resources && resources.length) {
resources.forEach(function (resource) {
if (typeof resource.value == "string") {
resource.value = sanitizeText(resource.value);
}
})
}
}
Diese Funktion ist an den Ereignishandler onLightboxSave gebunden:
protectedGantt.attachEvent("onLightboxSave", function(id, task, is_new) {
sanitizeResourceValues(task)
return true;
});
Vergessen Sie nicht, alle zusätzlichen Zeichenfolgenparameter in Ihrer Gantt-Konfiguration zu bereinigen.
Im Beispiel werden nur numerische Werte für Ressourcenzuweisungen in der Ressourcenzeitleiste akzeptiert. Andere Typen speichern keine Änderungen.
Gantt ermöglicht Anpassungen, einschließlich der Aufgabenbearbeitung mit Formularen, Tools oder Bibliotheken von Drittanbietern. Diese Szenarien basieren häufig auf der Gantt-API. Da Anpassungen variieren, gibt es keine einheitliche Lösung für die Datenbereinigung.
Im Beispiel wird ein benutzerdefiniertes Formular verwendet, um Aufgabennamen zu bearbeiten. Die Funktion sanitizeText() wird einbezogen, um das Escaping von Text zu behandeln:
document.body.querySelector("[name='save']").onclick = function(){
const newTaskName = document.body.querySelector("[name='text']").value;
task.text = sanitizeText(newTaskName);
protectedGantt.updateTask(task.id);
}
Durch die Bereinigung von Daten bei der Eingabe in Gantt werden potenzielle XSS-Angriffe neutralisiert, sodass sie nicht den Server erreichen.
Ein weiterer Bereich, den es zu beachten gilt, ist die Anzeige von Daten im Gantt-Diagramm. Obwohl dies nicht so kritisch ist wie die Dateneingabe, kann die Bereinigung angezeigter Daten XSS-Angriffsserien unterbrechen. Wenn beispielsweise der Server kompromittiert wird, Gantt jedoch unzugänglich bleibt, kann die Bereinigung den Angriff blockieren.
Der sicherste Ansatz besteht darin, alle Bereiche zu bereinigen, in denen Daten angezeigt werden. Dies umfasst die Verwendung von Vorlagen in Grid-Spaltenkonfigurationen und aller verfügbaren Vorlagen, um die Anzeige von bösartigem Inhalt zu verhindern.
Eine einfachere Alternative besteht darin, den Datenfluss in Gantt zu begrenzen. Dies stellt sicher, dass kein bösartiger Code den Inhalt beeinflussen kann. Beispielsweise können Aufgabenparameter beim Laden von Daten vom Server mithilfe des Ereignishandlers onTaskLoading bereinigt werden:
protectedGantt.attachEvent("onTaskLoading", function (task) {
task.text = sanitizeText(task.text);
if (task.notes) {
task.notes = sanitizeText(task.notes);
}
sanitizeResourceValues(task);
return true;
});
Wenn Aufgaben einzeln geladen oder in Gantt aktualisiert werden, sollten sie bereinigt werden, bevor sie hinzugefügt oder aktualisiert werden:
let newTask = await loadFromServer(23);
sanitizeTaskProperties(newTask);
gantt.addTask(newTask);
Während Benutzer Gantt-DOM-Elemente mit Browser-Inspektoren manipulieren können, bleiben solche Änderungen nicht bestehen und gehen bei einer Neudarstellung oder Serveraktualisierungen verloren.
Beachten Sie, dass die clientseitige Validierung nicht narrensicher ist und umgangen werden kann. Sie bietet Benutzern sofortiges Feedback bei fehlerhaften Eingaben, aber die endgültige Validierung muss immer auf dem Server erfolgen.
Da dhtmlxGantt vollständig clientseitig ist, liegt die Verhinderung von SQL-Injection in der Verantwortung des Backends.
Wichtige Punkte:
Wenn Sie dhtmlxConnector und eine Tabellenkonfiguration wie in der Dokumentation beschrieben verwenden, werden Werte automatisch escapt. Andernfalls befolgen Sie bewährte Verfahren für sichere CRUD-Implementierungen basierend auf Ihrer Plattform. Die How to Start Guides bieten sichere Beispiele zur Vermeidung von SQL-Injection.
Für das Hinzufügen benutzerdefinierter Autorisierungstoken oder Header zu Backend-Anfragen von Gantt lesen Sie diesen Artikel.
Um Ihre dhtmlxGantt-Anwendung mit dem CSP (Content Security Policy)-Standard in Einklang zu bringen, bietet die Bibliothek eine spezielle Konfigurationsoption. Dies hilft, Code-Injektionsangriffe zu verhindern und die Sicherheit Ihrer Anwendung zu stärken.
Erfahren Sie mehr über die Anwendung von CSP-Standards auf dhtmlxGantt-Anwendungen.
Zurück nach oben