© Giuliana Carullo 2020
G. CarulloImplementing Effective Code Reviewshttps://doi.org/10.1007/978-1-4842-6162-0_10

10. Security

Giuliana Carullo1 
(1)
Dublin, Ireland
 

I never make exceptions. An exception disproves the rule.

—Sherlock Holmes in Sir Arthur Conan Doyle’s “The Sign of Four” (1890)

First things first:

100% secure and reliable code is a unicorn.

I’ve been studying secure unicorns and their habits for a pretty long time. During that time, and as a conclusion of my extensive effort, I figured out that a big part of them are known as procrastinating unicorns whose famous motto is

I’ll think about security later.

In other words, achieving 100% secure code is wanted by everyone, but unfeasible. Every year thousands of vulnerabilities are discovered,1 and the exposure surface is always increasing. Although ensuring secure code also requires proper scans, especially for third-party libraries and the software we use on our infrastructure, at least the basic security principles should not be an afterthought: they need to be an integral part of any development process.

That being said, before dealing with what to check during a code review process, in this chapter, we will cover the security definitions and fundamentals that will walk you through the understanding of basic aspects to look for during a review.

Security Definitions

Figure 10-1 shows some of the main common terms used in the information security world.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig1_HTML.jpg
Figure 10-1

Security definitions

An asset is anything that is valuable for the organization, its business operations, and their continuity, including information resources that support the organization’s mission.2

A risk in the general meaning provided in the project management context is an uncertain event or condition that, if it occurs, may have a positive or negative effect on one or more objectives. It may have one or more causes and it may impact one or more assets. In the context of information security, however, it only refers to negative impacts and it expresses the potential and the relative likelihood that something bad might happen.

Vulnerability and risk can be confused and used with the same meaning. However, the risk is linked to the potential of something bad happening, while the vulnerability is the channel that can be exploited to make the risk real. In other words, a vulnerability is the concrete defect that can be exploited. Vulnerabilities may be related to
  • Software: A security bug in a piece of software is a vulnerability.

  • Hardware: In the physical security context, not properly enforcing restricted access to a server room is considered a vulnerability.

  • Human behavior: Plenty of attacks exist to, for example, gain access to, otherwise confidential, information by exploiting psychological vulnerabilities.

Existing vulnerabilities expose the organization to potential damages.

The possible danger arising from the exploitation of a vulnerability that may result in harm to a system and an organization is called a threat. A threat may be accidental or intentional including
  • Physical damages to facilities like in the case of natural events (e.g., seismic), information being compromised due to eavesdropping and theft—just to name a few.

  • Accidental disclosure of confidential information by a personnel member (e.g., social engineering)

The entity that tries to exploit a vulnerability is usually referred to as a threat agent. The way a system gets compromised is referred to as an exploit.

To mitigate the likelihood of a risk becoming a reality, the organization identifies and put in place countermeasures. Back to our case of a natural disaster happening. A commonly adopted countermeasure is to consider redundancy of data and services across several geographically separated regions. Other examples of countermeasures are encryption, firewalls, security fences, access control mechanisms, and so on.

Security Is Such a PAIN

If you ask two different security people to define information security, they will probably come to you with slightly different answers. This is because security is a very broad and complex area. Anyway, all of them have three universal pillars in common: confidentiality, integrity, and availability. These three properties shown in Figure 10-2 are also commonly known as CIA triad and are typically used to identify weaknesses and to establish security solutions.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig2_HTML.jpg
Figure 10-2

CIA triad

Confidentiality

Confidentiality ensures that only the subjects authorized to access to and use the contents of a message, a transaction, or any other data stored in the system have access to those contents. In other words, confidentiality is closely linked to privacy.

This is, for example, the case of any mailing service you use: the emails you receive need to be visible only to you, the receiver.

Some of the threats to the confidentiality of an information system are due to, for example, intruders, malware, or social engineering attacks.

To keep data and its existence secret is a problem that many organizations face, and they put a significant amount of time and money into it. This is because unauthorized access to confidential data could have a severe impact on the business, not only for critical applications. To this end, it is important to identify and classify data based on the required confidentiality in order to ensure that top priority security assets are adequately protected over time.

