When development teams use secure coding standards to develop software, the result is fewer security bugs and ultimately better quality that leads to a more robust experience for developers and users alike. In this blog, we go over the basics of secure coding standards, best practices, and how and when to use them.
Secure coding means that developers apply a set of coding standards or secure coding guidelines that they implement in source code to prevent and mitigate common vulnerabilities which often lead to cyberattacks. Implementing secure coding practices in code is the first line of defense that protects against bad actors exploiting software, and which eliminates attack surfaces that adversaries often target with malware. When organizations adhere to secure coding best practices religiously, they can reduce the cost of maintaining software and developers can spend more time innovating, as opposed to spending time on bug fixes.
Secure coding practices ensure that security controls are implemented in code to reduce security issues that may manifest as a result of poorly developed code. It is imperative that organizations formalize secure coding practices to establish a minimum set of software security standards for how developers should write code, which the organization can enforce and validate with automated static analysis or static application security testing (SAST) tools. These tools use rules and checkers that analyze source code for syntax violations, undefined variables, code quality, encoding and security violations, and programming errors (to name a few).
Parasoft static analysis tools employ secure coding standards like CERT coding standards, OWASP Top 10 (part of the OWASP Secure Coding Guidelines), MITRE Common Weakness Enumeration (CWE), and DISA Application Security and Development STIGS in rules and checkers as shown in Table 1.
|Coding Standard Name||Maintained By||Purpose Summary|
|CERT (Computer Emergency Response Team)||CERT Coordination Center||Guidelines to help developers avoid errors during coding and implementation, and also detect low level errors in design.|
|OWASP Top Ten||OWASP (Open Web Application Security Project) Foundation||Web application and software developers use these standards to identify and remedy high- security risks in web applications.|
|CWE (Common Weakness Enumeration)||Community developed and maintained.||This is a category system that helps developers identify vulnerabilities and weaknesses in software, and assists them in understanding software flaws. Developers also use the system to develop tools to fix and prevent flaws.|
|DISA Application Security and Development STIGS||Defense Information Systems Agency (DISA), and division of the United States Department of Defense.||Helps managers, designers, developers, and system administrators in developing and maintaining security controls in applications and application development.|
Developers need to be aware of the consequences of their coding and refactoring activities in creating and exposing vulnerabilities in software. The following are some common things that could go wrong when developers do not follow and use secure coding practices. We follow up with best practices for mitigating and remediating these security issues.
This happens when an attacker insecurely injects input to an SQL query, many times through a basic string chain. SQL injection is a highly dangerous security risk for applications because it is relatively easy to misuse and can lead to the exploiter modifying, wiping clean, or stealing the whole database. The attackers can also use the application to run dangerous commands on the operating system that hosts the database, which gives him entrance to your network.
Developers often incorrectly implement application tasks associated with session management and authentication. This allows attackers to compromise keys, passwords, and session tokens and to allow the bad actors to use user identities to their advantage.
Systems often do not correctly enforce what authenticated users are permitted to do. Bad actors can use such flaws to gain access to functionality and data, for example, to user accounts and files, to modify data, or to change access permissions.
This occurs whenever the application allows suspect data onto a new webpage without proper authentication. XSS enables hackers to implement scripts in the target’s browser. The scripts can vandalize websites or send users to malicious ones and commandeer user sessions.
The rise in cyber attacks attributed to poorly developed software make it essential that developers adhere to secure coding practices. When they do, it improves productivity and helps accelerate software delivery because there are fewer security issues to address. This increases the likelihood that the build will be passed. When a build is passed, it signifies that all critical and high severities have been resolved, and there is no significant risk posed to the organization. For an example, an organization could define thresholds (in terms of severity) and/or identify specific issues that are non-negotiable, and if identified will break the build until issues are resolved.
One way to ensure that a build will be pass is to enforce secure coding practices and compliance validation with static analysis as part of automated testing. The following are good security practices that developers can follow as part of secure coding.
Often database management systems do not include a secure-by-default component. Developers need to ensure that security controls in the hosting platform and the Database Management System (DBMS) are working and configured correctly. Guides, standards, and benchmarks exist for most popular DBMSs. The Database Cheat Sheet provides quick guidance for developing a secure configuration.
Properly authenticate all access to a database. Use a secure method to authenticate the DBMS. Only authenticate over a secure channel, and secure credentials properly before making them available. Refer to the Database Cheat Sheet for more information.
Almost all DBMSs support a range of methods to communicate, like APIs, services, etc., both insecure (unencrypted or unauthenticated) and secure (encrypted or authenticated). It is wise for developers to use only the secure communication choices available with Protect Data Everywhere (see below). The Database Cheat Sheet gives quick assistance in providing secure communication.
NIST 800-63b defines three levels for authentication surety, a.k.a., AAL, or authentication assurance levels.
Level 1 is for low-risk apps that contain no PII (personal identifiable information). It requires only a single-factor ID, usually a password.
Best practices include:
This level is for more at-risk apps that contain PII, which users have supplied online. AAL level 2 requires MFA, including QTP (quick test professional) implementation. MFA certifies that a user is who she claims to be and requires that the person identifies herself with two or more of these combinations:
When a comprised system can lead to substantial financial loss, personal harm, criminal or civil violations, or considerable harm to the public interest, level 3 authentication is needed. Developers usually use cryptographic modules to achieve this strong level of assurance.
An application can track authentication for a limited time period. This allows the user to keep using the application without the need to re-authenticate with every request. Tracking this is known as session management.
The system tracks the user state during a session. The server stores the session and attaches a session identifier to the user so the user info can identify the session that has the correct data for the user. The client simply maintains the identifier, which also shields confidential server-side session information from the client.
Security controls to consider when implementing or building session management systems include:
Applications commonly use browser cookies to store web application session identifiers when systems implement session management methods. A few defenses are:
For some types of authentication, server-side sessions may be restricting. “Stateless services” allow the system to manage session data to improve performance. The result is that the burden of verifying and storing users sessions on the server is less. A “stateless” application creates a temporary access token, which the system uses to authenticate a client’s request minus the user’s credentials following initial authentication.
The server does not always save the JWT. The system maintains the token’s integrity with a digital signature so a later server can confirm that the JWT remains valid and that no one has corrupted it since the system created the token.
This method is portable and stateless, meaning that the server and client technologies can be different but nonetheless they can interact.
Do the following to avoid unprotected data:
Developers can consider the following access-control measures during the design stage:
Escaping and encoding are defense methods that help stop injection hacks. Escaping means that the coder adds a specific character before the string to stop it from being misinterpreted. For example, you can add a backslash ( \ ) before a double quotation mark ( “ ) so the system interprets it as text instead of as a signal to close a string. Encoding, also called output encoding, means the developer changes special characters to a different but equal form, making them not dangerous in the interpreter. For instance, changing < to the < string when you write in HTML.
Other methods of injection protection include contextual output coding, which coding developers implement when they build a user interface; neutralizing specific metacharacters when you add input to a command of an operating system; Unicode Encoding, a method of storing characters using multiple bytes; and canonization, which is when systems transform data into a standard or simple form.
Software developers use SAST (static application security testing) to execute automated tests to analyze source code without executing or running the code. The goal is to identify coding violations and weaknesses that could expose software vulnerabilities. SAST is considered a “white box” testing approach because it has access to source code that documents the design, the framework, and how the system and/or application is implemented.
SAST uses the details documented in the source code, along with its code structure to ensure adherence to secure coding standards and guidelines. SAST uses rules and checkers to enforce and validate compliance, as well as to pinpoint coding violations in developers’ coding practices. Development teams can use different secure coding standards and guidelines like CERT Secure Coding standards and CWE at the onset of the development process to ensure the software meets certain quality and security requirements.
It should be noted that high-performing and mature software development organizations use these standards and practices to tailor security policies and governance for development teams. Many organizations add supplemental guidance that they can use for developer training and awareness. OWASP Top 10 and the Seven Pernicious Kingdoms play a key role in increasing the awareness of things that could go wrong in coding practices.
Because SAST does not require the software to run in order to perform an analysis, developers can implement it seamlessly in their existing development workflows to analyze code in real time, immediately flagging any coding violations that coding rules and checkers trigger. The result is finding critical quality and security issues within the developer’s workflow where the cost to fix and remediate security issues is the cheapest. This results in higher quality software with fewer security issues or vulnerabilities, enabling organizations to gain confidence in accelerating software deployment and delivery.
While integrating SAST in developers’ workflows helps developers triage their coding violations, SAST can also seamlessly integrate into an automated pipeline to analyze code commits before the software is released into production. Each commit can automatically trigger a scan from a SAST tool.
Parasoft SAST tools leverage AI/ML for incremental scanning, which only analyzes code that changed as part of that commit. This enables more efficient use of SAST and provides development organizations a historical view of scans. SAST integration in the CI/CD process is an essential part of creating quality, reliable, secure code during integration and before final delivery. It satisfies the concept of continuous software assurance, where software assurance practices are automated into development activities to ensure software deployment and delivery at speed.
Kevin, Director of Security Solutions at Parasoft, has extensive experience and expertise in software security, cyber research and development, and DevOps. He leverages his knowledge to create meaningful solutions and technologies to improve software security practices.