DEV Community

Kristiyan Velkov
Kristiyan Velkov

Posted on

Angular Security Best Practices Guide

Ensuring the security of your web applications is not just a best practice, it’s a necessity. This guide covers the essential aspects of securing your Angular applications.

Image description

Why Security Matters in Angular Applications

Web applications are prime targets for cyberattacks such as cross-site scripting (XSS), cross-site request forgery (CSRF), and data breaches. Securing your Angular app ensures:

  • Protection of sensitive user data.
  • Compliance with legal and regulatory standards.
  • Maintenance of user trust and application integrity.

Lear more about web security here:


1. Keep Your Angular Framework Up-to-Date

Angular’s active development community frequently releases updates that include important security patches. Regularly updating your Angular framework ensures that your application benefits from these enhancements.

Current LTS version of Angular is 19:

How to stay updated:


2. Sanitize User Input

User input is one of the most common attack vectors for malicious actors. Angular provides built-in tools to sanitize and validate inputs to protect your application from vulnerabilities like Cross-site scripting (XSS).

** Cross-site scripting (XSS) — attacks enable attackers to inject client-side scripts into web pages viewed by other users._**

Best practices:

  • Use Angular’s DomSanitizer to sanitize untrusted HTML, URLs, and styles.
  • Avoid using innerHTML or bypassing Angular’s sanitization unless absolutely necessary.
  • 🚨 Avoid Using bypassSecurity Methods Unnecessarily! 🚨

BypassSecurity Methods are:

  1. bypassSecurityTrustScript: Marks a value as trusted for use as a script.
  2. bypassSecurityTrustStyle: Marks a value as trusted for use in styles.
  3. bypassSecurityTrustUrl: Marks a value as trusted for use in URLs.
  4. bypassSecurityTrustResourceUrl: Marks a URL as trusted for loading resources.

🔴 Why is this dangerous?

Using Angular’s bypassSecurity Methods can introduce security vulnerabilities if misused. These methods explicitly tell Angular to trust the provided content, bypassing built-in security mechanisms like XSS protection.

Example of DomSanitizer with SafeHtml:

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

export class SafeHtmlComponent {
  safeHtml: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {
    const dangerousHtml = '<script>alert("XSS")</script>';
    this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(dangerousHtml);
  }
}
Enter fullscreen mode Exit fullscreen mode

3. Restrict Template and Style Injection

Angular’s built-in template syntax and style bindings are designed to prevent script injection. Avoid patterns that could lead to vulnerabilities.

Best practices:

  • Do not dynamically generate Angular templates or styles from untrusted data.
  • Avoid assigning user input directly to [innerHTML] or [style] bindings.

Safer alternative:

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Component } from '@angular/core';

@Component({
  selector: 'app-safe-content',
  template: '<div [innerHTML]="safeContent"></div>'
})


export class SafeContentComponent {
  safeContent: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {
    const content = '<script>alert("XSS")</script><p>This is safe content.</p>';
    this.safeContent = this.getSafeContent(content);
  }

