0 Tage Serie
javascript / expert
Snippet

Sanitisiertes dynamisches Class-Binding gegen Style-Injection

Wenn ein Klassenname aus nutzergesteuerten oder backend-gelieferten Daten stammt (z. B. ein CMS-Feld oder Query-Parameter, der in ein `theme`-Input weitergereicht wird), erlaubt eine direkte Bindung über `[class]="userValue"` einem Angreifer das Einschleusen beliebiger Klassennamen, die mit fremden Selektoren an anderer Stelle der App kollidieren oder — in Kombination mit einem zu offenen globalen Stylesheet — für CSS-basierte Datenexfiltration missbraucht werden können (Attribut-Selektoren, die Hintergrundbild-Requests auslösen). Angular sanitisiert Class-Bindings nicht so wie `innerHTML` oder `href`, da ein Klassenname nicht grundsätzlich aktiver Inhalt ist — die Allowlist-Prüfung hier ist somit die tatsächliche Sicherheitsgrenze, keine redundante Zusatzmaßnahme.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const ALLOWED_THEME_CLASSES = new Set(['theme-default', 'theme-compact', 'theme-highcontrast']);
@Component({
selector: 'app-themed-card',
standalone: true,
template: `<div [class]="resolvedClass()"><ng-content /></div>`,
})
export class ThemedCardComponent {
readonly themeInput = input<string>('theme-default', { alias: 'theme' });
readonly resolvedClass = computed(() => {
const requested = this.themeInput().trim();
if (!ALLOWED_THEME_CLASSES.has(requested)) {
console.warn(`Rejected unrecognized theme class "${requested}"; falling back to default.`);
return 'theme-default';
}
return requested;
});
}
angular
Erklärung
1
const ALLOWED_THEME_CLASSES = new Set(['theme-default', 'theme-compact', 'theme-highcontrast']);
Eine explizite, auf Modulebene definierte Allowlist — die einzigen Klassen, die diese Komponente jemals rendert, unabhängig von der Eingabe.
2
if (!ALLOWED_THEME_CLASSES.has(requested)) { ... return 'theme-default'; }
Schlägt geschlossen zu einem sicheren Default fehl, statt unbekannte Eingaben durchzureichen — ein unerwarteter Wert degradiert kontrolliert statt zum Injection-Vektor zu werden.
3
console.warn(`Rejected unrecognized theme class "${requested}"; falling back to default.`)
Protokolliert die Ablehnung, damit ein legitimes neues Theme, das nie zur Allowlist hinzugefügt wurde, in Produktions-Logs auffindbar ist statt still falsch zu rendern.