Avoiding the top 10 security flaws – A report by IEEE Computer Society’s Center for Secure Design (CSD)


Avoiding the top 10 security flaws – A report by IEEE Computer Society’s Center for Secure Design (CSD)

The most common type of defects that come with most softwares are implementation bugs and design flaws. In 2014, the Institute of Electrical and Electronics Engineers (IEEE) Computer Society, the leading association for computing professionals, launched a cyber-security initiative with an aim to make an impact in the field of cyber-security.
The initial step was to launch the IEEE Centre for Secure Design (CSD) and to shift the focus from finding bugs towards design flaws so that developers could learn from mistakes committed earlier in design flaws. Early in 2014, CSD brought people together from different organizations at a workshop to work towards this goal. Participants from the workshop identified the top flaws found in their own internal design review or from external data. Many of the flaws that made the list have been well known for decades, but continue to persist.
Both bugs and flaws are defects in software. A defect may lie dormant in the software and may resurface much later, when the software is fielded, causing great consequences. A bug is an implementation level software problem. It may exist in a code but may never be executed. A flaw, on the other hand, is a problem at a much deeper level. Flaws are often much more subtle than simply an off-by-one error in an array reference or use of an incorrect system call. Flaws appear due to mistake or oversight in the design level of nay software.
Software systems work on the right functioning of its existing parts, which if tampered by an attacker renders the whole system insecure. Exposure to untrustworthy environment leads to compromises and so any data sent from untrusted clients should be considered compromised. It is safer to consider that any systems whose components can’t be trusted are not suitable for performing security sensitive tasks. Security aware development strategies cannot eliminate app problems but can minimize potential risks. Subject matter experts should be consulted if system needs a client component with uncompromised level of protection. Also it needs to be made sure that in case of a threat, the system works in a limited fashion.
Every user who tries to access a system should be authenticated. Authentication is the act of validating an entity’s identity. Secure designs prevent unauthenticated entities from gaining access to systems. Multifactor authentications that rely upon something you know (e.g., a password), something you are (e.g., biometrics such as fingerprints), or something you have (e.g., a smartphone) should be used to authorize sensitive functions. The system should also consider the strength of authentication before taking action. Authenticated users are provided with tickets/tokens to prevent re-authentication. Designers can use time tested mechanisms like Kerebos and use the right cryptography for authentication of credentials. An authenticated interaction should be time limited so that access does not remain open when the user is idle. In all, a single authentication mechanism should leverage one or more factors as per an application’s requirements.
Not every authenticated user is given access to every aspect of the system. This is when authorization is necessary. Authorization should be conducted as an explicit check, and as necessary even after an initial authentication has been completed. Authorization depends not only on the privileges associated with an authenticated user, but also on the context of the request. The time of the request and the location of the requesting user may both need to be taken into account.
Co-mingling data and control instructions in a single entity, especially a string, can lead to injection vulnerabilities. At lower layers, lack of strict segregation between data and control instructions can result in the introduction of memory-corruption vulnerabilities, which permits attacker-controlled modifications of control flow or direct execution of attacker-controlled data as machine or byte-code instructions. At higher levels, co-mingling of control and data often occurs in the context of runtime interpretation of both domain-specific and general-purpose programming languages. Experience has shown that use of injection-prone APIs incurs significant risk that injection vulnerabilities will indeed be introduced. At lower levels, software platforms can utilize hardware capabilities to enforce separation of code and data. Modern operating systems take advantage of such hardware features to implement security mechanisms that harden the entire software stack against multiple forms of attack. Software designs that ignore the principle of strict separation between data and code, or that blur the line that distinguishes one from the other, are inherently less secure because they undermine or directly invalidate low-level security mechanisms.
When designing applications that rely on existing APIs, avoid APIs that mingle data and control information in their parameters, especially when those parameters are strings. If there is no choice in underlying APIs (for example, if the use of a relational database requires interfacing through a SQL query API), it is often desirable to encapsulate the injection-prone interface and expose its functionality to application code through a higher-level API that enforces strict segregation between control statements and potentially untrusted data.
Software systems and components commonly make assumptions about data they operate on. Vulnerabilities frequently arise from implicit assumptions about data, which can be exploited if an attacker can subvert and invalidate these assumptions. It needs to be ensured that all data are explicitly validated. It is furthermore desirable to design software to make it feasible for a security reviewer to effectively and efficiently reason about and verify the correctness and comprehensiveness of data validation. Designing for verifiability should take into account that code typically evolves over time, resulting in the risk that gaps in data validation are introduced in later stages of the software life-cycle.
Cryptography is one of the most important tools for building secure systems and hence it should be used correctly. It ensures the confidentiality of data, protects data from unauthorized modification, and authenticates the source of data. Cryptography is so hard to get right that it always makes sense to work with an expert if you can.
There are many common errors related to cryptography. Designing cryptographic algorithm requires significant skills and even experts produce algorithms with subtle errors. This can leak info to attackers and hence standard algorithms and libraries are preferable. Incorrect assumptions about using library routines or choosing the wrong algorithm leads to faulted cryptography. Understanding the nuances of algorithm and library usage is a core skill for applied cryptographers. Use of weak keys and erroneous key management can also lead to poor cryptography. When cryptographic randomness is confused with statistical randomness, it can again lead to poor cryptography. Care must be taken not to re-use the random numbers.
Data are critical to organizations and to users and hence it is necessary to identify sensitive data and how they should be handled. One of the first tasks that systems designers must do is identify sensitive data and determine how to protect it appropriately. Data sensitivity is context-sensitive. It depends on many factors, including regulation, company policy, contractual obligations, and user expectation. Creating a policy that explicitly identifies different levels of classification is the first step in handling data appropriately. It is important to factor all relevant considerations into the design of a data sensitivity policy. Data sets do not exist only at rest, but in transit between components within a single system and between organizations. As data sets transit between systems, they may cross multiple trust boundaries. Identifying these boundaries and rectifying them with data protection policies is an essential design activity.
Understanding users are of utmost importance while designing software. Almost every software system in existence today interacts in one way or another with human beings, from fielding to end-user. The security stance of a software system is inextricably linked to what its users do with it. It is therefore very important that all security-related mechanisms are designed in a manner that makes it easy to deploy, configure, use, and update the system securely. Usability and user experience considerations are often the most important factors ensuring that software systems operate in a secure manner.
It is important to understand how integrating external components changes your attack surface.  You need to consider how the external components change the threat model of the entire system and if it adds to the attack surface. You also need to consider if it modifies entry points in the system that had already been considered in its own threat model.  Unused features and interfaces needs to be checked for engagement and should be disabled if not being used. These also need to be a check whether the external components used have other external components with their own security weaknesses. It always better to get external components from a trusted source. The external components should also provide security documentation that helps better understand its threat model and security implications of its configuration.
Change is an integral part of software security development. Software, the environments running software, and threats and attacks against software all change over time and hence designers need to consider the security implications of future changes to objects and actors. Security designs should keep flexibility in mind. This includes the provision to have updates that change minor parts of the software to keep it up to date with the changing technological environment, to shut down a specific aspect of the software in case of a threat or external attack, to change algorithms and layers as needed into the system and to revoke access to areas when a user no longer has a need to access them.

Leave your thought here


Recent Courses

Blockchain Course for Managers