Security by Obscurity

Back in the day, people believed that hiding information was enough to consider it confidential. Since the beginning of mathematically sound solutions (given the time period and the technological advances), we finally stepped away from relying on obscurity to keep information secure in most cases. A very well-known practice is given by Kerckhoff’s principle that states that the security of a cryptographic system should not rely on the secrecy of the algorithm, while only keys should remain secret. Since then, security by obscurity is no longer considered a secure enough practice.

Even if different security mechanisms can provide different degrees of confidentiality (availability and integrity), the main prerequisite is to protect confidentiality via cryptography, by encrypting data both at rest and in transit (i.e., moving from one system to another), and access control mechanisms. These activities need to be tracked, audited, and monitored over time.

Integrity

Integrity ensures a message, data, or transaction has not been tampered (i.e., compromised). It encompasses different properties of stored or information including correctness, completeness, consistency, and accuracy. When a security mechanism provides integrity, it prevents improper or unauthorized access and modification of data, or a resource, in a system.

An example of integrity is the case of the balance of your bank account. At any point in time, the balance needs to be correct by means of any transactions (e.g., withdraw and deposit) you legitimately performed.

Maintaining integrity also ensures that any piece of information is internally and externally consistent.

Availability

Availability ensures that information is constantly and readily accessible by authorized users. Protection mechanisms must be in place to protect against both outside and inside threats that could affect the availability of the organization’s assets.

Back to our bank account example. Ensuring availability means that accessing the various banking services should work anytime you need to.

Facts from the World

Availability is generally formalized contractually by means of SLA (service-level agreements). Critical services, like those provided in the telecommunication world, generally strive for at least five-nine availability. This means that services should be available 99.999% of the time. In such a case, the maximum allowed downtime of a service is less than 5 minutes and 26 seconds in every given year.

Typical attacks against availability are denial of service (DoS) attacks and its distributed form DDoS. Anyhow, when dealing with system availability, it should also be taken into account possible power outages as well as risks due to natural disasters (i.e., physical security). Between all, properly implementing redundancy is the very first step into achieving availability.

Non-repudiation

The CIA triad is sometimes also referred to as PAIN, which stands for privacy, availability/authentication, integrity, and non-repudiation.

Non-repudiation means that an action cannot be denied. Any action (e.g., access or modification) is bounded to a unique subject. For instance, this property ensures that after a message is sent, it cannot be disputed if it has been sent or not.

Back to our email example; this means that if a friend sends you an email, they cannot argue whether they sent it or not.

Trade-offs

Implementing the right controls, based on security requirements, is fairly intricate. Trade-offs are made all the time between the various triad aspects. Certain aspects might require priority, but a balance should always be considered. Consider, for example, a scenario where high confidentiality is highly enforced but availability is neglected: in case of an attack, even the subject with the right permission would not be able to access anything.

Back to our banking example, high confidentiality means that the account holder is the only person allowed to access banking services. However, a lack of availability implies that not even the account holder can use services even if they should be allowed to.

Not balancing properly security requirements given the criticality of the offered services, the environment they run into, as well as any legal obligation would cost a lot for the industry, both in terms of money and reputation.

Fact or Fiction?

The adage “think first, then act” applies to coding as well as security. The “think first” is also known as security by design, which means that the software is born as secure. It is designed from the ground up to be secure. Secure is how software is meant to be.

Unfortunately, too often new solutions are built and delivered without dealing with security and privacy issues from time zero. Only later, maybe when some attacks and relative money losses took place, people think how to make their product secure and compliant.

Too many times securing a software seems like distracting from the final goal: releasing the product. Securing any piece of code surely comes with some costs. However, trying to secure an unsecured solution later on during its lifetime is not going to be a viable solution because think about it
  1. 1.

    The business who releases insecure software loses in credibility.

     
  2. 2.

    The business loses money.

     
  3. 3.

    It is so much more difficult to add security features later on in the software lifecycle.

     
  4. 4.

    It is costlier and more time consuming to fix after rather than designing first.

     

