What is client-side security? The half of your attack surface you don't host

Client-side security protects what happens in your visitors' browsers: XSS, script supply-chain compromise, session theft, clickjacking. A survey of the attack families and the defenses that cover them: CSP, SRI, cookie flags and violation reporting.

Published

Client-side security is the protection of everything that happens after your server sends its response: the JavaScript running in the visitor’s browser, the third-party scripts the page pulls in, the cookies the browser holds, and the contexts other sites can load your pages into. It matters because a growing share of real-world attacks never touch your infrastructure. The malicious code executes on a machine you have never seen, inside a browser you do not operate, against a user you still have to protect.

Browser security vs server security

Server-side security is the part everyone budgets for. Patch the OS, harden the framework, scan dependencies, put a WAF in front. All of it necessary, and all of it blind to what happens next.

The moment a response leaves your server, execution changes hands. The page gets assembled in the visitor’s browser alongside scripts from your CDN, your analytics vendor, your chat widget, your payment provider. Your logs show a 200 and a clean body. Whether that page then ran an injected script, leaked a session cookie, or quietly posted card numbers to a server in another country is invisible from your side, because none of that traffic goes through you.

That asymmetry is the whole subject. You configure the browser’s behavior through headers and attributes, but you never operate it.

The attack families that live in the browser

Four families cover most of what we actually see in violation data.

Cross-site scripting: injected code runs as your site

An attacker finds a way to get their script into your page, typically through input your application reflects without escaping it properly. The browser has no way to tell that script from yours, so it runs with the full authority of your origin: it can read the DOM, watch form fields, grab any cookie not flagged HttpOnly, and make requests as the logged-in user. XSS has sat near the top of vulnerability statistics for two decades because one missed escape anywhere in the codebase is enough. We break down the mechanics in how XSS attacks work.

Supply-chain compromise: a script you trust turns hostile

Here nobody injected anything. A script you legitimately load changed underneath you: a compromised CDN, a hacked vendor, a tag added through a tag manager by someone in marketing. The Magecart groups industrialized this against payment pages, skimming card numbers as users type them. British Airways lost around 380,000 cards to one such script in 2018. From the browser’s point of view the skimmer is just another authorized resource. We wrote up a concrete detection scenario in catching a Magecart attack with CSP.

Often the script itself is only a means. What the attacker wants is your user’s session: a cookie readable from JavaScript, a token sitting in localStorage. Exfiltrate it once and they can replay it from their own machine, already authenticated, MFA already passed. No password cracking involved. Details and defenses in cookie theft and session hijacking.

Clickjacking: your UI inside someone else’s page

The quietest of the four, because no code gets injected at all. The attacker loads your page in an invisible iframe on their own site and layers bait on top, so the victim clicks your real “confirm transfer” or “authorize app” button while believing they are clicking something else. Your application behaves exactly as designed. That is the problem. Full explanation in clickjacking explained.

The defense toolbox, and what each piece covers

None of these tools covers everything. Together they cover a lot.

A Content Security Policy is the broadest one: an HTTP header declaring which sources the page may load scripts, styles and frames from, and where it may send data. An injected inline script violates it. A skimmer’s exfiltration request to an unknown origin violates it. It is the closest thing to an allowlist for the browser.

Subresource Integrity (SRI) pins the exact content of a third-party script with a hash in the integrity attribute. If the file on the CDN changes by one byte, the browser refuses to run it. Perfect for static libraries, unusable for scripts that change legitimately every week (how SRI hashes work).

Cookie flags limit what a successful script can steal. HttpOnly hides the cookie from JavaScript entirely, Secure keeps it off plaintext connections, and SameSite stops most cross-site requests from carrying it. Three attributes, one line, and cookie theft gets dramatically harder.

frame-ancestors, a CSP directive, controls who may put your pages in a frame. Set it to 'self' or 'none' and clickjacking dies outright. It replaced the older X-Frame-Options header and does the job better.

Then monitoring, the piece most teams skip. Every control above is configuration you set once and hope still fits your site six months later. You cannot fix what you cannot see, and browsers will tell you what they see: CSP violation reporting is a native telemetry channel, no agent script required. Each blocked or would-be-blocked resource generates a report from the field. CentralCSP exists for exactly this layer: a managed endpoint you point one header at, violations indexed by directive, origin and page, a script inventory built from browser reports, and alerts when a new script or origin shows up where it shouldn’t.

Where to start

Order of operations, from experience: set the cookie flags this afternoon, they break almost nothing. Add frame-ancestors. Then ship a CSP in report-only mode with reporting pointed at CentralCSP, watch a few weeks of real traffic, build the policy from what actually loads, and enforce. The monitoring stays on afterwards, because the client side of your site changes every time a vendor ships, and now you’ll know when it does.

Frequently asked questions

Can a website be hacked even if the server is secure?

Yes. Attacks like XSS, Magecart skimming and clickjacking run entirely in the visitor's browser. The server keeps returning clean responses while the page, once assembled client-side, executes hostile code or gets framed on an attacker's site. Server logs show nothing unusual.

What is the difference between client-side and server-side security?

Server-side security protects infrastructure you operate: the OS, the framework, the database. Client-side security protects an environment you only configure: the visitor's browser, where your code runs next to third-party scripts on a machine you will never see. The controls are different too, headers and attributes rather than patches and firewalls.

What is the most effective client-side defense to start with?

A Content Security Policy, deployed in report-only mode first. It addresses several attack families at once (injected scripts, unknown origins, data exfiltration, framing via frame-ancestors) and its violation reports give you visibility into what actually loads on your pages before you enforce anything.

Do I need a JavaScript agent on my pages to monitor client-side attacks?

No. Browsers report CSP violations natively through the report-to and report-uri mechanisms. You add one HTTP header pointing at a collection endpoint and the telemetry arrives without any script added to the page, which matters on payment pages where every extra script is itself a risk.