Tips to making your code more secure
Security is not something we can ever take for granted and no matter how secure a company’s infrastructure and firewalls are, a security issue in the code can lead to significant issues and potential breaches within any company.
So, the idea of needing code to be secure is an easy one to argue for. Yet – surprisingly – it’s still something that people may take lightly, focusing too much on specialists and scans to do the work for them. Rather than putting in a little extra effort to ensure code and applications are resistant to security vulnerabilities, which can be exploited by malicious actors.
This doesn’t just apply to software or data engineers, but all disciplines of engineering where our code sits need to take responsibility for the code they write and any vulnerabilities or issues that could be caused by the code they write or the modules they may be importing into their code.
Here are some key reasons why secure coding is important:
Protection of Sensitive Data
Many applications handle sensitive information such as personal data, financial records, or business-critical information. Secure coding practices help protect this data from unauthorized access, leaks, or theft by minimizing vulnerabilities like SQL injection or cross-site scripting (XSS).
Prevention of Exploits
Security flaws in code can be exploited to gain unauthorized access to systems, alter data, or disrupt services. Secure coding helps developers identify and mitigate potential weaknesses like buffer overflows, improper input validation, or broken authentication mechanisms, preventing attacks like malware injection and denial-of-service (DoS) attacks.
Regulatory Compliance
Globally, we are governed by strict data protection regulations such as POPIA, GDPR, HIPAA, and PCI-DSS. Secure coding is critical for ensuring that software complies with these regulations, avoiding legal penalties, and ensuring the privacy of users' data.
Reduction of Long-Term Costs
Fixing security vulnerabilities after a product has been released is far more expensive and time-consuming than addressing them during the development phase. By integrating secure coding practices early, organizations can save costs associated with post-release patches, security breaches, and potential fines.
Improved User Trust
Users are more likely to trust applications that are secure, particularly in sectors like finance or healthcare where data security is paramount. Breaches due to insecure code can lead to loss of customer trust, damaging a company's reputation and revenue.
Business Continuity
Security vulnerabilities can lead to system downtime, data loss, or reputational damage, which can disrupt business operations. By implementing secure coding practices, companies can ensure the resilience of their systems, reduce the risk of breaches, and maintain business continuity.
Security by Design
By embedding security into the software development life cycle (SDLC), secure coding promotes a "security-first" mindset. This prevents developers from relying solely on later-stage defenses like firewalls and intrusion detection systems and ensures that software is fundamentally designed with security in mind.
Mitigation of Zero-Day Vulnerabilities
Secure coding can help reduce the window of opportunity for attackers to exploit unknown or unpatched vulnerabilities, known as zero-day vulnerabilities. Even if a vulnerability is discovered, secure coding principles like defensive programming can reduce its impact.
Secure Coding Best Practices
Improving secure coding skills involves adopting best practices, using tools to identify vulnerabilities, and staying up to date on the latest security threats.
Here are some practical tips to help you enhance secure coding practices:
Validate Input
Use Parameterized Queries
Implement Strong Authentication and Authorization
Encrypt Sensitive Data
Avoid Hardcoding Secrets
Follow Secure Coding Standards
Conduct Regular Code Reviews
Use Static Application Security Testing (SAST) Tools
Employ Secure Libraries and Frameworks
Implement Error Handling and Logging
Use Content Security Policy (CSP) for Web Apps
Regularly Patch and Update Dependencies
Use Secure Session Management
Learn from Security Incidents
Stay Up to Date on Emerging Threats
Some practical code examples
I thought it would only be fair though to provide you with some basic examples of what secure code looks like against unsecure code. As you can see from the below examples – it’s not always immediately clear that code isn’t secure because the code solves the immediate functional solution so effortlessly. These are just basic examples – with most applications containing far more complicated code, the chance of error only increases – which is what makes embedding these skills into your regular coding practices so important.
These examples, which use a mix of Python and JavaScript code, highlight common vulnerabilities and the best way to mitigate them.
SQL Injection
Insecure Code:
Python
# Insecure: Directly concatenating user input into a SQL query
user_id = request.GET.get('user_id')
query = "SELECT * FROM users WHERE id = '" + user_id + "'"
cursor.execute(query)
Recommended by LinkedIn
Secure Code:
Python
# Secure: Using parameterized queries to avoid SQL injection
user_id = request.GET.get('user_id')
query = "SELECT * FROM users WHERE id = %s"
cursor.execute(query, (user_id,))
Cross-Site Scripting (XSS)
Insecure Code:
javascript
// Insecure: Directly rendering user input in the browser
let userComment = getUserComment(); // User input from a form
document.getElementById('comment').innerHTML = userComment;
Secure Code:
javascript
// Secure: Escaping user input before rendering it in the browser
let userComment = getUserComment();
document.getElementById('comment').innerText = userComment; // Escape user input
Hardcoded Secrets
Insecure Code:
Python
# Insecure: Hardcoding sensitive credentials in the code
API_KEY = "12345-abcde-67890-fghij"
Secure Code:
python
# Secure: Storing secrets in environment variables
import os
API_KEY = os.getenv('API_KEY')
Weak Password Storage
Insecure Code:
Copy code
# Insecure: Storing plain text passwords
user_password = request.POST['password']
store_password_in_db(user_password)
Secure Code:
Python
# Secure: Hashing passwords before storing them
import bcrypt
user_password = request.POST['password']
hashed_password = bcrypt.hashpw(user_password.encode('utf-8'), bcrypt.gensalt())
store_password_in_db(hashed_password)
Insecure File Uploads
Insecure Code:
Python
# Insecure: Saving file uploads without validation
file = request.FILES['file']
file.save(os.path.join("/uploads", file.name))
Secure Code:
Python
# Secure: Validating and sanitizing file uploads
import os
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
def is_allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
file = request.FILES['file']
if is_allowed_file(file.filename):
safe_filename = secure_filename(file.filename)
file.save(os.path.join("/uploads", safe_filename))
Improper Error Handling
Insecure Code:
Python
# Insecure: Leaking sensitive error information
try:
# Code that might raise an exception
except Exception as e:
return f"Error: {str(e)}"
Secure Code:
Python
# Secure: Logging the error while providing a generic message to the user
import logging
try:
# Code that might raise an exception
except Exception as e:
logging.error(f"An error occurred: {str(e)}")
return "An unexpected error occurred. Please try again later."
Insecure Session Management
Insecure Code:
Python
# Insecure: Not using secure flags for cookies
session['user_id'] = user_id
Secure Code:
Python
# Secure: Using secure and HttpOnly flags for cookies
session['user_id'] = user_id
app.config.update(
SESSION_COOKIE_SECURE=True, # Only send cookies over HTTPS
SESSION_COOKIE_HTTPONLY=True, # Prevent JavaScript access to cookies
)
Conclusion
Secure coding is critical and it’s important that everyone who touches code becomes familiar with the skills required to make code secure. However, coding is more than just about the functional code you write, but also the data as well, which is why in my next blog post – I will be looking at tips to securing your data in your code as well.