Code is the core of a computer program. If there are any vulnerabilities in it, then the whole program may be compromised by cyber attacks.Secure coding is the practice in which any software is developed in a way that protects accidental security vulnerabilities. It governs the coding techniques, practices, and decisions that developers make during the development. Secure coding’s core aim is to ensure that the written code can minimize any vulnerabilities. It involves writing code in a high-level language that adheres to strict principles of security.Secure coding is much more than just writing, compiling, running, and releasing code into the production environment. To completely embrace secure coding, you must also create a secure development environment that is built on secure and reliable infrastructure using secured software, services, and providers. Besides, the code must not have any logic flaws, bugs, errors, and defects that can form security risks. Poor coding practices such as improper input validation and weak key generation can expose information systems to security vulnerabilities and result in cyber attacks and compromise of sensitive information assets. Organisations should ensure that secure coding principles are followed so that poor coding practices do not lead to security vulnerabilities.When it comes to application security, even the silliest mistake can create security risks.The goal of software security is to maintain the integrity, confidentiality, and availability of information resources to establish successful business operations that can only be achieved by integrating security practices.Flaws in security can happen at any stage of the development life cycle, like:
- Failure to identify requirements of security upfront.
- Errors in conceptual designs.
- Technical vulnerabilities are introduced due to poor coding practices.
- Implementing the software improperly or introducing errors during maintenance or updates
However, secure coding techniques make it easier for developers to remove common vulnerabilities by following security standards for coding. It also helps in weeding out exploited risks, preventing cyber attacks and leaks of sensitive information.
Secure coding principles should be applied to software development.
To ensure software is written securely thereby reducing the number of potential information security vulnerabilities in the software.
ISO 27002 Implementation Guidance
The organization should establish organization-wide processes to provide good governance for secure coding. A minimum secure baseline should be established and applied. Additionally, such processes and governance should be extended to cover software components from third parties and open source software. The organization should monitor real world threats and up-to-date advice and information on software vulnerabilities to guide the organization’s secure coding principles through continual improvement and learning. This can help with ensuring effective secure coding practices are implemented to combat the fast-changing threat landscape.
Planning and before coding
Secure coding principles should be used both for new developments and in reuse scenarios. These principles should be applied to development activities both within the organization and for products and services supplied by the organization to others. Planning and prerequisites before coding should include:
- organization-specific expectations and approved principles for secure coding to be used for both in-house and outsourced code developments;
- common and historical coding practices and defects that lead to information security vulnerabilities;
- configuring development tools, such as integrated development environments (IDE), to help enforce the creation of secure code;
- following guidance issued by the providers of development tools and execution environments as applicable;
- maintenance and use of updated development tools (e.g. compilers);
- qualification of developers in writing secure code;
- secure design and architecture, including threat modelling;
- secure coding standards and where relevant mandating their use;
- use of controlled environments for development.
Considerations during coding should include:
- secure coding practices specific to the programming languages and techniques being used;
- using secure programming techniques, such as pair programming, refactoring, peer review, security iterations and test-driven development;
- using structured programming techniques;
- documenting code and removing programming defects, which can allow information security vulnerabilities to be exploited;
- prohibiting the use of insecure design techniques (e.g. the use of hard-coded passwords, unapproved code samples and unauthenticated web services).
Testing should be conducted during and after development . Static application security testing (SAST) processes can identify security vulnerabilities in software. Before software is made operational, the following should be evaluated:
- attack surface and the principle of least privilege;
- conducting an analysis of the most common programming errors and documenting that these have been mitigated.
Review and maintenance
After code has been made operational:
- updates should be securely packaged and deployed;
- reported information security vulnerabilities should be handled ;
- errors and suspected attacks should be logged and logs regularly reviewed to make adjustments to the code as necessary;
- source code should be protected against unauthorized access and tampering (e.g. by using configuration management tools, which typically provide features such as access control and version control).
If using external tools and libraries, the organization should consider:
- ensuring that external libraries are managed (e.g. by maintaining an inventory of libraries used and their versions) and regularly updated with release cycles;
- selection, authorization and reuse of well-vetted components, particularly authentication and cryptographic components;
- the licence, security and history of external components;
- ensuring that software is maintainable, tracked and originates from proven, reputable sources;
- sufficiently long-term availability of development resources and artifacts.
Where a software package needs to be modified the following points should be considered:
- the risk of built-in controls and integrity processes being compromised;
- whether to obtain the consent of the vendor;
- the possibility of obtaining the required changes from the vendor as standard program updates;
- the impact if the organization becomes responsible for the future maintenance of the software as a result of changes;
- compatibility with other software in use.
A guiding principle is to ensure security-relevant code is invoked when necessary and is tamper- resistant. Programs installed from compiled binary code also have these properties but only for data held within the application. For interpreted languages, the concept only works when the code is executed on a server that is otherwise inaccessible by the users and processes that use it, and that its data is held in a similarly protected database. For example, the interpreted code can be run on a cloud service where access to the code itself requires administrator privileges. Such administrator access should be protected by security mechanisms such as just-in-time administration principles and strong authentication. If the application owner can access scripts by direct remote access to the server, so in principle can an attacker. Web servers should be configured to prevent directory browsing in such cases. Application code is best designed on the assumption that it is always subject to attack, through error or malicious action. In addition, critical applications can be designed to be tolerant of internal faults. For example, the output from a complex algorithm can be checked to ensure that it lies within safe bounds before the data is used in an application such as a safety or financial critical application. The code that performs the boundary checks is simple and therefore much easier to prove correctness. Some web applications are susceptible to a variety of vulnerabilities that are introduced by poor design and coding, such as database injection and cross-site scripting attacks. In these attacks, requests can be manipulated to abuse the web server functionality.
Organisations are to establish and implement organisation-wide processes for secure coding that applies to both software products obtained from external parties and to open source software components.Organisations should keep up to date with evolving real-world security threats and with the most recent information on known or potential software security vulnerabilities. This will enable organisations to improve, and implement robust secure software coding principles that are effective against evolving cyber threats.Secure software coding principles should be followed both for new coding projects and for software reuse operations. These principles should be adhered to both for in-house software development activities and for the transfer of the organisation’s software products or services to third parties.
Planning and precoding
Both new code development and code reuse require the application of secure coding principles – regardless of whether the code is written for internal software or for external products and services. This requires the evaluation of the organization-specific expectations and definition of recognized principles in advance. In addition, recommended actions for planning and precoding take into account known common and historical coding practices and errors that could lead to vulnerabilities. The configuration of development tools, such as rule-based in integrated development environments (IDE), should enforce the creation of secure code. Quite critical is the qualification of developers and their familiarity with secure architectures and programming standards. The inclusion of information security expertise in the development team goes without saying. When establishing a plan for secure coding principles and determining the prerequisites for secure coding, organisations should comply with the following:
- Organisations should determine security expectations tailored to their needs and establish approved principles for secure software coding that will apply to both in-house software development and outsourced software components.
- Organisations should detect and document the most prevalent and historical poor coding design practices and mistakes that result in compromise of information security.
- Organisations should put in place and configure software development tools to ensure the security of all code created. One example of such tools is integrated development environments (IDE).
- Organisations should achieve compliance with the guidance and instructions provided by software development tools.
- Organisations should review, maintain, and securely use development tools such as compilers.
During the coding process
During the coding process, coding practices and structured programming techniques play a primary role, taking into account the specific use case and its security needs. Insecure design techniques – for example, hard-coded passwords – should be consistently prohibited. Code should be adequately documented and reviewed to best eliminate security-related bugs. Code review should take place both during and after development, via static application security testing (SAST) or similar. Static testing methods support the shift left approach (“test early and often”) by shifting left in the lifecycle by testing visible code for rule conformance early. This allows early identification of tainted code, connections to files or specific object classes, or application-level gaps that can be abused for unnoticed interaction with third-party programs as exploitable vulnerabilities. Before the software is put into operation, Control 8.28 requires an evaluation of attack surfaces and the implementation of the least privilege principle. The analysis performed of the most common programming errors and documentation of their correction should be evaluated. Secure coding practices and procedures should take into account the following for the coding process:
- Secure software coding principles should be tailored to each programming language and techniques used.
- Deployment of secure programming techniques and methods such as test-driven development and pair programming.
- Use of structured programming methods.
- Proper code documentation and removal of code defects.
- Prohibition on the use of insecure software coding methods such as unapproved code samples or hard-coded passwords.
- Security testing should be performed both during and after the development .
Before putting the software into actual use in the live application environment, organisations should consider the following:
- What is the attack surface?
- Is the principle of least privilege followed?
Carrying out an analysis of the most prevalent programming mistakes and documenting that these risks have been eliminated.
Review and maintenance
Even after the software has gone live, the topic of secure coding remains relevant. This includes secure updates as well as checks for known vulnerabilities in one’s code. In addition, errors and suspected attacks must be documented so that necessary adjustments can be made promptly. In any case, unauthorized access to the source code must be reliably prevented by suitable tools. After the Code Is Put Into Use in the Production Environment, Updates should be applied in a secure manner. Security vulnerabilities reported should be addressed. Suspected attacks on information systems and errors should be recorded and these records should be reviewed on regular intervals so that appropriate changes to code can be made. Unauthorized access to, use of, or changes to source code should be prevented via mechanisms such as management tools. When Organisations Use External Tools, They Should Take Into Account the Following
- External libraries should be monitored and updated at regular intervals based on their release cycles.
- Software components should be carefully vetted, selected, and authorised especially cryptography and authentication components.
- Licensing of external components and ensuring their security.
- Software should be tracked and maintained. Furthermore, it must be ensured that it comes from a trustworthy source.
- Development resources should be available for the long term.
When Making Changes to a Software Package, the Following Should Be Considered
- Risks that may arise out of built-in controls or compromise of integrity processes.
- Whether the vendor gives consent to changes.
- Whether it is possible to get consent from the software vendor for regular updates.
- The likely impact of carrying on the maintenance of the software that arises out of changes.
- Whether the changes would be compatible with other software components used by the organisation.
In the area of verification and maintenance, it additionally lists explicit instructions for the use of external tools and libraries, such as open source software. These code components should be managed, updated and maintained in inventories. This can be done, for example, via a Software Bill of Material (SBOM). An SBOM is a formal, structured record of a software’s packages and libraries and their relationships to each other and within the supply chain, in particular to keep track of reused code and open source components. The SBOM supports software maintainability and targeted security updates.Organisations should ensure that security-relevant code is used when it is necessary and is resistant to tampering:
- While programs installed via binary code include security-relevant code, this is limited to the data stored within the application itself.
- Concept of security-relevant code is only useful when code is run on a server that is not accessible to the user and it is segregated from the processes that use it and its data is kept securely in another database. For instance, you can run an interpreted code on a cloud service and access to code can be restricted to privileged administrators. It is recommended that you protect these access rights via methods such as just-in-time administrator privileges and robust authentication mechanisms.
- Appropriate configurations on web servers should be implemented to prevent unauthorised access to and browsing of the directory.
- When designing application code, you should start with the assumption that the code is vulnerable to attacks due to coding errors and actions by malicious actors. You should design critical applications in a way that they are not vulnerable to internal faults. For instance, the output produced by an algorithm can be reviewed to ensure that it complies with security requirements before it can be used in critical applications such as finance-related applications.
- Certain web applications are highly vulnerable to security threats due to poor coding practices such as database injection and cross-site scripting attacks.
Top Secure Coding Checklist
- Input Validation: For input validation, you need to conduct data validation on the authenticated server, determine trusted and untrustworthy data sources, specify accurate character sets and encode data into common characters before validating. In case of input rejection, there must be a validation failure.
- Authentication: Another important factor to maintain the security of the code is authentication. It is crucial to authenticate all the pages as well as resources and enforce the authentication system on a trusted system. After that, you can easily establish and use standard authentication services. Another important thing to consider while authenticating is to segregate authentication logic from the resource that is being requested. If the app you are going to develop has a credential store to manage, it should ensure that the passwords are stored cryptographically to enhance security. Only use HTTP POST requests to transfer authentication credentials.
- Password Management: When it comes to passwords, they should be concealed on the user’s screen, and if someone is trying to access the account with the wrong credentials the account should be disabled for a certain time period to discourage brute force of password guessing. Temporary passwords should have a short expiration time and users must be verified in case of password reset. You can also add multi-factor authentication for highly sensitive or transactional accounts.
- Access Control: While developing an app you should restrict access to protected URLs, functions, services, object references, application data, user and data attributes, and security configurations to authorized users only. Moreover, the app should deny all access if the security configuration information cannot be accessed.
- Error Handling: Most software errors are caused by bugs, which can lead to vulnerabilities. Keeping a log of errors and handling them accordingly are two of the best ways to minimize their impact. Error handling attempts to prevent catastrophic failures by identifying errors in the code before they occur. Using error logging, developers can diagnose errors and mitigate their effects. To comply with secure coding standards, it is necessary to document and log all errors, exceptions, and failures.
- Data Protection: To improve data protection, you should encrypt highly sensitive information on the server-side by using cryptographic hashes and protect server-side code from being downloaded by the user. Disabling the auto-complete feature on forms containing sensitive information can also help in enhancing security.
- Communication Security: Implement encryption for sensitive data transmission by incorporating Transport Layer Security (TLS) certificates.
- System Configuration: System configuration can be secured if you are using the latest versions of frameworks, servers, and other system components, or removing unnecessary files, functionalities, test codes, etc, from HTTP response headers. Provide access to only authorized development and test groups and isolate development environments from the production network. Development environments are seldom as secure as production environments, which enables attackers to identify shared vulnerabilities or exploit them. It is thus imperative that you implement a software change control system to manage and track changes in both production and development environments.
- Database Security: For database security, use strongly typed queries, use input and output validation and use secure credentials to access the database. You should also change or remove the default passwords of the database with strong passwords or multi-factor authentication.
General Coding Practices
Now that we have gone through the checklist of secure coding, it is time to have a look at general coding practices that any developer should follow:
- Always use tested and approved codes rather than unmanageable code.
- Do not allow the app to directly issue commands to the operating system using initiated command shells instead use task specified APIs that conduct tasks related to the OS.
- To verify the integrity of libraries, interpreted codes, configuration files, and executables use hashes or checksums.
- Protect shared resources and variables from ill-suited intersecting access.
- Don’t pass user-provided data to a dynamic function.
- Users should not be able to alter existing code or develop new ones.
- Review all third-party code, applications, and libraries to ensure safe functionality and business necessity.
- Use cryptographic signatures for code in case of automatic updates and determine signature verification by clients.