What Application Developers Should Know About Secure Coding and Proactive Security? OWASP Top 10 Proactive Controls - Part 1
How to effectively teach your developers about Secure Coding? Find more about it below.
If you work in Application Security you’ve probably already heard about OWASP and the OWASP Top 10, which lists the Top 10 most critical vulnerabilities in web applications. Its latest version was released in 2017 after some changes and reviews from the community. But when it comes to teaching the developers about the basic principles on how to write secure code, there is another OWASP project that is the best option: the OWASP Top 10 Proactive Controls.
This project was created in 2014, and its latest version is from 2016, by well-known application security professionals from OWASP that have a very deep knowledge about secure coding. Here’s a brief introduction about why this project was created:
“Software developers are the foundation of any application. In order to achieve secure software, developers must be supported and helped by the organization they author code for. As software developers author the code that makes up a web application, they need to embrace and practice a wide variety of secure coding techniques. All tiers of a web application, the user interface, the business logic, the controller, the database code and more – all need to be developed with security in mind. This can be a very difficult task and developers are often set up for failure. Most developers did not learn about secure coding or crypto in school.” - OWASP Proactive Controls
As the OWASP Top 10, the Proactive Controls is ordered by importance, meaning that the first control is more important than the second and so on according to the project leaders. Let’s meet those controls:
- Verify for Security Early and Often
- Parameterize Queries
- Encode Data
- Validate All Inputs
- Implement Identity and Authentication Controls
- Implement Appropriate Access Controls
- Protect Data
- Implement Logging and Intrusion Detection
- Leverage Security Frameworks and Libraries
- Error and Exception Handling
Each of them have a set of information related to them such as their description, which vulnerabilities they aim to prevent, some references on why or how to apply them and the tools that you can use to do so. Now we’ll discuss the first five of these controls in details and how to apply them in any project you need.
C1 - Verify for Security Early and Often
This very first control, and the most important one, tells us a lot about what I mentioned before in my last article about DevSecOps and how to integrate security in the development process. According to this control, in many organizations, security is still treated as a plugin, something that can be added later after the software is ready. We all know that this process doesn’t work anymore because it is very slow and expensive, causing project delays and cost increases. Security testing must be done inside the development lifecycle and should be executed during the pipeline, otherwise the problems found are rarely fixed unless they are critical and impeditive for the project to move forward.
It is very common for pentesters and application security professionals to test systems and applications and after six months or one year when they go to test the same systems again, practically all the vulnerabilities found before are still there. That usually happens because when those tests are performed, they are done independently and outside of the project scope, so to fix those issues you will usually need to create a new project, allocate people, time and money, and schedule changes to perform those fixes, and that takes time, especially on big companies where you have to deal with a lot of people from different areas.
So, the main goal of this control is to establish the security requisites of your software as early as possible and create ways to verify if those requisites are being met during the project, and if not, report them so that they can get fixed as soon as possible, at least in the next sprint (if use agile). Techniques like TDD, CI/CD and Continuous Testing can help you achieve this control in a more efficient manner.
C2 - Parameterize Queries
Although it is more than 20 years old, SQL Injection is still one of the biggest issues on web applications. Since they affect the heart of the web application which is the database, they are very dangerous, being the root cause in many attacks. Also they are easily exploited since nowadays there are many free tools available, so most of the times they don’t require an advance expertise from the attacker.
The biggest problem is when parameters are mistaken from commands in a SQL Query, then the user has control of what to execute in the database being able to retrieve, alter or delete data. So, to avoid that a technique called Query Parameterization was created to separate the SQL Commands from the Input Parameters, avoiding one to affect the other.
Let’s check a basic example of a vulnerable code with SQL Injection and one that is fixed with Parameterize Queries:
• Vulnerable Code:
String query = "SELECT * FROM users WHERE userID=' " + request.getParameter("id") + " ' ";
• Fixed code:
int id = Integer.parseInt(request.getParameter("id"));
PreparedStatement pstmt = con.prepareStatement("SELECT * FROM users WHERE userID = ?");
Noticed the difference? That simple technique along Prepared Statements can avoid SQL Injection vulnerabilities on your code. So how do we keep finding this issue over and over on web applications until today?
Exploits of a Mom from XKCD
C3 - Encode Data
Data encoding is another great technique to avoid other kinds of injection attacks such as XML and LDAP injection, and also XSS with output encoding. This approach avoids some special characters to be considered dangerous to the interpreter. Reducing the risk of inputs acting as part of the code or the web page, very similar to SQL Injection that we mentioned before.
There are many types of encoding and it all depends on for what reason you are trying to encode the data. Some examples are: Command encoding, LDAP encoding, XML encoding, and HTML encoding. Also some programming languages and frameworks already have their encoders in place, all you have to do is to activate it or import their library to use them.
C4 - Validate All Inputs
Always consider any inputs on your application to be untrusted! And make sure you verify those before using it anywhere on your software. Even if they come from another application that you know or trust. They could be vulnerable and affect your application as well. Make sure your developers check the data with syntactic and semantic validations.
Syntax means that the data is the correct format, and semantic means that the data has some meaning to the application. Also make sure to perform those validations on the server side, since client side validations are easily bypassed. Another thing to consider is to always perform whitelisting instead of blacklisting, that is, only allow or accept that input that is considered valid, anything else is invalid. You can use regular expressions to help you with that and have a more accurate validation process.
C5 - Implement Identity and Authentication Controls
People often mistake identification with authentication and sometimes also with authorization. Let’s try to clear that out first. Identification is process of identifying someone, for example with an username. And authentication is process of proving that this user is who he says he really is, by providing his password and making sure it matches the one in the database. That is why identity and authentication controls are very important for applications.
This control goes beyond that and also provides information regarding session and identity management as well as two-factor authentication. Aside from some people in the security industry, most of the regular users tend to use very weak passwords for their applications, and sometimes even using the same password on multiple locations. Because of that and the many database leaks that happened over the years, people decided to create a mechanism called two-factor authentication (2FA), sometimes also known as multiple factor authentication (MFA). That is, after you provide your username and password to login to an application you will also have to provide what we call as one-time password (OTP) or token, that changes over time. These are usually obtained using specific apps on your phone such as Google Authenticator.
Many websites and applications use this mechanism already, but unfortunately only a few people know it and use it. Services like Google, Facebook, Twitter, Linkedin and many others already support 2FA. There are also websites that list all the applications that support this strong authentication mechanism such as Two Factor Auth (2FA).
In the next article we’ll talk about the other five Proactive Controls from OWASP. Make sure your developers read and understand these controls before next week. And don't forget to check out our free application Discovery service and make sure you start proactively protecting your apps!