It is like you cooked brownies, but you forgot to add chocolate before baking them, right? It is a huge no, no, no!

Security Principles

Now more than ever, when tons of solutions are deployed into the Cloud and we are (almost) all excited by the Internet of Things wave, using the security by design model is mandatory. And, surely, the underlying principles described as follows can be used to assess code during reviews.3

Least Privilege

Least privilege states that any subject should be given the minimum possible privilege on the minimum portion of resources for the minimum amount of time (Figure 10-3). In other words, a user should be given only those privileges which are strictly required to perform its designated task.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig3_HTML.jpg
Figure 10-3

Least privilege

A simple example application is often enforced in physical security: you do not have access to an office unless you need to (e.g., you work for the company who owns/rents that specific office).

Defense in Depth

Defense in depth is about providing multilayer protection: subsequent layer will provide protection if a previous one is breached (Figure 10-4). The reasoning behind this principle is that combining several layers of different types of security mechanisms is the only way to deploy a reasonably secure environment: attackers would need to overcome all the levels of protection that surround the protected assets in order to gain access to it.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig4_HTML.jpg
Figure 10-4

Defense in depth

As an an example, think about a simple multilayered software consisting of an API, some backend computation, and a database. Attempting to secure only the API is insufficient: any circumvention of the API would leave backend and data exposed to possible attacks.

Segregation of Duties

The segregation of duties (SoD) principle states that no person should be given responsibility or access to more than one related function (Figure 10-5). The reasoning behind this principle is that it mitigates the risks arising from accidental or intentional misuse of resources and information.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig5_HTML.jpg
Figure 10-5

Segregation of duties

This is as simple as thinking about the development tools we use every day, git included. Segregation of duties happens when you are granted read/write permissions to the projects your team owns, but you do not have permissions, by default, to the other projects within the company.

Fail Safe

The fail safe principle states that if a system fails, it should fail to a state in which security and data are not compromised (Figure 10-6). It means that the default access rights for any entity to any resource is no access.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig6_HTML.jpg
Figure 10-6

Fail safe

Let’s consider the case of a database. Fail safe, applied to transactions performed on a database, means that if, for example, a write happens to be unsuccessful midway before it is fully performed, the safe state would be
  1. 1.

    No data actually changed.

     
  2. 2.

    Error is signaled and handled accordingly.

     

Back to our banking system. If you attempt to perform a withdrawal, but no money can be released by the ATM, fail safe means that the error is clear and the failure of the withdrawal is reflected by no change into the balance of your checking account.

Complete Mediation

Complete mediation means that every request by a subject to access an object must be authorized, without exceptions (Figure 10-7). Indeed, it applies to every protected or unprotected object in the system. This principle imposes the constraint of identifying every subject attempting to access an object. Thus, it enables a consistent access control of the whole system, thus improving security as well as assurance and confidence.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig7_HTML.jpg
Figure 10-7

Complete mediation

As an example, complete mediation means that you won’t access to any of the data and services (either critical or not) on your laptop unless you authenticated yourself and authorization has been granted.

Least Common Mechanism

The least common mechanism states that a minimum number of protection mechanisms should be common to multiple (i.e., more than one) users, since shared access paths may lead to information leakage (Figure 10-8). In other words, mechanisms to access resources should not be shared.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig8_HTML.jpg
Figure 10-8

Least common mechanism

Consider, for example, two virtual machines, each running a service with a different set of users. Those two virtual machines need to be properly isolated in order to guarantee no leakage from one machine to another.

Weakest Link

The weakest link principle stresses how important it is to identify—and mitigate—the weakest mechanisms in the security chain and layers of defense (Figure 10-9).
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig9_HTML.jpg
Figure 10-9

Weakest link

Generally speaking, the commonly known weakest link is ourselves as humans and the usage we do of a system. Phishing and social engineering attacks are at the order of the day, and there is not much security a system can offer if we willingly, yet unconsciously, volunteer information.

