🔐 Web security
Summary
By adhering to these best practices, you can significantly enhance the security of your frontend application and protect against a wide range of attacks. Remember that security is an ongoing process, and regular audits and updates are essential to maintaining a secure application.
- Input Sanitize
- Prevent Cross-Site-Scripting XSS
- Add Content security policy CSP (via headers)
- Prevent Cross-Site-Request-Forgery CSRF (with csrf tokens)
- Always use HTTPs and WSS (secure only)
- Cookies with sameSite and secure
- Evaluate third party dependencies in regular interval
- IFrame - X-Frame-Options (to block embedding your site)
- IFrame - frame-ancestors in CSP (to block embedding your site)
- Secure client side logic and proper error handling
1. Input Validation and Sanitization
- Validate Input: Always validate user input on the client side, though remember that client-side validation is not a substitute for server-side validation.
- Sanitize Input: Remove or encode potentially harmful characters from user input to prevent injection attacks like Cross-Site Scripting (XSS).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Input Sanitization Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.4/purify.min.js"></script>
</head>
<body>
<div id="output"></div>
<script>
function sanitizeInput(input) {
return DOMPurify.sanitize(input);
}
const userInput = '<img src=x onerror=alert("XSS Attack!") />';
document.getElementById('output').innerHTML = sanitizeInput(userInput);
</script>
</body>
</html>
2. Cross-Site Scripting (XSS) Prevention
- Output Encoding: Encode data before rendering it in the HTML to prevent XSS attacks. Use libraries like DOMPurify to sanitize HTML.
- Avoid
eval
: Avoid usingeval()
or similar functions (setTimeout
,setInterval
with string arguments) which can execute arbitrary code. - CSP (Content Security Policy): Implement CSP headers to restrict the sources from which content (scripts, styles, etc.) can be loaded.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>XSS Prevention Example</title>
</head>
<body>
<div id="output"></div>
<script>
function escapeHTML(input) {
const div = document.createElement('div');
div.appendChild(document.createTextNode(input));
return div.innerHTML;
}
const userInput = '<script>alert("XSS Attack!")</script>';
document.getElementById('output').innerHTML = escapeHTML(userInput);
</script>
</body>
</html>
3. Cross-Site Request Forgery (CSRF) Prevention
- CSRF Tokens: Use CSRF tokens to ensure that requests made on behalf of users are legitimate.
- SameSite Cookies: Set cookies with the
SameSite
attribute to prevent them from being sent along with cross-site requests.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSRF Prevention Example</title>
</head>
<body>
<button id="submitBtn">Submit</button>
<script>
document.getElementById('submitBtn').addEventListener('click', () => {
const csrfToken = 'your-csrf-token';
fetch('/your-api-endpoint', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'CSRF-Token': csrfToken
},
body: JSON.stringify({ data: 'example data' })
}).then(response => {
if (response.ok) {
return response.json();
}
throw new Error('Network response was not ok.');
}).then(data => {
console.log(data);
}).catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
});
</script>
</body>
</html>
4. Authentication and Authorization
- Use Secure Authentication Methods: Implement strong authentication mechanisms (e.g., OAuth, JWT) and ensure that passwords are hashed and salted before storing.
- Access Control: Implement proper access control checks to ensure users can only access resources they are authorized to.
5. Secure Communication
- HTTPS: Always use HTTPS to encrypt data transmitted between the client and server. Use HSTS (HTTP Strict Transport Security) to enforce HTTPS.
- Secure WebSockets: If using WebSockets, ensure they are secure (wss://) to protect against man-in-the-middle attacks.
6. Secure Storage
- Avoid Storing Sensitive Data: Avoid storing sensitive data (like passwords or tokens) in local storage or session storage, as they are accessible through JavaScript.
- Secure Cookies: Store tokens and other sensitive information in cookies with
HttpOnly
andSecure
flags.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Secure Cookie Example</title>
</head>
<body>
<script>
function setSecureCookie(name, value, days) {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = '; expires=' + date.toUTCString();
}
document.cookie = `${name}=${value || ''}${expires}; path=/; Secure; HttpOnly; SameSite=Strict`;
}
setSecureCookie('sessionId', '123456', 7);
</script>
</body>
</html>
7. Third-Party Dependencies
- Review and Monitor Dependencies: Regularly review and update third-party libraries to ensure they do not introduce vulnerabilities.
- Use Subresource Integrity (SRI): Use SRI to ensure that the content of external scripts and stylesheets has not been tampered with.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SRI Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"
integrity="sha384-KyZXEAg3QhqLMpG8r+Knujsl5+5hb7O9l5m5V6zr9bU8pmM/sG4XfrdeL8wo/fFz"
crossorigin="anonymous"></script>
</head>
<body>
<script>
$(document).ready(function() {
console.log('jQuery loaded with SRI.');
});
</script>
</body>
</html>
8. Error Handling
- Generic Error Messages: Avoid displaying detailed error messages to users. Instead, log errors on the server and show generic messages to users.
- Catch Errors: Use try-catch blocks and error handling mechanisms to prevent application crashes and exposure of stack traces.
9. Clickjacking Protection
- X-Frame-Options: Use the
X-Frame-Options
header to prevent your site from being embedded in iframes, which can prevent clickjacking attacks. - CSP Frame Ancestors: Use the
frame-ancestors
directive in CSP to control which sites can embed your pages.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://cdnjs.cloudflare.com">
<title>Content Security Policy Example</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
console.log('jQuery is loaded and CSP is in effect.');
});
</script>
</body>
</html>
10. Secure Client-Side Logic
- Minify and Obfuscate: Minify and obfuscate JavaScript code to make it harder for attackers to understand and tamper with.
- Avoid Sensitive Logic on Client Side: Avoid putting sensitive logic or business rules on the client side where they can be easily inspected and manipulated.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Avoid Eval Example</title>
</head>
<body>
<script>
// Instead of using eval
// let result = eval('2 + 2');
// Use function constructors or direct code
let result = (function() {
return 2 + 2;
})();
console.log(result); // Output: 4
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Secure Event Handlers Example</title>
</head>
<body>
<button id="submitBtn">Submit</button>
<script>
document.getElementById('submitBtn').addEventListener('click', () => {
console.log('Button clicked!');
});
</script>
</body>
</html>