Application Security

Client-side security

Client-side security is the protection of code, data, and user interactions that run in or are exposed to the user's browser, mobile app, or local client.

In plain terms

Client-side security protects the code and data running in the user’s browser or app - where the user (and attackers) can see and tamper with it. A reminder that anything on the client cannot be fully trusted, so the server must still enforce the rules.

Because the browser, mobile app, or desktop client runs outside the organization’s direct control, any code, data, or user interaction that executes there can be inspected and tampered with - a reality that makes client-side security essential yet inherently limited. In web applications, the phrase usually refers to JavaScript, HTML, CSS, browser storage, cookies, frontend frameworks, third-party scripts, and browser-enforced controls. The core principle is that client-side code is important, but it cannot be fully trusted by the server.

The client is outside the organization’s direct control. Users, attackers, proxies, browser extensions, malware, debugging tools, modified mobile apps, and automated scripts can inspect or alter what happens on the client. They can change form fields, bypass disabled buttons, call APIs directly, modify local storage, replay requests, remove frontend validation, or tamper with application state. For that reason, client-side security must be paired with server-side authentication, authorization, validation, and business-rule enforcement.

Client-side security is not the same as simply securing JavaScript. JavaScript security is a major part of it, but the scope also includes browser isolation, DOM manipulation, cookie attributes, local storage choices, cross-origin behavior, embedded content, client-side routing, service workers, dependency loading, source maps, build artifacts, secrets mistakenly included in frontend bundles, and how sensitive operations are represented in the user interface.

A common failure is trusting frontend controls as enforcement. A website may hide an admin button, disable a field, calculate a price in JavaScript, or prevent file uploads with client-side checks. These controls improve usability, but they are not sufficient security controls because an attacker can send modified requests directly to the server. The server must verify who is making the request, whether the action is allowed, whether input is valid, and whether the resulting state is safe.

Cross-site scripting is one of the most important client-side risks. If attacker-controlled script runs under a trusted origin, it can read page content, manipulate the DOM, send requests as the user, steal exposed tokens, rewrite forms, or capture user actions. Defenses include context-aware output encoding, safe templating, avoiding dangerous DOM sinks, sanitizing rich text with proven libraries, using Content Security Policy, and keeping session material out of script-readable storage when possible.

Browser security boundaries matter. The same-origin policy limits how scripts from one origin can read data from another origin. CORS creates controlled exceptions for cross-origin reads. Content Security Policy restricts which resources and behaviors a page can use. Cookie attributes such as HttpOnly, Secure, and SameSite reduce exposure of session cookies. Frame controls reduce clickjacking. These mechanisms are strongest when they are designed together rather than added after an incident.

Third-party scripts are a major client-side dependency. Analytics tags, payment widgets, chat tools, advertising scripts, consent tools, monitoring agents, and content delivery networks can execute in the user’s browser with significant access to the page. A compromised or overly privileged third-party script can read sensitive data, change forms, capture credentials, or inject malicious behavior. Organizations should inventory third-party scripts, minimize what they load, isolate where possible, use subresource integrity when practical, review permissions, and monitor unexpected changes.

Client-side storage requires careful choices. Browser local storage, session storage, IndexedDB, caches, service workers, and mobile app storage can expose tokens, personal data, or sensitive business information if the device is shared, compromised, backed up insecurely, or attacked through XSS. Highly sensitive tokens should not be stored in places that arbitrary script can read. Applications should minimize stored data, expire it appropriately, clear it on logout where possible, and avoid placing secrets in frontend code.

Build and deployment pipelines influence client-side security. Modern applications rely on package managers, bundlers, transpilers, minifiers, source maps, dependency trees, and generated assets. Dependency confusion, malicious packages, vulnerable libraries, exposed source maps, hard-coded API keys, and unreviewed build plugins can all create client-side risk. Secure development practices should include dependency scanning, lockfiles, secret scanning, code review, and controlled releases.

Client-side security also includes user-interface integrity. Attackers may try to trick users through clickjacking, form injection, browser extension abuse, open redirects, malicious deep links, or manipulated display data. Security-sensitive actions should be clear, resistant to framing where appropriate, protected by server-side checks, and confirmed when risk is high. The interface should not display untrusted content as if it were trusted system information.

Mobile and desktop clients have similar trust issues. A mobile app may include API endpoints, feature flags, certificates, or business logic that attackers can reverse engineer. Obfuscation and tamper checks can raise effort, but they do not replace server-side controls. APIs used by clients must assume that requests can come from modified clients and automated tools.

Effective client-side security programs test both code and behavior. Reviews should look for unsafe DOM sinks, untrusted data flows, token exposure, permissive CORS, weak CSP, dangerous dependencies, source map exposure, browser storage misuse, third-party scripts, and missing server-side enforcement. Dynamic testing with a real browser is important because many flaws appear only after JavaScript runs and the DOM changes.

For example, an online store may use JavaScript to show discounts and prevent users from entering invalid quantities. That improves the user experience, but the backend must still recalculate prices, validate inventory, authorize the account, and reject manipulated requests. The client can guide the user; the server must enforce the rule.

Learn more in Application Security

Related terms