Security Principles Caveats

The described principles do not look like rocket science. However, they are a huge boost in securing any solution. Bad things always happen (Murphy’s law), but I think that—really—starting from the foundations of security principles and software development is the way to go. It does not end there for sure, but they are still underrated nowadays.

Worth noting, however, that any of these fundamental principles can be very complex depending on the technologies used and the context they run into.

As an example, let’s go back to the least common mechanism: isolating virtual machines is not the same as isolating containers that, in turn, is not the same as separating flows within a given service on top of them depending on the specific business logic and usage expectations.

Security Code Review

I strongly suggest to have broader security-specific reviews including
  • Security implication of the used programming language

  • Automation and penetration testing

  • Security architecture reviews

  • Broad checks of the security of third-party libraries the code depends on.

However, some checks can and need to be performed during the development process, even for not-so-mature software. I can’t stress enough how thinking about security earlier in the process can save you from a lot of headaches, as well as and costs and time, later on. Of course we are not talking about 100% secure and reliable code unicorns, remember?

We are speaking about software and products which are secure enough depending on the environment, context, or domain in which they are deployed. Security is such a broad aspect to consider. Hence, this section has trade-offs in mind and will walk through some of the main aspects to look at during code reviews to ensure that at least major flaws are checked.

Secure Software Development Lifecycle

Security code reviews are only a small piece into the secure software development lifecycle (SSDLC).

As anticipated, security should be by design. However, there is much more that goes into a proper SSDLC (Figure 10-10). Specifically
  • Security is a critical piece of any software application and a very complex one. Proper awareness training on the topic is fundamental to the security process and is generally provided by most companies.

  • As we saw, a good understanding of context and environment in which the application operates is fundamental to understand security requirements, implications, and potential risks from the get-go.

  • Always consider security by design.

  • Secure development and testing (reviews performed here as detailed in the following section).

  • It is very important to have an outlined security/incident response plan in place ahead of releasing the code. In other words, it is fundamental to have and know which processes are in place in case an incident happens and who is supposed to resolve it within which time frame.

  • Depending whether code needs to be publicly released or not, extra processes (company specific) are generally in place.

  • Last, but not least, like general code quality, it is important to consider how to maintain security over time.

../images/485619_1_En_10_Chapter/485619_1_En_10_Fig10_HTML.jpg
Figure 10-10

Secure software development lifecycle (SSDLC)

Facts from the World

Companies, especially in heavily regulated environments like healthcare, need to go through auditing processes of their systems to ensure compliance against a multitude of legal regulations that depend on both the sector they work in and their geographical location. We will not provide details about auditing processes in this book since they are generally broader and way more complex than day-to-day software development process for most engineers.

Security Code Reviews

A security code review serves the purpose of ensuring that major inconsistencies and other flows, not already detected, are still looked at. Figure 10-11 shows the software development lifecycle (SDLC) and highlights in which phase security code reviews are usually performed.
../images/485619_1_En_10_Chapter/485619_1_En_10_Fig11_HTML.jpg
Figure 10-11

Security code review

Generally speaking, such reviews focus on finding exposure to potential threats in the areas discussed earlier, that is, availability, confidentiality, and integrity. However, those are pretty broad, since they span across checking for identity and access management, how sessions are managed, data privacy, logging, error handling, confidential information, and encryption, just to mention some.

Automating Security Reviews

Automated code reviews might help a lot in speeding up the review—we love automation, don’t we?

Static application security testing (SAST) tools can be used to support static code analysis and help find security flaws. Generally speaking, they are very useful during the development process, and they are fairly easy to embed during the development phase.

