When I started developing web applications in 2005, our task was to make web pages that work. Security and user data privacy was never high on the agenda. Even if we did follow some practices, it never went beyond tightening our web server and database defaults to cover for known vulnerabilities. At the max we would make our pages “SQL injection” proof.
This post is an attempt to change that, and to list in one place everything you should know to secure your application. Proactivity is much valued when it comes to security, as often it is too late if you wait for a security breach to act. The 10 security vulnerabilities I list here are quite common with well known and documented solutions.
1. SQL Query Injection – We must never trust unfiltered input coming from the user, and make sure we check the input satisfies the validity conditions it is supposed to. Only then should we do any further processing with user input coming from the front end. It is not uncommon for attackers to inject commands into user inputs, which allowed to pass through without sanitisation, can do much harm to our underlying databases and underlying systems.
2. XSS – Cross Site Scripting – This happens when an attacker is able to execute a script in a user’s browser due to lack of validation of user input. An attacker can use XSS to steal the user’s session or other sensitive data like credit cards, etc.
The solution to a XSS attack is simple – escape all input that is to be presented to the user on the web page itself. This will make sure we don’t return any HTML tags to the user. Escaping characters and encoding them will prevent any XSS attacks. Example –
& encoded as & < encoded as < > encoded as > " encoded as "
3. XSRF – Cross Site Request Forgery – In a CSRF attack, an end user is tricked by an attacker into submitting a web request that they did not intend. A compromised user may never know that such an attack has occurred. Typically, the attacker persuades a victim to click on a link by using a social-engineering technique like an email or some other form of communication. This kind of attack only works when the user is already authenticated on the website, but it can be very harmful when it works.
We can prevent such attacks by using tokens and validating them with each request so that we are sure the request is coming from an authenticated user and not a malicious attacker. Suck tokens make it much harder for attackers to guess the proper token required to create a valid request.
4. Open Redirects – This happens when a web page takes a value and then creates a redirect to it. If /gotocart.php?url=https://example.com created a redirect to https://example.com that would be as Open Redirect vulnerability, as anyone can modify the GET parameter url in the HTTP request, and use your website to redirect a user to an attacker’s web page, which can further be used to impersonate a trusted website and phish for user’s data.
Open redirects can be prevented by not allowing any user provided data (like in URLs) to redirect the user to it. We can instead replace links to it with direct links to the relevant target URLs. Additionally, we can use a whitelist of trusted URLs where it is allowed to redirect and make sure our scripts only redirect to only those whitelisted domains and URLs.
5. Broken Authentication and Session Hacking – The easiest way to do something wrong with authentication is to try to implement it yourself, especially in 2020. There are so many things you need to take care like encrypting passwords (both in storage and in transport), leaking session ids, predictable and sequential session ids, no timeouts implementation, or using HTTP. In 2020, we should all be using HTTPS if we are dealing with authentication.
The best way to do authentication in 2020 is to use a framework or library like OAuth 2.0 which takes care of all the pitfalls I mentioned above.
6. Exposing Sensitive (PII) Data – With the advent of GDPR and concerns about user privacy, keeping your users’ personal identifiable information (PII) secure is very important. In my career, I have come in contact with countless organisations (including some very big names) who have stored sensitive data without proper encryption and access controls in place. Sensitive data like credit card information, passwords, mobile numbers should always be encrypted using strong algorithms like AES and RSA.
Another good rule of thumb is to capture and store only data which you need, and to use it only for the purposes you captured it. The European Union’s GDPR is a very good example of what good user privacy protection looks like. If you store and process financial data like credit cards, you might want to be PCI compliant. After doing the right encryption, it is also important to secure your private keys very carefully. Do not keep the keys next to the protected data.
7. Exposing Internal System Details – If you directly refer an internal object like database primary key, table and file names in an URL, it becomes easy for an attacker to access things they should never access to, just by guessing or incrementing the internal system references. We can avoid this by performing user authorisation properly and in all requests, not just on the primary access pages.
8. User Impersonation Attacks – These are attacks where attackers attempt to impersonate a known and trusted individual to gain access to someone else’s financial data. It normally starts with creating an email address with a spelling mistake, but one that resembles very closely the real email of a trusted individual. Attackers can register a domain similar to the individual’s company email and then use that to send emails to potential victims, asking to transfer money or provide access to financial accounts.
Since the email sounds legit to the unsuspecting user, many people fall prey to such attacks. A recent example is the French film group Pathe losing over 22 million dollars in an attack in its Dutch office, where its managing director transferred the amount to a company in Dubai after receiving a fake email from its CEO.
9. Wrong Configuration Leading to Attacks – Modern platform software such as web servers, databases are hugely complex systems with hundreds of configuration options. Often these configurations come with defaults which a lot of people never bother to change, leading to common security vulnerabilities and easy attacks. Lack of updates to such software and using outdated versions can also lead to more attacks.
To avoid such kind of attacks, we can use the services of an expert in the said software so that we can avoid common mistakes like leaving debugging or file directory listing enabled in production, running outdated software, not changing default passwords, and leaving unnecessary error information and stack traces publicly visible.
10. Lack of Logging, Monitoring and Alerting – The sooner an attack is detected, the less damage it will cause. And the best way to detect an attack is to have proper logging, monitoring and alerting in place so that the right amount of information is logged and monitors are set in place to trigger the right alerts in case some metrics are off the expected curve. Care must be taken that alerting is neither too much that people ignore it, or too little that it never get in front of the right people.
Events such as failed login attempts, unexpected hits from a single or similar IP addresses must be logged and relevant people alerted if significant thresholds are crossed. It is also important to have detailed “what to do” documents ready for different type of alerts so that people know how to react to unknown or rare events.