The principle of secure software development
Prevent injections as well as vulnerabilities
Injection vulnerabilities occur when user input is sent to the interpreter without sufficient validation to create statements or queries. By manipulating the input syntax, an attacker executes unwanted commands and gains unauthorized access to sensitive data. For example, SQL injection in a web application allows database access in the backend.
XSS (Cross-Site Scripting) vulnerabilities occur when web applications use user input unchecked to generate output. For example, suppose the information in a search field is output in the results page without being checked. In that case, the attacker can use this method to insert malicious code into the website. Often, malicious code is loaded via well-prepared URLs and executed automatically.
In a cross-site request forgery attack, an attacker makes HTTP requests through the user’s browser. The requests are executed in the user’s context and with their rights. They are indistinguishable from legitimate access by the application.
Modern programming languages and frameworks provide routines for checking input. These routines are usually well tested and reduce the risk significantly. In opposite, self-created routines often miss details and should therefore be avoided.
Scaffolding refers to the generation of methods for creating, reading, updating, or deleting data. In this way, Frameworks for generating CRUD implementations or form content based on a data model contribute to security. Here, a large community supports the implementation and is often more mature compared to proprietary solutions.
If interactions with databases only allow defined operations, this avoids lasting system damage. The application code does not have to contain functions for creating or deleting tables or dropping databases. The possibility to run the application without these rights reduces the possible attack surface.
Separation of data processing and data presentation
An important aspect of processing data (creating, reading, updating, and deleting) is separating presentation logic (e.g., in the web browser) and internal processing logic. This separation is done, for example, when using the Model-View-Controller (MVC) pattern. The separation of data models (model), presentation layers (views), and program control (controller) increase the reusability of elements.
The separation of application logic and data representation reduces the risk of inadvertently placing security-relevant checks in the presentation layer. An attacker can easily bypass security checks in the presentation layer. They are not an obstacle.
Use scaffolding to implement MVC program code.
Development frameworks often support the generation of program code for data models, data representation, and controllers. This code generation is called scaffolding. Generating source code for CRUD operations saves time and creates uniform security mechanisms. Applications benefit from security adjustments and optimizations in the framework. Often, better software quality is achieved by updating the framework and regenerating source code.
Always validate data before processing.
The consistent validation of input and output data is a fundamental principle of software development. It is the basis of stable, robust, and secure program code. Incorrect and incomplete syntax verification or semantics often leads to security vulnerabilities, such as injection attacks. These vulnerabilities compromise the integrity, confidentiality, and availability of user data. Often, attackers gain access to the data in this way and to the hosting servers.
Regardless of vulnerabilities, insufficient validation can lead to inferior data quality. A few examples of quality impacts are incomplete form data, negative personal age, or invalid email addresses. They lead to consequential errors in the processing chain.
Protect data between the web browser and application from external viewing
Protect the communication between the web browser and the server to avoid viewing by third parties. Appropriate encryption using HTTPS and current cryptography is essential. Public WLANs or guest WLANs do not use strong cryptography, so transport encryption alone is no longer sufficient.
If an attacker succeeds in viewing the communication, he may be able to obtain sensitive information. Spying on user names and passwords enables unauthorized access and results in further damage.
Secure applications, therefore, use TLS 1.2 or TLS 1.3 to protect sensitive data. End-to-end encryption also protects against man-in-the-middle attacks.
Keeping an eye on the users of the application
Errors in session management often lead to security vulnerabilities. Authentication errors, insufficient password reset checks, or attackers can exploit incomplete user authorization checks.
Check the authorization for every user action. Under no circumstances may a user be granted access to a function for which they are not explicitly authorized. Sessions must be limited in time. Limited session time reduces the damage caused by a hijacked session. Using single sign-on reduces the frequency of password entry. Accordingly, this reduces the risk of spying.
Adhere to the principles of safe software development. Then you are well on your way to developing secure software. Security is relative, and perfectly secure software is a utopia. Make life difficult for attackers. Chances are they will look for easier targets and let you go. Easy targets motivate the attacker. They give them a sense of achievement. We want to avoid that as much as possible.