Secure Coding Standards: Enforcing Secure Coding Practices With SAST
By Kevin E. Greene
September 2, 2021
9 min read
Jump to Section
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.
How Secure Coding Works
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).
Getting Started With Static Analysis
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.|
Poor Coding Practices Lead to Security Issues
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.
Issue: SQL Injection
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.
Issue: Broken Authentication and Session Management
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.
Issue: Broken Access Control
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.
Issue: Cross-Site Scripting (XSS)
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.
Best Security Code Practices
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.
To Mitigate SQL Injection
Use Secure Configuration
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.
Use Secure Authentication
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.
Use Secure Communication
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.
To Mitigate Broken Authentication and Session Management
NIST 800-63b defines three levels for authentication surety, a.k.a., AAL, or authentication assurance levels.
Level 1: Passwords
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:
- Employing passwords with no less than 8 characters, if we use MFA (multi-factor authentication); 10 characters if we do not use MFA.
- Use of all printable ASCII characters, in addition to the space character.
- Promoting using long passphrases and passwords.
- Removing complexity requirements (developers have found they’re not very effective).
- Avoiding using common passwords, especially those that have been compromised previously.
- Password recovery that implements MFA elements.
- Secure storage of passwords using cryptographic controls.
Level 2: Multifactor Authentication
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:
- A PIN or password
- A phone or token
- Biometrics, like a fingerprint or facial image
Level 3: Cryptographic-Based Authentication
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.
Session Generation and Expiration
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:
- Making sure the session ID is unique, long, and random.
- Ensuring that the application generates a new session, or at least rotates the session ID during authenticating and re-authenticating.
- Making sure the application implements an idle timeout following a time of inactivity, in addition to setting a maximum lifetime for every session. After this, the user must re-authenticate.
Applications commonly use browser cookies to store web application session identifiers when systems implement session management methods. A few defenses are:
- Only a small number of domains should be able to access the cookies. The application should tag their paths so that the tags expire at the end, or soon after, the session loses its vitality.
- Setting the “secure” tags to make sure the system transfers only on a secure channel.
- Adding “samesite” characteristics to cookies, which stops some current browsers from sending cookies that have cross-site demands. This protects against information-leak-type attacks and cross-site demand forgery.
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.
JSON Web Tokens (JWT)
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.
To Mitigate Unprotected Data
Do the following to avoid unprotected data:
- Classify the information in the application according to the level of sensitivity and map each category of data to the appropriate protection rule.
- Encrypt data that is in transit. For protection of web application data over a network, developers commonly use properly configured TLS (transport layer security).
- Encrypt at-rest data. Avoid storing sensitive information, if possible. If you must store it, however, then be sure to protect it cryptographically.
- Secure local storage in mobile devices. People often steal or lose mobile devices, making the information in them vulnerable to leakage. Owners need to store minimum sensitive data on their devices and store it in the specified data-storage directory.
- Manage secret key lifecycles. Developers use secret keys in applications for confidential functions; for example, for protecting credit cards and for signing JWTs. Manage keys properly by:
- Making sure all secret keys are protected against unauthorized use.
- Using independent keys if multiple keys are needed.
- Storing keys properly in secrets vaults.
- Building applications for changing keys and algorithms when required.
- Building features to accommodate key rotation.
- Manage application secrets. Applications have many “secrets” that the applications need for operating securely, such as passwords, certificates, and encryption keys. If someone were to compromise these secrets, it can lead to a complete system failure. To manage application secrets:
- Do not pass them thru environment variables or store them in config files or code.
- Keep them securely in secrets vaults.
To Mitigate Broken Access Control
Developers can consider the following access-control measures during the design stage:
- Include access control from the start. Also, allow for customization.
- Compel all requests to pass access-control checks.
- Deny by default. If the program does not specifically allow the request, deny it.
- Implement the “principle of least privilege.” Make sure all programs, processes, and users get as little access as possible.
- Do not hardcode roles. Too many programs default to role-based access control, which is fragile and doesn’t allow multi-tenancy and horizontal and data-specific access-control rules. It is also difficult to audit.
- Log every access-control failure. These may point to exploiters searching the application for weaknesses.
Mitigating Cross-Site Scripting (XSS)
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.
How Static Application Security Testing (SAST) Helps Developers with Improving Their Coding Practices
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.