Software developers and information security professionals have almost always been two mutually exclusive groups. However, with the increase in security awareness, developers have started integrating security into the development process. To further bridge the gap between development and security, it is essential for developers to have a good understanding of security principles. In this post, we’ll talk about the basic security concepts that every developer should be aware of while building applications.
An application obtains data from various trusted and untrusted sources during its workflow. It is important to perform input validation of data obtained from all sources to ensure that only properly formed data gains entry into the application workflow. If not properly validated, malformed input can lead to attacks such as SQL injection and cross-site scripting (XSS). Always conduct input validation on the server—even if client-side validation is also present.
It’s important to validate data both syntactically and semantically. Syntactic validation ensures that the input data has the correct elements such as structure, data type, and length. On the other hand, semantic validation ensures the correctness of data per business logic (e.g., checking for negative price).
The two primary approaches for performing input validation are blacklisting and whitelisting. Blacklisting involves detecting dangerous characters and patterns in the input (e.g., an apostrophe character or the <script> tag) and filtering them out. Since blacklisting does not account for all attack vectors, it is relatively easy to bypass these checks and controls. Also, the exclude list needs to be updated every time a new attack vector is discovered. This isn’t very manageable. As such, they should not be used for validating data.
Whitelisting involves defining a set of approved characters and patterns. It also involves implementing controls for validating that the input contains characters and patterns only from the defined set. If the input contains any other characters, that input is discarded. This is a stronger approach for input validation and is generally performed using regular expressions.
Just as input is validated before utilization in the application workflow, output should be properly encoded before sending it to the target interpreter. Encoding involves converting special characters executed by the target interpreter into an equivalent telling the interpreter to use it in a harmless way. For example, consider a web application in which the target interpreter is a web browser. When the server sends a response back to the browser, the output sent in response should be HTML encoded. Thus, stopping the browser from executing script tags, and preventing potential XSS attacks.
Applications need to access the database at some point in the application workflow to retrieve or store information. Developers should ensure that they are accessing the database in a secure way to prevent SQL injection attacks. The best way is to use parameterized queries since they, unlike dynamic SQL queries, can help the database distinguish between application code and data.
Another way to defend from SQL injection attacks is to make use of stored procedures, which are essentially SQL statements defined and stored in the database. However, developers should take care not to include unsafe dynamic SQL queries inside the stored procedure.
Lastly, the principle of least privilege should be adopted and only the minimum required permissions should be assigned to the database. For example, if a user account needs to read data from some tables in the database, it should be given read-only access only to required tables and should be prevented from accessing anything else.
A basic knowledge of cryptography is essential for all developers. Before implementing crypto in applications, it’s critical to understand how to do so securely. Some common cryptography related best practices include:
Make sure that the error handling in the application is implemented properly. Improper error handling may lead to two issues:
An application is as secure as its weakest link, as they say. Many developers use third-party libraries in their code. They must ensure that these libraries do not have any security vulnerabilities. Some points that developers should keep in mind before using third-party libraries include:
Defense in depth is a security principle that suggests adding multiple layers of security to increase the overall security of an application. In case an attacker manages to compromise one security layer, they would need to get through other layers of security before achieving their attack goal. An example of defense in depth for a web application is implementing client-side input validation, layered server-side input validation, and output encoding to protect the application from XSS.
While this is by no means an exhaustive list, these basic security fundamentals are a good starting point to help software developers begin building securing into their applications.