Client Side Security
What It Is
Client-side security means protecting the data, tokens, sessions, and browser storage used by a frontend application.
In the browser, data can be stored in places like localStorage, sessionStorage, IndexedDB, cookies, and cache storage.
Frontend App -> Browser Storage -> Tokens / Session Data / Cached Data
The main idea is simple:
Do not trust the client completely.
Store less data.
Protect what must be stored.
Expire sensitive values.
Verify that data was not changed.
Why It Matters
Client-side storage is useful, but it can become risky if sensitive data is stored carelessly.
Examples of sensitive data:
- passwords
- tokens
- session IDs
- personal user data
- payment-related data
- identity-related data
If this data is exposed or modified, it can affect the user account, application security, and data correctness.
| Area | Why It Matters |
|---|---|
| Sensitive data storage | Browser storage can be inspected or misused |
| Authentication | Tokens and sessions must be controlled properly |
| Data integrity | Stored data should not be changed silently |
| Storage limit | Too much client-side data can hurt performance or cause data loss |
| Session management | Sessions and cookies must be handled safely |
Core Flow
Need to store data in browser?
↓
Check if it can stay on the server
↓
If client storage is required
↓
Store only required data
↓
Encrypt sensitive data if needed
↓
Set token/session expiry
↓
Verify data integrity
↓
Check storage usage and quota
↓
Manage session cookies safely
Main Security Goals
Client-side security mainly focuses on five important goals.
| Goal | Simple Meaning | Main Practice |
|---|---|---|
| Sensitive Data Protection | Avoid exposing private data in the browser | Prefer server storage, encrypt if required, set expiry |
| Authentication Safety | Login/session should be secure | Use JWT/OAuth/OIDC, session expiry, and MFA |
| Data Integrity | Data should not be changed secretly | Use checksum or integrity checks |
| Storage Control | Browser storage should not exceed limits | Track usage and avoid storing too much data |
| Session Management | Sessions and cookies should be safe | Use proper cookie flags and server-managed sessions |
Sensitive Data Storage
The safest rule is:
Try to store sensitive data on the server first.
Client storage should only contain data that is actually required by the frontend.
Bad example:
localStorage.setItem("password", "mySecretPassword");
This is unsafe because the browser is not a fully trusted place.
Better example:
const sensitiveData = "cached-profile-data";
const encryptedData = encryptFunction(sensitiveData);
localStorage.setItem("encryptedData", encryptedData);
This is better than storing raw data, but it does not make client storage completely safe. Do not store passwords in browser storage, even encrypted, because client-side keys and code can be exposed.
Encryption reduces risk.
Server-side storage is still safer for truly sensitive data.
Token Expiry
Tokens should not remain valid forever.
If a token is stored on the client, it should have a short expiration time so the risk window is smaller.
const token = generateToken();
const tokenExpirationTime = 15 * 60 * 1000; // example: 15 minutes
localStorage.setItem("token", token);
setTimeout(() => {
localStorage.removeItem("token");
}, tokenExpirationTime);
Simple idea:
Token created -> token stored -> token expires -> token removed/invalidated
Client-side removal is only local cleanup. The token must also expire or be invalidated on the server side.
| Without Token Expiry | With Token Expiry |
|---|---|
| Token may stay usable for a long time | Token becomes unusable after a fixed time |
| Higher risk if token is leaked | Lower risk window |
| Session may stay active unnecessarily | Session is controlled better |
Authentication
Authentication should use standard and secure mechanisms.
The PDF highlights:
- JWT/OAuth or OpenID Connect depending on the login flow
- session token expiry
- MFA, meaning multi-factor authentication
User logs in
↓
Server verifies user
↓
Server issues token/session
↓
Client stores only what is required
↓
Token/session expires after a fixed time
MFA adds another layer of security because the user needs more than just a password.
Password only -> weaker
Password + MFA -> stronger
Data Integrity
Data integrity means data has not been changed in an unauthorized way.
It applies to data:
- in storage
- during processing
- while in transit
Simple meaning:
Data integrity = data is still the same as expected
For browser storage, this means we may need to verify whether stored data was modified.
Checksum for Data Integrity
A checksum can be used to check whether stored data changed accidentally. For security against tampering, use a keyed MAC/signature or server-side verification because an attacker who can edit client storage may also edit a plain checksum.
const dataToStore = "myData";
const checksum = calculateChecksum(dataToStore);
localStorage.setItem("data", dataToStore);
localStorage.setItem("checksum", checksum);
const storedData = localStorage.getItem("data");
const storedChecksum = localStorage.getItem("checksum");
if (calculateChecksum(storedData) === storedChecksum) {
console.log("Data integrity is intact");
} else {
console.log("Data may have been changed");
}
Important difference:
Encryption hides data.
Checksum detects accidental data changes.
MAC/signature detects unauthorized changes.
So, encryption, checksum, and MAC/signature solve different problems.
Storage Limit
Browser storage is limited.
The PDF mentions two major impacts of storing too much data on the client:
- It affects performance.
- Storing more data than the browser capacity can lead to data loss.
More client-side data
↓
More browser storage usage
↓
Possible performance impact
↓
Quota errors or data loss
Client Storage Limits
Common browser storage limits mentioned in the PDF:
| Storage Type | Approximate Limit |
|---|---|
localStorage | 5-10 MB |
sessionStorage | 5-10 MB |
IndexedDB | 50-100 MB |
| Cookie | 4 KB-20 KB |
| Cache API | Browser-managed |
Use larger storage like IndexedDB only when the app really needs it, such as for offline data or structured client-side data.
Checking Storage Usage
The browser StorageManager API can be used to estimate current usage and available quota.
function hasEnoughSpaceForData() {
if ("storage" in navigator && "estimate" in navigator.storage) {
navigator.storage.estimate().then((estimate) => {
console.log(
"Usage: " + (estimate.usage / 1024 / 1024).toFixed(2) + " MB",
);
console.log(
"Quota: " + (estimate.quota / 1024 / 1024).toFixed(2) + " MB",
);
});
} else {
console.log("StorageManager API is not supported in this browser.");
}
}
This is useful when the frontend stores data for:
- offline support
- cached API responses
- PWA data
- IndexedDB records
- media or file cache
Session Management
Sessions and cookies should be managed carefully.
A session usually connects a browser user with server-side user data.
Browser has session ID
↓
Server maps session ID to user data
↓
User stays authenticated
For session cookies, use proper cookie flags.
res.cookie("sessionId", sessionId, {
httpOnly: true,
secure: true,
});
| Cookie Flag | Purpose |
|---|---|
HttpOnly | Helps prevent JavaScript from reading the cookie |
Secure | Sends the cookie only over HTTPS |
Important note:
Session cookies should usually be controlled from the server.
Do not depend only on client-side JavaScript for session security.
Basic Checklist
Use this checklist when reviewing client-side security:
- Avoid storing sensitive data in browser storage.
- Prefer server-side storage for highly sensitive data.
- Encrypt sensitive data if it must be stored on the client.
- Set expiry for tokens and sessions.
- Use proper authentication methods like JWT/OAuth/OIDC.
- Add MFA where stronger authentication is needed.
- Use checksums for accidental changes, and MAC/signature checks for tamper resistance.
- Respect browser storage limits.
- Check storage usage for large/offline apps.
- Use secure cookie flags like
HttpOnlyandSecure.
Interview Style Answer
Client-side security means protecting data, tokens, sessions, and storage handled by the browser. Since browser storage is not fully trusted, we should avoid storing sensitive data on the client whenever possible and prefer storing it on the server. If data must be stored on the client, we should minimize it, encrypt it, and set proper expiry for tokens on the server side. Authentication should use secure approaches like JWT, OAuth/OpenID Connect, session token expiry, and MFA. For data integrity, checksums can detect accidental changes, while MAC/signature checks are needed for tamper resistance. We should also respect browser storage limits because storing too much data can affect performance or cause data loss. For sessions, cookies should be managed carefully using flags like HttpOnly and Secure.
One-Line Summary
Client-side security means storing less sensitive data in the browser, protecting what must be stored, expiring tokens, validating integrity, respecting storage limits, and managing sessions safely.
Final Mental Model
Client storage is useful, but not fully trusted.
Remember it like this:
Client-side Security = Store Less + Encrypt + Expire + Verify + Limit + Secure Sessions
Or even simpler:
Server first.
Client only when needed.
Protect everything important.