As an example, GitLab CI/CD offers easy integration with SAST (https://docs.gitlab.com/ee/user/application_security/sast/) and can be used to spot both the existence unsafe code that could potentially be used for unintended code execution and XSS attacks.

Note

Plenty of SAST tools exist that can be used depending on the language, your programming environment and preferences. OWASP (https://owasp.org/www-community/Source_Code_Analysis_Tools) provides a fairly comprehensive list of options. Consider adding a SAST tool to your SSDLC.

At the other side of the seesaw, there are manual code reviews that require a good knowledge of the programming language, domain, application, use cases, and—in this case—security as well. They are definitely more complex and time consuming than using automation.

However, some of the aspects like how identities are managed can be better detected via manual reviews. Code scanners can speed up the process, especially if the code base is fairly big. Their use is useful especially as a first pass. Anyway, they may lack context, hence possibly producing both false positives and false negatives. Thus, I encourage you to automatize when possible but still embed manual reviews to ensure as much as possible code quality and security.

Summary

Security code reviews help in finding flaws in the code. But don’t be fooled. You will not spot all of them. Remember that having healthy code is about constant improvements. With security, it is also about constant monitoring. Certain issues are not that easy to detect and code reviews per se surely will not solve them. Monitor data based on the context of your application to discover anomalous behaviors, and if that happens, start to find the root cause.

Especially for security, there is no one size fits them all.

Key takeaways
  • Always consider security by design.

  • Consider the trade-offs and any consequent risk of the software you write.

  • Always consider at least the security implications given by the fundamental principles described in this chapter.

  • Have both manual and automatized reviews and processes in place.

In the next chapter, we will put together the entire code review process and provide guidance on metrics to track and monitor during the review process. Furthermore, we will depict common behavioral issues that can make or break its effectiveness.

Further Reading

Security can’t really be condensed in a couple of readings. To inspect deeper on the foundation of security, the Official (ISC) 2 Guide to the CISSP CBK, 3rd ed. by Steven Hernandez (Auerbach Publications, 2012) is surely not a lightweight read, while an amazing reference. OWASP (https://owasp.org/) also provides a nice guidance on application security.

Review Checklist

Some of the following questions might be excluded depending on the type of software you might be dealing with, but they are meant to be as general as possible to be a good guidance during the review process.
  1. 1.

    Is any sensitive/private/confidential information logged?

     
  2. 2.

    Is any sensitive/private/confidential information disclosed?

     
  3. 3.

    Are audit trails present?

     
  4. 4.

    Are authentication and authorization mechanisms consistently enforced? Are they adequate to the intended security degree wanted?

     
  5. 5.

    Is every access to an object authorized (i.e., complete mediation)?

     
  6. 6.

    Is the least privilege principle enforced?

     
  7. 7.

    Is defense in depth applied?

     
  8. 8.

    Is segregation of duties principle ensured?

     
  9. 9.

    In case of failures, does the system fail safely?

     
  10. 10.

    Is encryption performed? Is it adequate to the security needs?

     
  11. 11.

    Are weak ciphers used?

     
  12. 12.

    Are security keys too small to provide adequate security?

     
  13. 13.

    Are certificates valid?

     
  14. 14.

    Are security keys protected from unauthorized access?

     
  15. 15.

    Are hashing mechanisms used to check for integrity when needed?

     
  16. 16.

    Are security tests in place?

     
  17. 17.

    Which is the weakest link in the security chain? Is it secure enough?

     
  18. 18.

    Are systems secure enough to expose the least attack surface as possible?

     
  19. 19.

    Are all entry points to the system secured?

     
  20. 20.

    Is input validated against well-known attacks (e.g., SQL injection, XSS injection)?

     
  21. 21.

    Does the system plan for failure?

     
  22. 22.

    Is security by obscurity in place instead of proper mechanisms?

     
  23. 23.

    Does the code contain any security bug (also language dependent)?

     
  24. 24.

    Are privacy-enhanced protocols in place when required?

     
  25. 25.

    Are the used protocols tamper resistant?

     
  26. 26.

    Is the code resistant to buffer overflow?

     
  27. 27.

    Is there any hard-coded password?

     
  28. 28.

    Is there any backdoor in the code?

     
  29. 29.

    Is the code compliant with security policies and standards?

     
  30. 30.

    Are security requirements clear?

     
  31. 31.

    Is the team well trained on security?

     
  32. 32.

    Are security response plan and processes in place?

     
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.218.254