← Retour au blog
sécuritéCSRFXSSAngularcookies

CSRF, XSS, and httpOnly Cookies: Beyond Buzzwords, a Real Strategy

Web security rests on three pillars that every developer claims to understand but few truly master: CSRF, XSS, and httpOnly cookies. These are not marketing buzzwords but concrete attack vectors that compromise production applications every day. The common trap is treating them independently, as if enabling an httpOnly checkbox is enough. It is not. These three mechanisms work together, and it is precisely this synergy that creates solid defense.

CSRF: The Invisible Action Theft

CSRF (Cross-Site Request Forgery) exploits the trust browsers place in cookies. When you are logged into your bank and visit a malicious site, that site can trigger an action on your account via a silent request: transfer money, change settings, or delete data. The browser automatically sends cookies with the request, making the attack transparent to the user. The key insight is that the attacker cannot access the response data—they simply exploit the fact that the browser sends cookies automatically. An img tag, a hidden form, or a fetch request is enough. The classic attack vector remains straightforward: the attacker controls a site, you visit it, and your browser executes an action on another site where you are authenticated.

The standard defense against CSRF uses CSRF tokens (also called anti-CSRF tokens). The server generates a unique token, transmits it to the client via HTML response or a dedicated endpoint, and the client includes it in HTTP headers of state-modifying requests (POST, PUT, DELETE). The attacker cannot guess this token, so their request fails. With Angular, CSRF token management can be automated via an HTTP interceptor. Here is how: instead of manually adding the token to each request, Angular can read the token from a cookie or endpoint and inject it automatically into the X-CSRF-TOKEN header. This centralizes logic and reduces oversights.

XSS: When the Attacker's JavaScript Becomes Yours

XSS (Cross-Site Scripting) is different from CSRF. Here, the attacker injects malicious code directly into your application. If a text field accepts user content without sanitizing it, an attacker can inject a script that executes in your application's context. That script can then access cookies, local storage, history, or perform actions on behalf of the user. Angular mitigates this risk by automatically escaping dynamic content by default. When you use interpolation {{variable}} or property bindings [property], Angular escapes HTML. But this protection is not magical: it does not cover cases where you intentionally bypass the security system.

There are two main forms of XSS: reflected XSS and stored XSS. Reflected XSS occurs when a URL parameter is reflected without escaping in the HTML response—for example, a search page displaying the search term directly. Stored XSS is more severe: malicious content is saved in a database and executed every time a user views it. In an Angular application, stored XSS can come from user comments, product descriptions, or any data from a form. Mitigation involves systematic escaping and using Content Security Policy (CSP), an HTTP header that restricts authorized script sources.

httpOnly Cookies: The Barrier Against Session Theft

httpOnly cookies are a simple but powerful directive: they tell the browser that the cookie must not be accessible via JavaScript. Only the browser can read it and automatically transmit it to HTTP requests. This means an XSS script cannot do document.cookie and exfiltrate the session token. Without httpOnly, an attacker who injects malicious JavaScript can grab your session cookie and use it to impersonate you. With httpOnly, this vector is blocked. It is defense in depth: even if XSS occurs, the cookie remains safe. The secure directive completes the protection by forcing the cookie to be transmitted only over HTTPS, eliminating the risk of plain-text interception.

How All Three Work Together

True defense relies on the combination of all three elements. CSRF protects against unauthorized actions initiated from another site. XSS protection and CSP prevent malicious code injection. httpOnly cookies protect the session itself. Here is a concrete flow: a user logs into your Angular application. The server sends a session cookie with httpOnly and secure flags. Simultaneously, it provides a CSRF token via an endpoint or a JavaScript-readable cookie. For each POST, PUT, or DELETE request, the client includes this CSRF token in the X-CSRF-TOKEN header. Angular can automate this via an HTTP interceptor. If an attacker attempts XSS injection, CSP blocks unauthorized scripts. If an attacker attempts a CSRF request from another site, the CSRF token will be missing and the request is rejected. If an attacker somehow injects JavaScript, they cannot read the httpOnly cookie.

Concrete Implementation with Angular

Here is an Angular HTTP interceptor that automatically handles CSRF tokens: const httpClient = inject(HttpClient); const httpOptions = { withCredentials: true, headers: new HttpHeaders({ 'X-CSRF-TOKEN': this.getCsrfToken() }) }; private getCsrfToken(): string { return document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || ''; } This pattern assumes the server places the CSRF token in a meta tag. The server must also validate the token on each state-modifying request. On the server side (Node.js/Express for example): app.use(csrf()); app.post('/api/data', (req, res) => { // The csrf middleware validates the token automatically res.json({ success: true }); }); Angular must also configure interceptors to include the token automatically with each request. This centralizes logic and reduces the risk of oversights.

Common Pitfalls and Implementation Mistakes

The most common pitfall is thinking that httpOnly cookies alone are sufficient. Developers enable httpOnly and believe they are protected against all attacks. Wrong. httpOnly only protects against cookie theft via JavaScript. It does not protect against CSRF. An attacker can still force an action via a silent request. Similarly, simply enabling CSP without implementing CSRF is insufficient. CSP reduces XSS vectors but does not eliminate them completely. Headers must be configured strictly: Content-Security-Policy: script-src 'self'; default-src 'self'; Too permissive, they become ineffective. Another pitfall: not validating CSRF tokens server-side. Generating a token and transmitting it to the client is not enough. The server must verify that the received token matches the session token. Without this validation, the token is just security theater.

A final pitfall: mixing CSRF token storage strategies. Some developers place the token in a JavaScript-readable cookie and include it in a header. Others store it only in server session. Best practice is to store it in server session and transmit it to the client via an endpoint or meta tag, never in a readable cookie. This strengthens security because the token does not traverse the network unnecessarily.

Conclusion: Real Defense in Depth

CSRF, XSS, and httpOnly cookies are not three independent solutions to check off. They form a defense-in-depth strategy where each compensates for the weaknesses of the others. Implementing all three correctly means: using CSRF tokens for every state-modifying request, systematically encoding dynamic content and configuring CSP strictly to prevent XSS, and finally, enabling httpOnly and secure on all session cookies. In a production Angular application, automating these mechanisms via HTTP interceptors and server-side security directives drastically reduces the risk of oversight. Web security is never "done", but these three elements correctly combined close the most obvious doors to attackers.

Développeur Angular & Mobile freelance — Strasbourg.

© 2026 Emilien Pons — Tous droits réservés.Conçu avec Angular, PrimeNG et ❤️