Part I: Secure Coding Made Easy: 5 Tips to Integrate Security Into Development
This two-part guide will give you practical tips in using secure coding best practices. It’s based on the OWASP Top 10 Proactive Controls.
Join the DZone community and get the full member experience.Join For Free
Part 1: Secure Coding Made Easy
With increasing cyberattacks and corporate takedowns, secure coding skills are no longer optional for software developers. In fact, you’ve probably found that application security (AppSec) has become an absolute necessity in your day-to-day workflow. How you write code, and the steps you take to update and monitor it, have a significant impact on your applications, your organization, and your ability to do your job well.
This two-part guide will give you practical tips in using secure coding best practices. It’s based on the OWASP Top 10 Proactive Controls — widely considered the gold standard for application security. We’ll provide an overview of each control, along with coding examples, actionable advice, and further resources to help you create secure software.
Tip 1: Verify for Security Early and Often
It used to be standard practice for the security team to do security testing near the end of a project and then hand the results over to developers for remediation. But tackling a laundry list of fixes just before the application is scheduled to go to production isn’t acceptable these days. In fact, it dramatically increases the risk of a breach; the Verizon 2020 Data Breach Investigations Report (DBIR) found that web applications were the source of over 43 percent of breaches, which is more than double the amount in 2019.
To verify your security early and often, you need the tools and processes for manual and automated testing during coding – it must be iterative.
- Consider data protection from the beginning. Include security parameters and scanning frequency upfront when agreeing upon the definition of “done” for a project.
- Consider the OWASP Application Security Verification Standard as a guide to define security requirements and generate test cases.
- Scrum with the security team to ensure testing methods fix any defects.
- Build proactive controls into stubs and drivers.
- Integrate security testing in continuous integration to create fast, automated feedback loops
Add a security champion to each development team. A security champion is a developer with an interest in security who helps amplify the security message at the team level. Security champions don’t need to be security pros; they just need to act as the security conscience of the team, keeping their eyes and ears open for potential issues. Once the team is aware of these issues, it can then either fix the issues in development or call in your organization’s security experts to provide guidance.
Tip 2: Parameterize Queries
SQL injection is one of the most dangerous application risks, partly because attackers can use automated attack tools to exploit these common vulnerabilities. In August of 2020, the company Freepik suffered a SQL injection attack in which emails and passwords for 8.3 million users were stolen. You can control this risk using query parameterization. This type of query specifies placeholders for parameters, so the database will always treat them as data, rather than as part of a SQL command. You can use prepared statements, and a growing number of frameworks, including Rails, Django, and Node.js, use object-relational mappers to abstract communication with a database.
- Parameterize queries by binding variables.
- Be cautious about allowing user input into object queries (OQL/HQL) or other advanced queries supported by the framework.
- Defend against SQL injection using proper database management system configuration.
Tip 3: Encode Data
Encoding translates potentially dangerous special characters into an equivalent form that renders the threat ineffective. This technique is applicable for a variety of platforms and injection methods, including UNIX command encoding, Windows command encoding, and Cross-Site Scripting (XSS). Encoding addresses the three main classes of XSS: persistent, reflected, and DOM-based.
- Use relevant, industry-proven encoding tools to address the spectrum of attack methods, including injection attacks.
Tip 4: Validate All Inputs
It's vitally important to ensure that all data is syntactically and semantically valid as it arrives and enters a system. As you approach the task, assume that all data and variables can’t be trusted, and provide security controls regardless of the source of that data. Ensure that inputs not only include the correct number of characters or digits, but that they have actual meaning and are valid for the interaction or transaction. Allow listing is the recommended validation method wherever possible.
- Assume that all incoming data is untrusted.
- Develop allowlists for checking for specific trusted values.
- Input validation must take place on the server side. This extends across multiple components, including HTTP headers, cookies, GET and POST parameters (including hidden fields), and file uploads. It also encompasses user devices and back-end web services.
- Use client-side controls only as a convenience.
Tip 5: Implement Identity and Authentication Controls
You can avoid security breaches by confirming user identity up front and building strong authentication controls into code and systems. These controls must extend beyond a basic username and password. You’ll want to include both session management and identity management controls to provide the highest level of protection.
- Use strong authentication methods, including multi-factor authentication, such as FIDO or dedicated apps.
- Implement secure password storage as irreversible hashes.
- Implement a secure password recovery mechanism to help users gain access to their account if they forget their password.
- Establish timeout and inactivity periods for every session.
- Use re-authentication for sensitive or highly secure features.
- Use monitoring and analytics to spot suspicious IP addresses and machine IDs.
Password hashing in PHP using the password_hash() function (available since 5.5.0) defaults to using the BCrypt algorithm. This example uses a work factor of 15:
Ready to Test Your Skills?
Educational training tools that allow you to exploit and patch the flaws you face daily are critical to expanding your know-how and improving the security of your code. Veracode Security Labs offers the courses you need to create more secure applications, with real-world examples and hands-on-keyboard training that helps you apply new skills immediately. Even better: Security Labs Community Edition is a forever-free option for developers like you who are looking to gain authentic experience that you can use on the job.
Click here for the second part of our series with more secure coding tips and best practices!
Published at DZone with permission of Fletcher Heisler. See the original article here.
Opinions expressed by DZone contributors are their own.