  getSafeContent(content: string): SafeHtml {
    return this.sanitizer.bypassSecurityTrustHtml(content);
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Secure API Communication

Ensure secure communication between your Angular application and backend APIs.

Best practices:

  • Use HTTPS for all API requests.
  • Include anti-CSRF tokens in your requests and validate them on the server.
  • Validate all inputs received from APIs on the server side.

5. Enable Content Security Policy (CSP)

Harness Content Security Policy (CSP) as a defense mechanism against XSS attacks to restrict the types of resources the client can load. CSP effectively blocks malicious script injections by specifying an allowlist of trusted content sources.

Image description

Start by defining CSP directives in your web server’s configuration. Set up Content-Security-Policy headers that specify trustworthy sources for scripts, styles, images, fonts, and other resources. Include script sources that align with Angular’s dynamic script requirements, such as ‘self,’ ‘unsafe-inline,’ ‘unsafe-eval,’ and trusted domains for APIs and CDNs.


6. Use Angular Interceptors for HTTP Security

Angular HTTP interceptors provide a powerful mechanism to enhance HTTP security by allowing you to inspect and transform HTTP requests and responses.

Image description

You can automatically append authentication tokens, such as JWT (JSON Web Tokens), to the headers by intercepting every outgoing HTTP request. This guarantees that all requests from your Angular application to the server carry the necessary credentials for user verification without manually adding them to each service call.


7. Route Guarding

Angular provides route guards to protect routes based on specific conditions, such as user authentication, authorization, or application logic. These guards prevent unauthorized access to sensitive pages.

Common Types of Guards in Angular:

  • CanActivate: Prevents unauthorized users from navigating to specific routes.
  • CanActivateChild: Controls navigation to child routes.
  • CanDeactivate: Prompts users to save unsaved changes before leaving a route.
  • CanLoad: Prevents modules from loading until specific conditions are met.
  • Resolve: Pre-fetches data before the route is activated.

Example: Protecting Routes with CanActivate:

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

@Injectable({
  providedIn: 'root',
})
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService, private router: Router) {}

  canActivate(): boolean {
    if (this.authService.isLoggedIn()) {
      return true;
    } else {
      this.router.navigate(['/login']);
      return false;
    }
  }
}```



**Usage in Routing Module:**



```typescript
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from './auth.guard';
import { DashboardComponent } from './dashboard/dashboard.component';
import { LoginComponent } from './login/login.component';

const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}
Enter fullscreen mode Exit fullscreen mode

Auth Guard as a Function:

Here’s an example using canActivateFn, introduced in Angular 15, to define guard logic in a functional style.

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  if (authService.isLoggedIn()) {
    return true; // Allow navigation
  } else {
    router.navigate(['/login']); // Redirect to login page
    return false; // Prevent navigation
  }
};
Enter fullscreen mode Exit fullscreen mode

Add Guard to Routes

In your routing module, apply the guard to the route using the appropriate property (canActivate, canActivateChild, etc.).

Example: Protecting a Route with canActivate

import { Routes } from '@angular/router';
import { authGuard } from './auth.guard';
import { DashboardComponent } from './dashboard/dashboard.component';

export const routes: Routes = [
  {
    path: 'dashboard',
    component: DashboardComponent,
    canActivate: [authGuard],
  },
];
Enter fullscreen mode Exit fullscreen mode

Best Practices:

  • Combine multiple guards for complex logic (e.g., authentication and role-based access control).
  • Ensure guards validate conditions on the server side as well to prevent bypassing via API calls.
  • Avoid hardcoding roles and use a dynamic configuration for role-based checks.

8. Authentication

Authentication is a critical component of any secure Angular application. It verifies the identity of users before granting access to protected resources or actions.

Best Practices for Authentication in Angular:

1. Use a Secure Authentication Flow

2. Token-Based Authentication

  • Use JSON Web Tokens (JWTs) to authenticate users.
  • Store the JWT securely, preferably in HttpOnly cookies, to prevent XSS attacks.
  • Avoid storing JWTs in local storage or session storage if sensitive data is included.
  • Validate tokens on the server to ensure they haven’t been tampered with or expired.

Example: Interceptor for Adding Authentication Tokens

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler) {
    const token = localStorage.getItem('authToken'); // Replace with secure storage method
    const clonedReq = token
      ? req.clone({
          setHeaders: {
            Authorization: `Bearer ${token}`,
          },
        })
      : req;

    return next.handle(clonedReq);
  }
}

Enter fullscreen mode Exit fullscreen mode

📢 If you like what I'm doing, support me by following and subscribing!

🔔 Subscribe to my newsletter for exclusive content:

📩 Substack

🌐 Follow me for more content:

📝 Medium

💻 GitHub

👨‍💼 LinkedIn

🐦 Twitter (X)

🐳 Next.js Production Dockerfile

© 2025 Kristiyan Velkov. All rights reserved.

Top comments (0)