To Build Your Code Quality (Chapter A): Secure Coding (Part 1)
From the roots of issues
Code quality’s always a matter of software engineering. It’s hard to measure the level of code quality and even to define it. As a result of searching on the Internet, it is a group of attributes and requirements determined and prioritized by your business. These include clarity, maintainable, documented, refactored, well-tested, extendible, efficiency. Some organizations have different methods to measure and track your code quality and expose them to their clients as a part of the evidence for their reliable engineering. In this era of cloud-based and IoT, a factor cannot be ignored is secure coding to build your own secured products and protect your users from threats.
Developing software in a way that guards against the accidental introduction of security vulnerabilities is a critical part of building your code quality. Nowadays, we are facing many repetitive security issues which are coded into a group of common issues as follows:
About Web Application Development Issue Group
- Input Validation Issues
- Man-In-Middle Issues
- Session Management Issues
- Error Handling Issues
- Logging & Output Issues
- Configuration Issues
- Database Issues
- I/O & File Management Issues
- Memory Management Issues
About Security Development Awareness Issue Group
- Authentication & Password Management Issues
- Authorization & Access Control Issues
- Cryptography Issues
To Building Secure Code
Let’s go through every item in this list.
Input Validation Issues: As the beginning, let’s explore what the attack vectors at play. There are many techniques used to inject into the web application from poor input validations. One of the most common exploits is the SQL injection attack. SQL Injection Attack to provide inputs that not only completes the intended statement but also executes a new statement (for attacker’s intention) by simply adding a semicolon. You can link to [Video] OWASP Top 10 series (Part 1): SQL Injection exploitation- step by step for more info.
Another form of Input Validation Attack is to use Scripting Attack based on lack of proper input validation. The most common of scripting attack is Cross-Site-Scripting (XSS). The concept is rather simple. The attacker injects a script through a user input field or some other post/put method. That script is then served to a victim through his or her browser. The script is then rendered in the client browser of the victim and the exploit is executed. Often these scripts send data of some kind back to the attacker’s server. The way has been described usually known as persistent XSS. And there are a couple of other forms as Reflected cross-site scripting is often used in phishing attacks, where the malicious script actually originates in the request. More details can be found at [Video] XSS – Cross Site Scripting – More dangerous than you think!
Although these attacks are taken in many different forms, the fixes are relatively straightforward. Following are some approaches to these fixes:
- Use Blacklisting: The approach to provide a list of “bad” things. It looks for key patterns like “Script” keyword in inputs and filters it out. The list can be a set of URLs, IP addresses, keywords, or even users to prevent those resources from accessing our application. However, blacklisting is easy to circumvent, it must be combined with other techniques in building your secured code.
- Use Whitelisting: The reverse of Blacklisting is true for Whitelisting. Whitelisting looks at the pattern that the data should have, such as length or symbols, and requires that the data matches that pattern before it’s ever accepted. One of most common example for whitelisting is to require an email must contain @ and the dot.
One of the things to keep in mind is these validations should be implemented at the server side and the things to be executed at first.
Man-In-Middle Issues: The way of TCP/IP working exposes threats in its communication channel. If an attacker can gain access to the network of either the client or the server, he/she is totally able to steal the transmitted data over the channel. The brutal fact is that many organizations supply free wifi without authentication and encryption, while users usually “trust” and connect their devices to public wifi and making the ability to spoof these SSIDs an attack vector. Therefore, you need to proactively protect users from these kinds of attacks.
Using TLS and redirect all traffic from HTTP to HTTPS is good practices in building your web application with secure communication between server and client. It’s important for you to make sure that the certification used must be: valid & trust (signed by s trusted certificate authority) and not expired. At the client’s side, your code should validate the certificate. This includes not only checking that it is a valid certificate but that it has not expired or been revoked. Each language and framework have tools around not only making TLS connections but doing the validation. Often developers skip that validation part.
Session Management Issues: Session used between client & server always a subject to be hijacked. Session hijacking works by using the session’s tokens which are often created using random numbers. When the generators are not good to create random numbers, attackers can simply predict the value of the session identifier for a user. Once they can predict the pattern through an algorithm, they can generate a seed session and use it to grab the next user’s session. If you are to create tokens for sessions, you must use a secure generator. Most languages have a general random or pseudo-random number generator and a secure one. Always use the secure generator. If you don’t mark the session token cookie to be secure, it can be passed over HTTP instead of HTTPS. Always create a new session when the user logs in, reusing the session in the first visit is always a threat to be hijacked.
When a pre-authentication session token would now point to an authenticated session, if anyone can grab the session on HTTP prior to login, once login occurs, session token can be used.
Session timeout is another subject to be considered when building your web application to do with situations when the user leaves the browser, but no longer using the web application. Moreover, rarely, the user actually logs out their site being used, instead, they just close the browser, so the session still remains active and can be stolen. We should invalidate the session when the browser closes to ensure the session cannot be stolen.
Finally, you must make sure that when the user logs out the session is invalidated. If not, the session token can still be stolen and used by a bad actor even if the user is no longer interacting with the system
Error Handling Issues: Error handling is a good mechanism that helps developer prevent abnormal termination. It’s a powerful tool, but also be an attractive place for attackers. The most common vulnerability comes from error handling is to use the information provided by itself. In these vulnerabilities, the application raises an error that produces an error status such as an error discloses the info as a database dump or a specific file not found,… The info is valuable for an attacker to figure out how to gain access to the system or prepare for an attack. A common issue we have frequently seen in applications is that every time when typing in user authentication, developers expose messages such as the user doesn’t exist versus the wrong password was entered. This level of disclosure can provide attackers a brute force vector into your system
The best way to prevent these vulnerabilities is only disclosed that the situation exists, not which case we’re in. Using consistent language so a user can take his appropriate action while attackers won’t be given too much info. Good practices here are:
- Document your messages and review the textual display and make sure that errors don’t disclose internal system information
- Don’t expose info about users to attackers
Building good practices about what text should be displayed and what shouldn’t be is a good exercise to ensure your messages are consistent, valuable, and don’t disclose sensitive information.
Logging and Output Issues
Similarly, sometimes we can see developers to provide too much information in their logs and system outputs. Two common vulnerability roots can be identified with logging and System Outputs. One is to expose too much information about our internal system behaviors, and another is about user info. When writing logs, we need to provide a certain level of details about what’s actually happening. So it is critical for operations in nature or for security purposes. However, when our logs become too much information, it’s a subject to be attacked. The things such as events (session events for authentications, system completions) or errors are necessary to get them logged. But there are several other things should never be objects in our logs:
- Connection Strings
- Tokens for Sessions
- Key & passwords
- Personal info like email address should not be logged in plain-text, instead, it is useful to keep in our logs, let’s hash it. We can use it for troubleshooting, not to reverse.
Application output should be considered to validate user’s inputs to ensure that we are not creating a risk to other systems that may be downstream. Data should be filtered and sanitized so that the user sees what they need to but not so much that an attacker could use it as an exploit.
Finally, keep our logs protected by Access Control Lists (ACLs)