During the COVID-19 pandemic, cyber-attacks have increased dramatically.1 While educating employees to be wary of phishing attempts and updating anti-virus software may give companies a superficial feeling of security, organisations need to pay close attention to all the parts of their digital presence. This starts with examining the mere foundation.
These days, we hear about cyber-attacks all the time. As the value of digital data increases, so does the frequency of cyber-attacks. Companies are being forced to pay for ransomware, governments are having secret data stolen, and even celebrities are having their private photos leaked. The common denominators of all these cases are security holes, vulnerabilities that a threat actor can exploit. Fundamental to any application is the source code. It must not only work, be fast and efficient, it must also be secure. Otherwise, design and implementation flaws can lead to vulnerabilities that can later be exploited in cyber-attacks.
Secure Code Should Be Practised in Every Software Development Project
Next-generation firewalls and other security appliances can mitigate some vulnerabilities, but not all. Let us say you visit a blog website where different users publish their posts. You click on the author of the first blog post. On the page that appears, you see the author’s name, the number of posts, and some other information, but when you take a closer look at the actual web address, you notice that it ends with “/profiles/15”. Hmm… what happens if you change that “15” to, say, “14” or “304”?
Since the site exposes internal identifiers, you can easily iterate over and find how many users are there and collect their information. And no firewall can save you in this case; only secure code can. Instead of exposing internal identifiers, the page could use a more natural identifier like username, so that the address would end with “/profile/john-smith” and this simple modification now prevents easy extraction.
But not all vulnerabilities are that obvious. Let us take, for example, the following function that checks if a provided token equals some predefined secret value.
The code looks simple and straightforward, but it also contains one hidden vulnerability. To understand it, we need to know how string comparison works. It iterates over strings and compares them character by character. As soon as two characters mismatch, it ends the comparison and returns that the strings are not equal. Let us compare “tiger” with “table”. As we can see on the image below only the first two characters are compared. But if we take “tight” instead of “table” two more characters are compared. So, a string comparison can take a different amount of time, depending on the location of the first difference.
This can be exploited in case when the attacker controls the token that is compared to some secret value. The attacker can measure the execution time and, with enough measurements, detect the first character of the secret value, as the comparisons, in that case, takes a little more time. He then continues sending tokens that start with this correct first character and determines the next correct character. Using this technique, he can reconstruct the whole secret value. To prevent this from happening, we need to use secure coding once again. This kind of timing attacks can be successfully prevented with a constant time string comparison function that always compares all the string characters. In Python, this function is already part of the standard library, so the code requires just a small modification.
As we can see, the difference between secure and insecure code lies in the details, and it requires an experienced software developer with deep security knowledge to recognize such code vulnerabilities.
Therefore, every software application should incorporate good security practices. Implementing secure code is one of those practices that we often do not think about until it’s already too late.
Writing Secure Code Is a Continuous Learning Process
At the end of October, Cisco’s annual global developer conference Cisco DevNet Create 2021 took place. In addition to attending some great talks, I took part in the Secure Code Warrior tournament, where attendees competed in a series of vulnerable code challenges. Some challenges involved locating insecure code and then fixing it.
Personally, I liked the attacker challenges more. I found them easier and more fun, as we had multiple shots at constructing evil payloads. The tournament consisted of two rounds. First, the qualifying round with 328 participants and the grand final for the best 25 participants one week later. Fortunately, I qualified for the grand final.
In the final, the types of challenges remained the same; they were just a bit more difficult and included some more advanced topics. At the end of the tournament, I was able to secure the outstanding 6th place.
How to Start Writing Secure Code?
A good starting point for secure coding is the Open Web Application Security Project’s (OWASP) TOP 10 list of the 10 most common security risks for web applications.
OWASP is a nonprofit foundation dedicated to improving the security of software.
The TOP 10 categories in 2021 are:
- Broken Access Control
- Cryptographic Failures
- Insecure Design
- Security Misconfiguration
- Vulnerable and Outdated Components
- Identification and Authentication
- Software and Data Integrity Failures
- Security Logging and Monitoring Failures
- Server-Side Request
Each is explained in detail on the OWASP page. Along with other references and attack scenarios, this is a solid starting point.
Remember, attackers must find only one vulnerability, we must find them all!
Want to find out more about our services or work on a project with us? We’d love to hear from you!
For more information, articles and updates follow us on LinkedIn.
1PWC. How to protect your companies from rising cyber attacks and fraud amid the COVID-19 outbreak, 2021. https://www.pwc.com/us/en/library/covid-19/cyber-attacks.html