Let's see how we can make more secure software.
Using vulnerable and outdated components with known vulnerabilities has always been in the OWASP Top 10 Application Security Risks. You can take a giant leap in securing your projects only if you use up-to-date tools and libraries.
If you have the Not invented here (NIH) syndrome, you prefer to develop everything from scratch. That's fine if you have the time and money to do so. But building major things like cryptography and web servers from scratch needs a lot of skills and effort. Such complex components cannot be built by a single person. Even if you have made one, you should not use it in production without in-depth reviews from many other people.
In design and architecture concepts, you should do the same. You should follow best practices to benefit from the community experience.
Next time instead of introducing your own hash algorithm, use one of the well-known hash functions implemented by an open-source and peer-reviewed library.
One significant risk of using third-party modules (like packages in npm, PyPI, NuGet, etc. ) is the Supply Chain Attack. Consider one of your project's dependencies goes rogue and doesn't do what it was supposed to do. It is called a supply chain attack. This has happened for popular npm packages (UA-Parser-JS, COA, and RC), and it can happen for many others.
We know that using third-party packages is inevitable. So, here are a few tips to consider before choosing a third-party library.
- Prefer packages with more contributions (more contributors, commits, pull requests, and stars)
- Prefer packages with less open issues
- Prefer packages with higher release frequency
- Use dependency scanners like GitHub Dependabot to find vulnerable packages.
Always validate data received from user input before processing them. Check the length, type, allowed characters, and data pattern before using it.
The essential thing in user validation is to do it where the user cannot manipulate the logic. For example, the user has complete control over a webpage, so checking if the user entered a correct email address on the client is not enough, and you should validate it on the back-end again.
Always use proper encoding when displaying data to the user. The encoding depends on the context you display the data within.
For example, data on a web page should be HTML-Encoded, and data in URL should be URL-Encoded. Other contexts like CSV, XML, JSON files, or email need unique encodings.
Exceptions happen! We should be prepared for them. Unhandled errors create security issues like failing insecurely or revealing sensitive information.
Always assume things will break eventually and get prepared for it.
When you put comments in the code, it means your code is not clear and expressive enough and needs explanation. So, a better title for this section would be Do not Write Comments.
“Comments are always failures.”
— Robert C. Martin @ Clean Code
There are some valid use-cases for comments in the code, but writing operational information and sensitive data like passwords are not one of them.
Linters can analyze your code and enforce particular rules. Linters assist you in finding errors, bugs, code smells, and suspicious expressions like using
eval and dangerous regular expressions.
Open source projects are maintained by the community. It means their structure is not specific to a single user's environment. Open source projects (usually) don't have any hard-coded passwords or internal IP addresses. These are good practices we can follow in our projects.
Not every project is supposed to be open-source and publicly available. But we should prepare all projects for open sourcing. Here are a few things to start:
- Remove hard-coded passwords, IP addresses, and database connection strings, ...
- Load all configurations from environment variables
- Add a
readme.mdfile to your project and document build and test instructions.
A clean code is inherently more secure. From a security point of view, a clear code has many benefits:
- A clear code has fewer opportunities for vulnerabilities to occur because they're less complex
- Reviewing and finding vulnerabilities in a clear code is easier
- It takes less time and effort to fix a vulnerability in a clear code
You can read the Clean Code book (if you haven't read it already) and start refactoring your codes.