Web security is one of the crucial concepts in software development. It is a set of practices that ensure your web application is protected from different kinds of attacks. When someone does some malicious things, like accessing others information or making actions on behalf of others, without the real one being aware off it, then we will completely lose the business or money. It is our core responsibility to ensure our application is secured enough so that our business runs smoothly. To maintain the security of our application, I am writing down a few important concepts that will help to deliver a well-secured app.
Common Security Risks
Cross Site Scripting Attack or XSS
It is one of the common security vulnerability. It occurs when an attacker injects malicious scripts into web pages viewed by other users. These scripts can be written in JavaScript. Let’s explore this with an example,
When users submit content via a textarea field, it’s stored in the database. An attacker put something malicious inside the textarea,
<img src onerror="alert(document.cookie)" />
Once this image is uploaded and stored in the platform’s database, whenever anyone views it, the hidden script gets activated in their browser. So, even if you’re just scrolling through their feed and come across this image, the script would still run, potentially putting your data at risk. This is a very simple example but you can consider, there can be an api calling a function that can pass the cookie to an attacker.
How to prevent?
- Sanitize user input: Validate and filter user-supplied data to remove any potentially dangerous characters. DOMPurify can help you on this.
- Content Security Policy (CSP): Content Security Policy or CSP is a security standard that prevents XSS attacks by specifying which content sources are allowed to be loaded on that web page. Learn how to set this header in nginx.
Cross Site Request Forgery (CSRF)
It is an attack that tricks you into doing things you didn’t intend to do on a website where you’re already logged in. It’s like someone secretly making you click buttons or submit forms without your knowledge, potentially causing some serious trouble. Let’s take an example of it,
Imagine you’re logged into your online banking website. You receive an email in Gmail from someone you don’t know, but it looks legitimate, asking you to click a link to see some good things. Without realising it, that link actually takes you to a page that makes you transfer money from your bank account to the attacker’s account. This is an example of a CSRF attack, where you’re tricked into performing actions on the website without your consent.
How to prevent?
- Logout when not in use: On sensitive platforms like banking, it is always better to log out, when not in use. You may notice that your banking transaction app always logs out after some time (minutes).
- Enable two factor authentication: By enabling two factor authentication it will add extra layer of security.
- Use framework: Popular server side framework like Laravel, Express(.js) etc provide own way to handle CSRF attack.
Are XSS and CSRF same?
No. For XSS, visitors executing malicious code by just viewing that can trigger XSS without requiring login. For CSRF, users need to log in; when they visit any malicious website the code will execute and perform some actions in their authenticated site.
SQL Injection
SQL injection is a code injection technique, in which attackers target databases by injecting malicious SQL statements into an entry field for execution.
To better understand that let’s explore an example,
SELECT * FROM users WHERE email=${email} AND password=${password}
This SQL statement ensures that when a user attempts to log in, the server verifies their identity against the database. Now what if an attacker pushed something malicious when submitting password? Let’s say attacker know the user email but not password. So he/she put this in password field,
555 OR (1=1)
In SQL, OR is a logical operator that evaluates to true if any of the conditions it connects are true. (1=1) is a condition that always evaluates to true, as it’s a comparison of the same value (1) with itself, resulting in a true statement.
So the server passes that true to password in sql statement,
SELECT * FROM users WHERE email=${email} AND password=true
As a result, the attacker successfully bypasses the database’s security measures.
How to prevent?
- Sanitize and Validate input: Properly sanitize and validate input before passing it to sql query.
- Use ORM: Modern ORMs give us the ability to prevent SQL Injection.
Denial-of-service (DoS) & Distributed denial-of-service (DDoS)
Denial-of-Service (DoS) is a cyber attack that disrupts or denies access to a network or service to legitimate users. Distributed denial-of-service (DDoS) is also a cyber attack, where an attacker overwhelm targeted servers using different methods, causing disruptions or denial of service to legitimate users.
How to prevent?
- Use Rate Limiting: Implement rate-limiting measures to restrict the number of requests or connections from individual IP addresses. For application level you can use package that can help you to ensure rate-limiting. For example, express(.js) has express-rate-limit.
- Use AWS WAF: For network level throttling use service like AWS WAF, that will filter and block malicious traffic targeting specific applications or services.
- Implement re-captcha.
Zero-day Vulnerabilities
It is a security weakness that software is exploited by attackers before the developer has had a chance to create a fix. The reason we call it “zero-day” is because developers have zero days to fix the issue before it’s actively exploited. Let’s explore a real world example,
Let’s say there’s a popular npm package called “example-package” that we used in our project. Someone discovers a flaw in the package’s code that allows attackers to execute malicious code on the server. Since we are using that package, we can’t figure out that flow until it’s actively exploited.
How to prevent?
- Always update your software/package.
Buffer Overflow
It is a vulnerability, when a program writes more data to a buffer(a temporary storage area in memory) than it can hold. Happens due to input data is not properly validated or the size of the input exceeds the capacity. It can lead crashing the program, corrupting data, or even allowing attackers to execute malicious code.
How to prevent?
- Properly validate input data to both server and client.
- Set maximum range for input fields.
OWASP Security Rules
An attacker can abuse any API that is vulnerable. Due to broken access control, an attacker can gain access to a particular API. So OWASP security rules give us an indication of what potential causes can create issues.
Don’t send Password or any other security information as response
When sending response to client, the response should only contain what client wants. If we send password or token then attacker can manipulate this.
How to prevent?
- Always send what is required.
Error Message
A proper error message is good in terms of the user experience, but in some cases, the error message shouldn’t express the root cause of the error. This gives the attacker a clear idea of whether the data is correct or not. For example, a login form shouldn’t specify what field is incorrect; it should specify ‘Email or Password incorrect’.
These are some security suggestions that can help you building a secured system. I hope you understand. Feel free to ask questions or give suggestions.