Web security is a critical component of any online application, as even minor oversights can leave systems exposed to significant threats. This article will cover the most common web vulnerabilities and provide actionable strategies to protect against them. You’ll find code examples in JavaScript, HTML, and SQL where relevant, allowing you to quickly apply these practices in your own projects.
SQL Injection
SQL Injection is a type of attack where an attacker inserts or "injects" malicious SQL queries into an application’s input fields, potentially gaining unauthorized access to the database.
How to prevent it:
- Use parameterized queries or prepared statements rather than directly concatenating user inputs into SQL queries.
- Input Validation: Never trust user input. Sanitize and validate user input to prevent malicious code injection.
BAD
const userInput = req.body.email;
const query = `SELECT * FROM users WHERE email = '${userInput}'`;
db.query(query, (err, result) => {
if (err) throw err;
// Process result
});
BETTER
const userInput = req.body.email;
const query = `SELECT * FROM users WHERE email = ?`;
db.query(query, [userInput], (err, result) => {
if (err) throw err;
// Process result
});
By using parameterized queries, the user’s input is treated as data, not executable code, eliminating the risk of SQL injection.
Cross-Site Scripting (XSS)
Cross-Site Scripting (XSS) is a type of web security vulnerability that allows an attacker to inject malicious scripts into web pages viewed by other users. When a vulnerable website allows user-supplied content to be displayed without proper validation and sanitization, an attacker can exploit this weakness to execute malicious code in the victim's browser.
How to prevent it:
- Content Security Policy (CSP): A security header that restricts the sources of content that can be loaded on a website.
- Escape special characters to prevent their interpretation as HTML or JavaScript. Modern frontend libraries/frameworks like React automatically escapes special characters in strings to prevent them from being interpreted as HTML or JavaScript, protecting applications from potential Cross-Site Scripting (XSS) attacks.
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self';
Cross-Site Request Forgery (CSRF)
CSRF tricks users into unknowingly executing malicious actions while they are authenticated on a site.
An attacker creates a malicious website that contains a hidden form or script, the victim logs into the trusted website, the victim is tricked into clicking a link or opening an image on the malicious website, which automatically submits a request to the trusted website, often using the victim's authenticated session. The trusted website processes the malicious request, thinking it's coming from the legitimate user, leading to unauthorized actions like transferring funds, changing passwords, or deleting data.
How to prevent:
- This usually involves the backend generating CSRF tokens unique to each session and validate them for every form submission.
- Add anti-CSRF tokens to forms as hidden fields, and implement SameSite cookies to ensure cookies are not sent with cross-site requests. (Frontend task).
- The Referer header: server checks the referer header to ensure requests are coming form a trusted domain. Referer header indicates the origin of the HTTP request.
<form action="/submit" method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit">Submit</button>
</form>
Security Headers
Security headers are HTTP response headers that can be set by a web server to enhance the security of a website. These headers provide instructions to the browser on how to handle requests and responses, mitigating various web vulnerabilities.
Key Security Headers
Here are some of the most important security headers and their functions:
1. Strict-Transport-Security (HSTS):
- Forces browsers to only communicate with the website over HTTPS, preventing downgrade attacks.
Strict-Transport-Security: max-age=31536000; includeSubDomains;
2. Content-Security-Policy (CSP):
- Restricts the sources from which a browser can load resources like scripts, stylesheets, and images.
- Helps prevent XSS and other injection attacks.
Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com; style-src 'self'; img-src 'self';
3. X-Frame-Options:
- Prevents clickjacking attacks by restricting the ability of a website to be embedded in an iframe.
X-Frame-Options: DENY or X-Frame-Options: SAMEORIGIN
4. X-XSS-Protection:
- Instructs the browser to enable its built-in XSS protection mechanisms.
X-XSS-Protection: 1; mode=block
5. Referrer-Policy:
- Controls how much information is sent in the Referer header, reducing the risk of information leakage.
Referrer-Policy: no-referrer-when-downgrade
6. X-Content-Type-Options:
- Prevents MIME sniffing, which can lead to unexpected behavior and security vulnerabilities.
X-Content-Type-Options: nosniff
Sensitive Data Exposure
This is a security vulnerability that occurs when personal or confidential information is exposed to unauthorized individuals. This can lead to serious consequences, such as identity theft, financial loss etc.
How to prevent:
- Encrypt data at rest and in transit: Use HTTPS for encrypted data transmission and encrypt sensitive data at rest using strong hashing algorithms.
- Avoid including sensitive data in local storage, session storage, or URLs.
Conclusion
A comprehensive web security strategy involves securing both the frontend and backend to prevent vulnerabilities from different entry points. By using parameterized queries, CSRF tokens, data protection, and security headers, you can establish robust defenses against common attacks. Regularly review and update your security practices to stay ahead of emerging threats and keep your applications secure for users.
Osaretin Igbinobaro
Software Engineer @ Apadmi