Learn Angular - Secure Web Practices
Episode 13 of 24

Learn Angular - Secure Web Practices

This episode covers web security practices: preventing XSS, CSRF, and injection, applying content security policy and secure headers, sanitizing HTML and handling URLs safely, and client-side security best practices.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Authentication is only one layer of security. The other side, just as important, is how the application processes user input, renders content, and talks to the server. This is where XSS, CSRF, and injection attacks often happen.

Episode 13 covers preventing XSS, CSRF, and injection, content security policy and secure headers, HTML sanitization and safe URLs, and client-side security best practices. Angular already provides a lot of protection by default — our job is not to dismantle it without reason.

Preventing XSS, CSRF, and Injection

What is XSS

Cross-Site Scripting (XSS) happens when malicious JavaScript makes its way into a page and executes in the victim's browser. Common sources: user input displayed without sanitization, or HTML attributes filled with untrusted data.

Angular's Built-in XSS Protection

By default, Angular sanitizes all values rendered through interpolation and binding. Consider this example:

JSMalicious content made safe by sanitization
@Component({
  selector: 'app-komentar',
  standalone: true,
  template: `<p>{{ komentar }}</p>`,
})
export class KomentarComponent {
  komentar = '<script>alert("xss")</script>';
}

Even though komentar contains <script>, Angular will display it as plain text instead of executing it. This is the default protection you must preserve: always use interpolation and binding, and never inject raw HTML into the DOM.

CSRF and Injection

CSRF tricks the victim's browser into sending malicious requests to a trusted site. Prevention: use a CSRF token, verify a custom header like X-Requested-With, and use httpOnly cookies with the SameSite attribute. Injection — SQL injection, command injection — happens server-side; on the frontend, always treat data from the server as untrusted until validated.

Content Security Policy and Secure Headers

Setting Up CSP

Content Security Policy restricts what resources a page may load. A strict policy blocks inline scripts and disallowed external sources:

Recommended CSP header
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'

The policy above only allows scripts from your own domain and inline styles. CSP can be set via a server header or a meta tag. Angular builds with hashing are safe under policies like this.

Other Secure Headers

Besides CSP, make sure the server sends: Strict-Transport-Security to force HTTPS, X-Content-Type-Options: nosniff, Referrer-Policy, and X-Frame-Options to prevent clickjacking. These headers can be added in a web server like nginx, or in hosting platforms like Vercel and Netlify.

Sanitizing HTML and Safe URL Handling

Don't Trust Data from the Server

Sometimes an application genuinely must display HTML from the server. Don't disable Angular's sanitization carelessly. If you must, use DomSanitizer and review very carefully:

JSMarking trusted HTML content
import { Component, inject } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
 
@Component({
  selector: 'app-konten',
  standalone: true,
  template: `<div [innerHTML]="htmlAman"></div>`,
})
export class KontenComponent {
  private readonly sanitizer = inject(DomSanitizer);
  htmlAman: SafeHtml = '';
}

SafeHtml tells Angular the developer has explicitly declared the value safe. This means you take over the sanitization responsibility — use it only when the content truly comes from a trusted source.

Safe URLs

URLs can also be dangerous — for example javascript: as a scheme. Angular blocks dangerous URLs in href and src bindings. To open a link from user data, use bypassSecurityTrustUrl only after validating the scheme:

JSValidating a URL scheme
function urlAman(raw: string): SafeUrl | null {
  if (!/^https?:\/\//i.test(raw)) {
    return null;
  }
  return sanitizer.bypassSecurityTrustUrl(raw);
}

The ^https?:\/\// regex ensures only URLs with the http or https scheme are accepted. All other schemes are rejected — this pattern prevents dangerous javascript: URLs.

Best Practices for Client-side Security

Core Principles

  • Never trust user input or data from the server.
  • Always use binding and interpolation; avoid direct innerHTML manipulation.
  • Don't store secrets or sensitive tokens in localStorage.
  • Enable HTTPS in every environment, including development on public networks.
  • Limit resources with CSP and make sure cookies use SameSite and httpOnly.

Regular Audits

Perform security audits periodically: run npm audit for dependencies, use automated scanners for security headers, and review code that uses bypassSecurityTrust*. Security isn't a one-time task — it's maintained every day.

Wrap Up

Key takeaways:

  • Angular sanitizes content by default; don't dismantle this protection without a strong reason.
  • Prevent CSRF with tokens and httpOnly SameSite cookies.
  • Apply CSP and secure headers like HSTS and nosniff.
  • DomSanitizer is only for trusted content, with strict review.
  • Validate URL schemes so javascript: links never get through.
  • Audit dependencies and security headers regularly.

In the next episode, episode 14, we'll cover API communication and caching — using HTTP interceptors for centralized error handling, caching strategies for API responses, state transfer and server-side rendering cache, and optimizing network request performance.

Learn Angular - Secure Web Practices | Learn Angular