Cybersecurity for Developers: Cheat Sheet
9 min read
The issue of cybersecurity must be a matter of concern not just for experts, but for ordinary developers as well. Not every project can afford a dedicated role of a security specialist, so the one to bear this burden, in one way or another, might be You
It’s nice to have a kind of reminder or a cheat sheet for such cases, so I made up a list of the things to take care of.
The created list is neither really short nor exhaustive, but at least it seems rather manageable and comprehensible.
I must confess that the material hereinbelow is ultimately inspired by a very nice course that I attended a few years ago and which I do recommend to everyone interested in the topic of InfoSec/Cybersecurity. So, be aware of a freely available Software Security course offered by the University of Maryland on Coursera.
Cybersecurity Cheat Sheet
Software security is conceptually different and therefore not that intuitive compared to general functional requirements, of which we care foremost. Nevertheless, security is a crucial property of software, especially when it comes to the software-controlled machines that can affect the life and health of the customers or the systems that process personal data.
While usually the desired program behavior is treated as a primary goal, the main concern of security, in contrast, is what a program should not do, in other words, preventing the undesired behavior.
There are three primary properties of the software security, which we strive to keep from violation:
- Confidentiality. Means that sensitive information should not be leaked to unauthorized parties;
- Integrity. Means that preserved information should not be damaged by unauthorized parties;
- Availability. Means that a system should remain responsive to requests (according to the agreed conditions).While intuitively availability is associated with protection from DoS attacks, it is not limited to them. Just consider the following problems of the same importance:
- Application upgrades;
- IP address possession renewal;
- Domain name possession renewal;
- Encryption and authentication certificates rollover.
Whenever such properties are violated, the software is considered to have a vulnerability.
Vulnerability is a security-relevant software defect that can be exploited to achieve undesired behavior.
If a vulnerability is caused by a defect in design rather than code, it is called a flaw.
There is a set of common principles that you ought to follow when building secure software. In general, these principles can be split into the following categories:
- Prevention – eliminate defects entirely;
For example, it is possible to eliminate entire sets of defects by using memory-safe languages like Java or C# instead of C/C++.
- Mitigation – reduce the harm from the exploitation of an unknown defect;
For instance, the harm of the hijacked database can be greatly reduced when the stored data is encrypted. Blocking accounts with suspicious behavior and requiring additional confirmation on potentially harmful actions is another example.
- Detection – identify and understand attack (i.e. Monitoring);
It is necessary to get informed of potentially malicious actions as soon as possible. Comprehensive real-time telemetry makes a great help in such case.
- Recovery – undo the damage.
“Quickly raised is not considered fallen,” therefore it is always necessary to have data backed up and extra resources ready to be available in case of urgency. In addition to that, it is highly important to have procedures of recovering hacked user’s accounts.
The basic principles you ought to follow whenever you design, implement, or maintain the software are as follows:
- Favor simplicity (prevention);
- Favor simple design;
“Keep it simple, stupid,” is a well-known meme that is utterly applicable in our context.
For instance, think twice when you choose between an old-fashioned monolith and overhyped microservices. Always consider available capabilities and expertise.
- Use fail-safe defaults;
Never keep using default passwords, apply industry-standard cryptography, favor whitelisting over blacklisting, etc.
- Do not expect an expert user;
The more power you give in an unrestricted manner – the higher the probability of misusing it is. For example, installing applications from untrusted sources on Android (APK files) requires explicit activation of this feature in device settings, which is a fair foolproof solution.
- Favor simple UI;
Again, complexity is the enemy of security. Complex UI increases the chance of a mistake from both developer’s and user’s sides.
- Avoid allowing users to make security choices.
You cannot assume the users understand cryptography schemes or even rules of secure online behavior, therefore do not let them chose encryption algorithms & keys or insecure passwords.
- Trust with reluctance (prevention/mitigation);
- Employ a small trusted computing base;
The more components (both hardware & software) your system consist of – the wider the attack surface is. In that sense, every new platform you are going to support and every service you integrate with should be considered as a source of risk and danger.
- Avoid using your own cryptography;
Cryptography is such a non-trivial matter that trying to implement its aspects on your own is nothing but conceit, unless you’re not an expert. The right approach is to use open, industry-standard protocols and algorithms.
- Least privilege possible for components and users;
Be careful when giving permissions to your application and users (even indirectly). Does your application really need access to a file system? Do read operations against a database need to be executed under a higher privileged account?
- Input validation;
Do not feed your system with malformed data. Clearly define the boundaries of valid data and enforce them by whitelisting.
- Promote privacy – limit access to personal data;
The formal definition of private/personal data may differ depending on the local law, while the common feature of private data is direct or indirect possibility to determine the actual person this data belongs to.
- Compartmentalization – make use of processes, containers, and sandboxes to isolate components or even particular operations from each other.
- Defense in depth (all);
- Security by diversity (HTTPS + safe language + data encryption + VPN);
Combine all security mechanisms at your disposal. At the same time, omit using tools out of your competence and find an expert if necessary.
- Use standard and open source solutions (avoid security by obscurity);
Get rid of the idea that proprietary software or protocols (especially your own ones) provide any protection on the ground that nobody knows them. Only publicly available and studied tools and protocols can claim to be secure.
- Monitoring and traceability (prevention/recovery).
- Collect logs, telemetry;
Do not forget to create alarms on dangerous/suspicions events.
- Make backups/snapshots.
Keep them on separate servers and have mechanisms of their recovery.
For sure, it is possible to come up with more principles of that kind, while following the already defined ones should be sufficient in most of the cases.
Secure Development Process
It is quite common to process security issues reactively, deferring them until they become exploited and intolerable, which is a flawed approach.
Secure development process means that necessary activities and practices are introduced for each stage of development:
- Define security requirements (abuse cases);
Abuse case – is the opposite to a use case (or functional requirement). It should explicitly define what a system should not do.
- Define the required security properties of the system components (i.e. Confidentiality, Integrity, Availability);
Explicitly identify what parts of preserved data are confidential. Identify what roles are present in the system and what data they ought to manipulate. Arrange availability requirements.
- Define security mechanisms to support these properties (Authentication, Authorization, Audit);
The presence of these three Au* mechanisms is often regarded as a “Golden Standard of Security”. A system cannot be considered secure if it lacks one of them.
- Define threat models.
This means a necessity to define a malicious actor and possible surfaces of attack (e.g. network traffic, local files, or even displayed data, etc.).
- Threat-driven design (respond to previously defined threat models in the system’s design);
- Architectural risk analysis / assessment (identify potential flaws in design);
- Apply security principles defined above (Prevention, Mitigation, Detection, Recovery).
- Follow the best coding practice and guidelines;
- Conduct mandatory code reviews;
- Apply automation tools to enforce the highest code quality.
I. Static analysis;
III. Concolic execution.
- Risk-based security tests;
These tests aim at the most critical parts of the system, identified by threat modeling.
- Penetration testing;
Security specialists play the role of the perpetrator in an attempt to overcome security mechanisms.
- Fuzz testing;
Feeding the system with random and malformed data may often expose undesired behaviors.
Common Design Flaws and Implementation Defects
When following the secure development process, always keep in mind the fallacies widely committed by developers:
- Assume trust rather than explicitly give it;
- Use an authentication mechanism that can be bypassed;
- Authorize without sufficient context;
- Confuse data and control instructions;
This is exactly the source of notorious SQL Injections, XSS attacks, and Remote code executions.
- Fail to validate data;
- Fail to use cryptography correctly;
- Fail to identify sensitive data;
- Integrate external components without considering their attack surface;
- Rigidly constrain future changes to objects and actors.
OWASP and Top 10 Vulnerabilities
Open Web Application Security Project is a not-for-profit organization focused on improving the security of software. And you can make great use of its resources. This organization provides useful guidelines and “cheat sheets” for popular development platforms like .NET and Java.
OWASP is primarily famous for its “Top Ten” lists describing the most common vulnerabilities in different domains:
It is highly important to be well familiar with the common vulnerabilities of your domain: forewarned is forearmed.
Security for Developers: the Gist
Address security concerns first, do not dare to postpone them till the bitter end. Plan and carry out necessary activities through each phase of development to keep your customers safe and your reputation unquestioned.
I hope you’ll find this article helpful, but keep in mind that it is just a general cheat sheet. Becoming a competent specialist requires a lot of learning and practice.
You necessarily need to invest your time and resources to attend relevant courses or even achieve certification specific to the particular field of your interest.
Alternatively, if you are eager to pass on the burden of security concerns on the shoulders of professionals, you are heartily welcome to contact our highly skilled InfoSec team!
Nikolay is an advanced .NET developer working with Sigma Software for many years. He is passionate about technology and its progress, so Nikolay actively participates in tech community events, acts as a mentor and trainer, competes and takes high places at international Hackathons.