7.4 KiB
XSS Prevention Guide
Overview
Cross-Site Scripting (XSS) is a security vulnerability that allows attackers to inject malicious scripts into web pages viewed by other users. This guide provides best practices for preventing XSS attacks in frontend applications that interact with the Farm Auth Service.
Server-Side Protection
The Farm Auth Service implements several server-side protections:
1. Content Security Policy (CSP)
The service sets a strict Content Security Policy header that:
- Restricts script execution to same-origin and nonce-based inline scripts
- Prevents unauthorized resource loading
- Blocks inline event handlers and
javascript:URLs
CSP Header Example:
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-...' 'unsafe-eval'; style-src 'self' 'nonce-...'; ...
2. Security Headers
Additional security headers are set:
X-XSS-Protection: 1; mode=block- Legacy browser XSS filterX-Content-Type-Options: nosniff- Prevents MIME type sniffingX-Frame-Options: DENY- Prevents clickjacking
3. CORS Protection
Strict CORS origin whitelisting prevents unauthorized domains from making requests.
Frontend Best Practices
1. Output Encoding
Always encode user input before displaying it:
// ❌ BAD - Vulnerable to XSS
document.getElementById('username').innerHTML = userInput;
// ✅ GOOD - Safe
document.getElementById('username').textContent = userInput;
For HTML content, use proper encoding:
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// Use when you must set innerHTML
element.innerHTML = escapeHtml(userInput);
2. Avoid Dangerous APIs
Never use these with user input:
innerHTMLouterHTMLdocument.write()eval()Function()constructorsetTimeout()/setInterval()with string arguments
Use safe alternatives:
textContentinstead ofinnerHTMLsetAttribute()for attributesaddEventListener()instead of inline event handlers
3. Content Security Policy Nonce Support
If you need inline scripts or styles, use CSP nonces:
// Get nonce from meta tag (if server sets it)
const nonce = document.querySelector('meta[name="csp-nonce"]')?.content;
// Use nonce in script tag
const script = document.createElement('script');
script.nonce = nonce;
script.textContent = '// Your inline script';
document.head.appendChild(script);
Note: The current CSP configuration allows 'unsafe-inline' for compatibility, but this should be tightened in production by using nonces exclusively.
4. Sanitize User Input
For rich text content, use a sanitization library:
// Using DOMPurify (recommended)
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userInput, {
ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a', 'p'],
ALLOWED_ATTR: ['href']
});
element.innerHTML = clean;
5. URL Validation
Always validate and sanitize URLs:
function isValidUrl(url) {
try {
const parsed = new URL(url);
// Only allow http/https
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch {
return false;
}
}
// Use for links
if (isValidUrl(userUrl)) {
link.href = userUrl;
} else {
link.href = '#';
link.onclick = (e) => { e.preventDefault(); alert('Invalid URL'); };
}
6. JSON Handling
Always parse JSON safely:
// ❌ BAD - eval() is dangerous
const data = eval('(' + jsonString + ')');
// ✅ GOOD - Use JSON.parse()
try {
const data = JSON.parse(jsonString);
} catch (e) {
console.error('Invalid JSON');
}
7. React / Vue / Angular Specific
React:
- React automatically escapes content in JSX
- Use
dangerouslySetInnerHTMLonly when necessary and sanitize first - Never use
dangerouslySetInnerHTMLwith user input
// ✅ GOOD - React escapes automatically
<div>{userInput}</div>
// ⚠️ CAUTION - Only if absolutely necessary
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
Vue:
- Use
v-textinstead ofv-htmlwhen possible - Sanitize before using
v-html
<!-- ✅ GOOD -->
<div v-text="userInput"></div>
<!-- ⚠️ CAUTION - Sanitize first -->
<div v-html="sanitizedInput"></div>
Angular:
- Use interpolation
{{ }}which automatically escapes - Use
[innerHTML]only with sanitized content
// ✅ GOOD - Angular escapes automatically
<div>{{ userInput }}</div>
// ⚠️ CAUTION - Use DomSanitizer
import { DomSanitizer } from '@angular/platform-browser';
const safe = this.sanitizer.sanitize(SecurityContext.HTML, userInput);
8. API Response Handling
Never trust API responses blindly:
// ❌ BAD - Directly inserting API response
fetch('/api/user')
.then(r => r.json())
.then(data => {
document.getElementById('profile').innerHTML = data.bio; // DANGEROUS!
});
// ✅ GOOD - Sanitize or use textContent
fetch('/api/user')
.then(r => r.json())
.then(data => {
document.getElementById('profile').textContent = data.bio; // Safe
});
9. Cookie Security
Set secure cookie flags (server-side):
HttpOnly- Prevents JavaScript accessSecure- Only sent over HTTPSSameSite=Strict- Prevents CSRF
Note: The Farm Auth Service uses Bearer tokens, not cookies, which is more secure.
10. Third-Party Libraries
Be cautious with third-party libraries:
- Only use well-maintained, trusted libraries
- Keep dependencies updated
- Review library code for XSS vulnerabilities
- Use Content Security Policy to restrict external scripts
Testing for XSS
Manual Testing
Try these payloads in input fields:
<script>alert('XSS')</script>
<img src=x onerror=alert('XSS')>
<svg onload=alert('XSS')>
javascript:alert('XSS')
<iframe src="javascript:alert('XSS')">
Automated Testing
Use tools like:
- OWASP ZAP
- Burp Suite
- XSSer
- Browser DevTools Console
Common XSS Attack Vectors
- Stored XSS: Malicious script stored in database and executed when displayed
- Reflected XSS: Malicious script in URL parameters reflected in response
- DOM-based XSS: Malicious script in DOM manipulation without server interaction
Checklist
- All user input is encoded before display
- No use of
innerHTMLwith user input - URLs are validated before use
- JSON is parsed safely (not with
eval()) - Third-party libraries are vetted and updated
- CSP nonces are used for inline scripts/styles
- API responses are sanitized
- Framework-specific best practices are followed
- Regular security audits are performed
Additional Resources
Reporting Security Issues
If you discover an XSS vulnerability in the Farm Auth Service, please report it responsibly:
- Do not disclose publicly
- Contact the security team
- Provide detailed reproduction steps
- Allow time for fix before disclosure
Last Updated: 2024 Version: 1.0