What is Secure Coding?
Much of the world today runs on software applications, which include parts of our daily lives. But how can we make sure that we are protected in this aspect of our lives? This is where secure coding comes in. Secure coding relies on standards, or a set of uniform guidelines that software developers can apply to their code, to provide safeguards against security vulnerabilities. Software vulnerabilities are unfortunately an ever present risk. For that reason, it's important that you ensure that your code is secure and protected.
Why Should We Care?
Secure Coding is a defense against many types of vulnerabilities. If left insecure these vulnerabilities can be exploited by hackers causing irreparable damage. The risk of insecure software includes:
- Denial of service to a single user
- Compromised secrets
- Loss of service
- Damage to the systems of thousands of users
- Loss of life
Types of Vulnerability
Injection: Injection flaws allow attackers to ‘inject’ code into a system through a simple system call. These calls are generally done using external programs via shell commands. Injections done to database or SQL Injections are the most common and dangerous of all.
Buffer Overflow: Buffer is a sequential memory allocated to contain data like strings or integers. Consider if this buffer gets bombarded with data or requests more than what it can handle. It will overflow into adjacent storage. This overflow can create significant issues like crashing your software, loss of data, or the most dangerous, creating an entry point for cyberattacks.
Broken Authentication: Broken authentication vulnerability occurs when an attacker uses different ways to get into someones account. It leads to false authorization and then the loss of sensitive data yet again. The code becomes vulnerable in cases when there are no multiple verifications or session timeouts. The most common code vulnerability in web apps is when a session ID is created for a user and the hacker somehow retrieves and uses URL rewriting to recreate that session. Another way is if a hacker can get into your password database using other security vulnerabilities, and if it is not correctly hashed and salted, one can reverse the encoding and display everyone's passwords.
Industry Level Security Standards
With secure coding comes industry level security standards. This is so important because it not only protects businesses, it also protects the consumers who use the application.
For instance, consider how much of today's purchases are done online. Consumers must place their payment information in the care of the business. This is one big reason why we should care because if someone were to get ahold of your information, they could rob you of all your money.
When considering secure coding for payment card industry compliance, code must adhere to the PCI DSS requirement. PCI DSS stands for Payment Card Industry Data Security Standard. Building the security happens during the development process. Coders must be properly trained to ensure that any card payment transactions are not occurring in an insecure environment.
Here are some of the requirements for the PCI DSS compliance
Protect Your Systems with firewalls:
- Properly configured firewalls protect your card data environment. Firewalls restrict incoming and outgoing network traffic through rules and criteria configured by your organization. To maximize efficiency, its best to install both software and hardware firewalls.
Configure and password settings:
- PCI Requirement 2 involves securing your systems. This includes things like passwords, configuration, and system hardening.
- Changing Default Passwords. Devices such as routers or POS systems usually come straight from the vendor with factory settings like default usernames and passwords. To harden your system, remove any unnecessary functionality in your system and configure what is left in a secure manner.
Protect stored card holder data:
- The purpose of PCI is to protect and secure stored card holder data and prevent data breaches. And according to requirement 3, stored card data must be encrypted using industry-accepted algorithms. Not only must card data be encrypted, the encryption keys themselves must also be protected. For example, using a solid PCI DSS encryption key management process will help keep you from storing the key in the “lock” itself.
- To fulfill this requirement, you need to create and document a current card holder data (CHD) flow diagram for all card data flows in your organization. A CHD flow diagram is a graphical representation of how card data moves through an organization. As you define your environment, it’s important to ask all organizations and departments if they receive card holder information, and then document how their answers may change card data flows.
Encrypt transmission of cardholder data across open, public networks:
- Keep track of your PAN: You need to identify where you send cardholder data. Information like Primary Account Numbers (PAN) and magnetic stripe data should be stored securely and encrypted. Some common places PAN is sent include:
- Backup servers
- Third parties that store/handle PAN
- Outsourced management of systems
- Corporate offices
Regularly update and patch systems:
- PCI DSS requires anti-virus to be installed on all systems that are commonly affected by malware. Using outside sources such as the United States Computer Emergency Readiness Team (US-CERT), SANS Institute, and vendor/anti-virus threat feeds, you can identify emerging malware and attacks on systems. You can then configure systems to alert and report on suspicious activity, such as new files added to known malware directories or unauthorized access attempts.
Conduct vulnerability scans and penetration tests:
- A vulnerability scan is an automated, high-level test that looks for and reports potential vulnerabilities. While, a Penetration Testing a.k.a pen testing involves a team of cybersecurity experts who attempt to break into your company's network to find and exploit weaknesses and vulnerabilities in your systems.
- There differences are that a vulnerability scan is automated, while a penetration test includes a live person actually digging into the complexities of your network. A vulnerability scan only identifies potential vulnerabilities. During a penetration test the tester will verify the exploitability of the vulnerability and look to identify the root cause of the vulnerability that allows access to secure systems or stored sensitive data.
Documentation and risk assessments:
- Keep documentation, policies, procedures, and evidence relating to your company’s security practices. You will need to include the following information in your documentation:
- Employee manuals
- Policies and procedures
- Third-party vendor agreements
- Incident response plans
Also, you will need to perform an annual, formal risk assessment that identifies critical assets, threats, and vulnerabilities. This requirement will help you identify, prioritize, and manage your information security risks.
Best Practices for Secure Coding
1. Don't leave security until the end
- Implement the security during the development process.
2. Valid User Input
- User input are can be one of the major attacking points from where various attacks such as SQL Injection, XSS injection can take place. Hence, it is very important to make sure that you as a developer have sanitized all the user input fields. Validating user input includes filtering out hazardous blacklisted characters like parenthesis and special characters could be one possible approach, but whitelisting can be more effective.
3. Manage Sessions and Permissions
- The main motive of any application is to keep the targeted users involved in the application. And, sometimes users are the same individual who can cause a great threat to your application. For this it's best to make sure your application enables two-factor authentication. Also does not allow concurrent logins with the same user account and makes sure to enforce a timeout for each session, setting a new and unique identifier with each re-authentication.
4. Secure Database Design and Access
- As you all know the database is one of the most crucial part of any application, which holds entire data of the application in one place. Sometimes, due to insecure coding, attackers can easily view the data that one should not be allowed to and can manipulate the entire data which leads to delivering false information to the real users and worst, attackers can also deliver malicious attacks through the database.
5. Error Handling:
- When users perform any invalid activity in the application, most applications throws an error message. This could be very useful for the user to know what happened. But, the same thing if left as the default error message, can reveal a lot more information about your system. Whatever caused the problem should be logged.
6. Secure Server Configuration
- Some ways to ensure this are:
1. Delete default and guest accounts.
1. Rename the default Administrator account.
1. Disable debugging functions and make sure to edit all the default error messages.
1. Do not use self-signed SSL or default certificates.
1. Scan from the outside network and assure that all unnecessary ports are closed.
1. Monitor latest security vulnerabilities and apply the latest patches.
1. Regularly scan for vulnerabilities and document the reports.
Pierce Taylor, Software Engineer Intern at HacWare. HacWare measures risky cybersecurity behaviors and automates security education to help MSPs combat phishing attacks.
Learn more about HacWare at hacware.com