Angular provides contextual escaping, sanitization, XSRF integration, and routing tools, but the browser remains an untrusted client. This lesson separates template safety, trusted-value bypasses, navigation controls, and server-side authorization.
Angular reduces several browser-side risks, but the application and server still own the security boundary. Treat every value from users, URLs, storage, APIs, and third-party scripts as untrusted until the correct layer validates it.
Angular escapes interpolation and sanitizes values in supported HTML and URL binding contexts. Resource URLs can load executable code and cannot be made safe by ordinary sanitization. Avoid direct DOM APIs and never construct Angular templates from untrusted strings.
Authentication proves identity; authorization decides whether that identity may perform an operation. Enforce both on the server for every protected request. Client route guards only improve navigation flow and cannot protect data or APIs.
Use HTTPS, restrictive Content Security Policy, Trusted Types where supported, secure cookies, dependency review, and server-side input validation as complementary layers rather than relying on one framework feature.
Angular treats template expressions as data and applies a security context to relevant bindings. HTML and URL values are sanitized when required; interpolation is escaped. These protections do not make arbitrary direct DOM writes or third-party widgets safe.
HttpClient includes an XSRF mechanism for eligible same-origin mutating requests when the server uses the matching cookie and header contract. Configure names with withXsrfConfiguration only when the backend contract differs, and understand that token handling is one part of CSRF defense.
A guard runs in code controlled by the user. It may redirect an unauthenticated visitor or prevent accidental navigation, but an attacker can modify the bundle, invoke an API directly, or forge client state.
Return a UrlTree or RedirectCommand for a redirect instead of returning false and starting a second navigation. Keep authorization policy on the backend and treat every API request independently of which Angular route displayed the button.
// auth.guard.ts - Functional guard (Angular 15+)
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;
}
// Redirect to login with return URL
return router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url }
});
};
// app.routes.ts - Apply the guard
export const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [authGuard] },
{ path: 'admin', component: AdminComponent, canActivate: [authGuard, adminGuard] },
{ path: 'login', component: LoginComponent },
];
// auth.service.ts - Token-based auth
@Injectable({ providedIn: 'root' })
export class AuthService {
isLoggedIn(): boolean {
const token = localStorage.getItem('auth_token');
if (!token) return false;
// Check token expiry
try {
const payload = JSON.parse(atob(token.split('.')[1]));
return payload.exp > Date.now() / 1000;
} catch {
return false;
}
}
}
Angular evaluates bound values in a security context determined by the destination. Escaping text and sanitizing a supported property are different operations, and a value accepted in one context must not be assumed safe in another.
| Context | Rule |
|---|---|
| Interpolation and text | Angular escapes text so markup characters render as data rather than executable HTML. |
| HTML property | Angular sanitizes risky HTML when binding to destinations such as innerHTML; styling may be removed. |
| Style property | Angular applies style-context handling to bound style values; keep untrusted values constrained to expected formats. |
| URL property | Angular sanitizes dangerous navigation URLs in supported URL contexts. |
| Resource URL | A script or executable resource URL cannot be made safe by ordinary sanitization; allow only explicitly trusted application-controlled values. |
| Direct DOM API | Values written through nativeElement, document, or a third-party widget bypass normal template protections. |
Authentication state in the browser improves user experience but cannot authorize an operation. The server must validate the session or token, enforce permission for the exact resource, and reject forged or replayed requests.
| Risk | Control |
|---|---|
| Cross-site request forgery | Use SameSite cookie policy, server-side origin or token validation, and Angular HttpClient XSRF integration for the matching same-origin contract. |
| Token theft through XSS | Prefer HttpOnly cookies for server-managed sessions when architecture permits, minimize script access, and deploy CSP plus Trusted Types. |
| Broken object authorization | Authorize every requested record and action on the server; never trust a hidden button or route guard. |
| Sensitive browser storage | Do not store secrets in localStorage, sessionStorage, source maps, environment bundles, or client logs. |
| Cross-origin API calls | Allow only intended origins, methods, headers, and credentials on the server; CORS is not authentication. |
Framework protections are one layer. Production security also depends on how scripts are loaded, dependencies are maintained, errors are reported, and the server configures browser policies.
A route guard improves navigation, but the server still checks the authenticated principal and resource permission.
app.delete('/api/projects/:id', requireSession, async (req, res) => {
const project = await projects.find(req.params.id);
if (!project || !canDelete(req.user, project)) {
return res.sendStatus(403);
}
await projects.remove(project.id);
res.sendStatus(204);
});
Unauthorized requests receive 403 even when the URL is called directly.
The bypass call does not sanitize HTML; it tells Angular that the developer has already established the value is safe.
No. A guard controls navigation in code running on the user’s machine.
The built-in mechanism is designed for same-origin mutating requests and expects a configured cookie and header name. It may not add a token to cross-origin requests, requests using a different cookie name, or deployments where cookie path, domain, SameSite, or secure settings prevent the browser from sending the cookie.
Explore 500+ free tutorials across 20+ languages and frameworks.