In the first part of this series, we have been taking a look at several types of languages and the resulting security implications.
This time, we focus on the baseline for secure development. We will cover the most basic principles that apply independently of the creation of a more specific application.
Secure software is the result of a security-aware software development process.
Applications will fail at some point in time, no matter how cutting-edge and security-aware programmers, project managers, and product designers are.
A sense of how to handle failures is essential to stay in control of unpredictable situations for an application or system.
There are two general practices when planning for failure:
The fail-open state allows a system to continue operations when failure conditions occur. This approach should only be taken in limited circumstances. It might be appropriate on the lower-layers of multilayered security concepts. A good example is an electronic locking door that unlocks in case of failure to ensure the exit in the event of a natural disaster.
The fail-closed state puts a system into a high level of security or even shuts down a failing system. This strategy should be the default where there are security concerns. An example is when a forgotten password results in the denied entry to an account and multiple wrong password entries result in the lock of the account.
Authentication and Session Management
Many applications require that users authenticate before accessing sensitive information or modify the data in an application. One of the most basic security tasks developers are facing is to ensure that those users are properly authenticated, that they perform only authorized activities, and that their sessions are securely tracked.
It is generally more secure to use an existing and hardened authentication system than to try to develop a system for a specific application.
Similarly, programmers should be encouraged to use established methods for session management. This includes the usage of encrypted channels and that identifiers used in sessions are long and randomly generated. Session tokens have to expire after a specific time and require reauthentication.
Many applications receive data from potentially untrusted sources. This includes user input on internet-facing web applications or API communication with suppliers, partners, or other applications in the backend.
Developers often expect these values to fall within certain parameters. For example, if the programmer asks the user to enter a telephone number, the program may expect to see a chain of integer values. If the user enters a value outside the range or character set, a poorly written program may crash or even allow the user to gain control of the underlying system.
Input validation verifies that the values match the programmer’s expectation before allowing further processing.
Input escaping describes a check for unusual characters, such as quotation marks within a text field, which may indicate an attack. Escaping can be performed with a blacklisting or better whitelisting approach.
All input validation efforts should be performed on the server-side of a transaction and as early as possible in the processing of a request.
Detailed error messages with in-depth information are crucial to debugging code and make it easier for developers to diagnose a problem.
However, those errors are exposing potentially sensitive information to attackers, including the address of internal servers, database schemas, and other data that may be useful in preparing an attack.
Therefore, developers have to disable detailed error messages on any publicly available application.
While user-facing error messages may present a security threat, the information that those messages contain is quite useful. Not only to developers but also to security analysts.
Therefore, applications should be sending detailed logging messages to a centralized log repository.
The OWASP Secure Coding Guidelines suggest logging the following events.
Input validation failures
Authentication events, especially failures
Access control failures
Apparent tampering events
Attempts to connect with invalid or expired session tokens
Exceptions by systems and applications
Use of administrative privileges
TLS connections failures
The above topics are the most basic principles to guide stakeholders in creating secure software.
In the next article, we’ll take a look at several specific activities of a development process and how security can be applied in each of these.