Modern front-end apps are not “just UI”. They handle user input, store tokens, call APIs, and display data from servers. That makes security everyone’s job, including front-end developers.
This topic covers practical security controls you should apply in real projects: HTTPS, secure headers, input validation and sanitisation, protection against common attacks (XSS and SQL injection), and safe secrets management.
1) Always use HTTPS (and enforce it)
HTTPS protects data in transit (between the browser and the server) by encrypting it. Without HTTPS, attackers on the same network can read or change requests and responses.
What you must do
- Serve the entire site over HTTPS, including:
- API calls
- Images, fonts, scripts, and third-party assets
- Redirect HTTP → HTTPS at the web server / hosting layer.
- Use HSTS (HTTP Strict Transport Security) so browsers remember to only use HTTPS.
Why it matters
- Protects login credentials, session cookies, and personal information.
- Prevents “man-in-the-middle” attacks that inject malicious scripts.
- Some browser features (like service workers for PWAs) require HTTPS.
Key points
- In development you may use
http://localhost, but treat that as a special case. - In production, mixed content (loading HTTP assets on an HTTPS page) should be considered a defect.
2) Secure headers (browser-level protections)
Security headers tell the browser how to behave. Many attacks are reduced or blocked when the right headers are set.
Important headers to know
Content-Security-Policy (CSP)
- Helps prevent XSS by restricting where scripts, styles, images, and other resources can load from.
- You can also block inline scripts and only allow scripts with a nonce/hash.
Example (conceptual):
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
X-Content-Type-Options
- Prevents MIME sniffing.
X-Content-Type-Options: nosniff
X-Frame-Options (or use CSP frame-ancestors)
- Helps prevent clickjacking by controlling who can embed your site in an iframe.
X-Frame-Options: DENY
Referrer-Policy
- Controls how much referrer information is sent when users click links.
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
- Restricts powerful browser features (camera, microphone, geolocation, etc.).
Permissions-Policy: geolocation=(), microphone=(), camera=()
Where to set them
- Best set at the server/hosting layer (Nginx/Apache/Node, CDN, platform config).
- Some frameworks provide security middleware (for example, common Node setups use middleware to set headers).
3) Input validation and sanitisation (front-end and back-end)
All user input is untrusted:
- Form fields
- URL parameters and query strings
- Headers
- API responses from external services
- Anything stored in local storage and later reused
Validation vs sanitisation
- Validation: checking input matches what you expect (type, length, format, range).
- Sanitisation: cleaning or escaping input so it is safe to store, process, or display.
Front-end validation: useful but not enough
Front-end validation is good for:
- Better user experience (instant feedback)
- Reducing accidental errors
But it is not security by itself, because attackers can:
- Bypass the UI
- Send requests directly to your API
Back-end validation: mandatory
Your server must validate:
- Data types and formats (e.g. email format, phone number patterns)
- Length limits (to reduce abuse and unexpected behaviour)
- Allowed values (e.g. roles cannot be set by the client)
- File uploads (type, size, scanning, safe storage)
Practical rules
- Apply allow-lists (what is allowed) rather than block-lists (what is forbidden).
- Put strict length limits on strings.
- Validate at boundaries: when requests enter your API, and before writing to a database.
4) Protect against common attacks
4.1 Cross-Site Scripting (XSS)
What it is
XSS happens when an attacker gets your site to run malicious JavaScript in a user’s browser. This can lead to:
- Session hijacking (stealing cookies/tokens)
- Changing what users see (defacement, fake payment prompts)
- Performing actions as the user
Where it commonly happens
- Rendering user-generated content (comments, profiles)
- Displaying API data that contains HTML
- Using unsafe DOM operations
How to reduce XSS risk
- Escape output: When displaying data, ensure it is treated as text, not HTML.
- Avoid dangerous patterns:
- Don’t insert untrusted strings into the DOM as HTML.
- Be careful with code that interprets strings as markup.
- Use CSP to limit what scripts can run.
- Keep dependencies updated (XSS can also come via third-party packages).
Framework note
Many modern frameworks escape values by default in templates, which helps. XSS risk increases when you bypass those protections (for example, by rendering raw HTML). Treat “render raw HTML” as an exception that requires strict controls.
4.2 SQL Injection (and database injection)
What it is
SQL injection happens when attackers manipulate database queries by sending crafted input. They can:
- Read private data
- Change or delete records
- Bypass login checks (in poorly built systems)
How to prevent it
- Use parameterised queries (prepared statements) or a safe ORM.
- Never build SQL with string concatenation using user input.
- Validate input, even when using parameterised queries (helps reduce edge cases and abuse).
- Use least-privilege database accounts (your app should not connect as a database admin).
Front-end takeaway
Even though SQL injection is mainly a back-end issue, front-end developers should:
- Assume all server-side validation is necessary (don’t rely on “the UI won’t allow it”).
- Avoid sending unnecessary fields that could be misused (e.g. sending
role: "admin"from the client).
4.3 Authentication and authorisation mistakes (common in front-end apps)
Important difference
- Authentication: who the user is (login)
- Authorisation: what they are allowed to do (permissions)
Key rules
- Never trust authorisation decisions done only in the browser.
- Hiding an “Admin” button is not security.
- The API must enforce permissions.
- Protect against IDOR (Insecure Direct Object Reference):
- Example: changing
/api/orders/123to/api/orders/124should not expose someone else’s order.
- Example: changing
- Keep sessions secure:
- Prefer secure cookies set by the server for session identifiers where appropriate.
- If using tokens, understand storage risks (see below).
5) Safe secrets management (don’t leak keys)
A “secret” is anything that grants access:
- API keys
- Database credentials
- JWT signing keys
- OAuth client secrets
- Private keys
- Admin passwords
Core principle
Never ship secrets to the browser.
Anything in front-end code is public:
- Bundled JavaScript can be viewed by anyone
- Environment values prefixed for front-end builds are still visible in the final bundle
- “Obfuscation” is not a real defence
What to do instead
- Keep secrets on the server (or serverless functions).
- The front-end calls your API; your API calls third-party services using secrets.
- Use environment variables on the server/hosting platform (not hard-coded in code).
Practical workflow tips
- Add
.envfiles to.gitignore. - Rotate secrets if you suspect exposure.
- Use separate secrets for development, staging, and production.
- Apply least privilege: keys should only access what they need.
6) Secure use of tokens and storage (front-end focus)
Front-end apps often store authentication state. This is a common source of vulnerabilities.
Common storage options (and risks)
- Local storage / session storage
- Easy to use, but vulnerable if XSS happens (malicious scripts can read tokens).
- Cookies
- If using cookies for session tokens, configure:
HttpOnly(reduces token theft via JS)Secure(HTTPS only)SameSite(reduces CSRF risk)
- If using cookies for session tokens, configure:
Reduce exposure
- Keep tokens short-lived where possible.
- Prefer server-managed sessions if it fits your architecture.
- Avoid storing more user data in the browser than necessary.
7) Dependency and supply-chain safety
Modern front-end development uses many packages. Attackers sometimes target the dependency chain.
Good habits
- Use a lockfile (
package-lock.json,pnpm-lock.yaml, etc.) and commit it. - Keep dependencies updated.
- Use automated checks (audit tooling in CI).
- Remove unused dependencies.
- Only use trusted packages (check maintenance, downloads, repository, and history).
8) Quick checklist for projects
Use this as a practical review before release:
- [ ] Site and API use HTTPS only; HTTP redirects to HTTPS
- [ ] HSTS enabled in production
- [ ] Key security headers set (CSP, nosniff, frame restrictions, referrer policy)
- [ ] Input is validated on the server, not only in the UI
- [ ] Output is escaped; avoid rendering raw HTML without strict controls
- [ ] Database access uses parameterised queries / ORM
- [ ] No secrets in front-end code, repos, or client environment variables
- [ ] Auth and authorisation enforced by the API
- [ ] Dependencies audited and updated; lockfile committed
Knowledge check (self-assessment)
- Why is front-end validation not enough to secure an application?
- What is the main purpose of a Content Security Policy (CSP)?
- Name two ways XSS can impact users.
- Why should secrets never be included in front-end bundles?
- What is the difference between authentication and authorisation?