by Phil Martin
The Benefits of Identity Management
In summary, we can list the following benefits delivered by using an identity management solution:
Identification, authentication and authorization policies are consistently automated
Identities are de-provisioned to avoid them from hanging around; this in turn provides protection against an attacker using an ex-employee’s credentials to gain access
Unauthorized access to resources by a user or application is mitigated
Provides auditing and reporting capabilities to meet compliance requirements
A common security architecture is leveraged across all applications
Credential Management
When performing identification and authentication, a set of credentials must be provided before access to a system should be granted. Those credentials must be stored somewhere, and is sometimes called a claim. While usernames and passwords are the most common form of credentials, other forms are just as applicable such as tokens, fingerprints, or face and retinal patterns. The process of managing credentials is an important topic and includes credential generation, storage, synchronization, reset capabilities and revocation. Since they are the most common, let’s cover passwords, certificates and SSO technologies in a little more depth.
Password Management
First of all, let’s cover some basic best practices for passwords.
Passwords for new accounts should be automatically generated using a truly random algorithm.
Users should be required to change passwords for new accounts on the first authentication.
Never allow blank passwords.
Do not allow users to use dictionary words as these can be easily discovered using brute force attacks.
Require passwords using at least three of four characters sets – lowercase alphabetic, uppercase alphabetic, numerical and symbols.
Pass phrases are more secure and easier to remember than passwords, but they must be reasonably long – 12 characters or more – to ensure sufficient strength.
Never hardcode passwords in-line or in scripts.
Never encrypt passwords – use a one-way hashing algorithm such as SHA-2 or better before storing them
Require users to provide the current password before changing to a new password
If a question and answer mechanism is used to verify identity when changing a password, always allow the user to enter a custom answer, not pick from a list. Ideally allow the user to type in their own question as well.
An out-of-band mechanism to verify identity is preferred over a question/answer process. For example, emailing a unique, one-time URL to the email address of record ensures that the user has access to the email account. Sending an SMS message to a phone can also improve security during this process.
Ensure passwords have an expiration date.
Do not allow users to reuse a previous password until a pre-specified time has elapsed, preferably one year.
LDAP mechanisms can help keep password changes in-synch among multiple systems, and it allows a single password policy to be implemented for all systems.
Single Sign On
The best place to put identification and authentication is at a common layer such as the network or the OS. Unfortunately, the reality is that most applications require their own credentials and the typical user is left having to memorize multiple passwords. The inevitable result is that passwords are written down somewhere just waiting for someone to steal them.
To address this problem, the concept of a single-sign-on capability was developed in which the user authenticates once, and thereafter each application he or she accesses uses the credentials already entered. In short, the user signs-on a single time, which is abbreviated as SSO.
The system that a user authenticates into using SSO credentials is called the primary domain, with all other systems referred to as secondary domains. While this sounds like a great solution – and it is when implemented properly – it is extremely difficult and expensive to put into place since each application behaves just a little bit differently.
SSO provides four distinct advantages:
Multiple passwords are no longer required, resulting in an increased chance that each user will choose a stronger password.
It becomes much easier to manage accounts and authorization across the enterprise.
Resetting forgotten passwords becomes much easier.
The time it takes to log into multiple applications is greatly reduced.
On the downside, besides being very expensive SSO reduces reliability by introducing a single point of failure, and support for all major OSs is spotty at best, often requiring multiple solutions.
One of the most common implementations for SSO revolves around a protocol called Kerberos. It was originally developed in the 1980s and is currently implemented on all major OSs, and many commercial non-OS products implement it as well. The primary component in Kerberos are the principals – users and servers. The whole idea of Kerberos is that principals don’t trust each other, but everyone trusts Kerberos. So, if Kerberos says ‘Hey, I know this guy can be trusted, and since you trust me, you should trust this guy too’ then everyone gets along. It’s actually a LOT more complex than that, but for the purposes of this book, this description is good enough.
SSO can also be implemented for browsers using something called the security assertion markup language, or SAML. SAML is based on XML and allows a user to share their credentials among multiple web sites.
Until SAML 2.0 burst onto the scene, companies using federated identities had to work with three primary protocols – OASIS SAML 1.0, Liberty Alliance ID-FF 1.1/1.2, and Shibboleth.
OASIS SAML dealt with business-to-business relationships, while Liberty focused on the business-to-consumer aspect and Shibboleth addressed the need for anonymity for educational institutions when being part of a federation. The Fast Identity Online alliance, or FIDO alliance, is dedicated to removing this complexity.
SAML 2.0 helps with this by removing the need to negotiate, map and translate the various protocols. Because it is an open standard for a web-based, SSO service, it holds great promise.
SSO is difficult to implement as both the application that performs authentication and the application that will accept the credentials must establish a high level of trust. However, it removes a great deal of human error and is usually worth the effort. Another challenge that SSO might introduce it that it can be a single point of failure. Beyond the impact if availability is compromised, the theft of a single set of credentials can result in breaches across multiple systems. And let’s not forget that any SSO implementation is costly and resource-intensive.
Flow Control
Controlling the flow of information between two systems with differing level of trust or access will always be challenging. The technologies we can use to control this flow are primarily made up of firewalls, proxies, middleware, and queues. We have already covered firewalls and proxies extensively, so let’s talk about middleware and queuing.
Middleware is software that acts as the glue between multiple software components by facilitating communication and data flow. Since middleware sits squarely in the middle of the pipeline, it represents a single point of failure.
Think of an executive assistant who passes phone calls and visitors directly to an executive without screening them or making appointments. The executive will quickly get overwhelmed and eventually experience a breakdown from the stress. Instead, the assistant should make note of who wants what, prioritize each, and feed the meetings to the executive one at a time, with the most important scheduled first. That is exactly what a queue does, acting as the executive assistant for the processes that take care of requests. The queue will forward on requests in real time if the external process can handle them, but when too many requests are received, instead of simply dropping them the queue will store them up and forward them to the process when the process becomes available.
This has the effect of:
Preventing processes from becoming overloaded and failing
Prevents messages from being lost
Allows a system to scale properly
The most well-known queuing mechanisms include Microsoft Message Queuing, or MSMQ, Oracle Advanced Queuing, or AQ, and IBM MQ Series.
Code Analysis
Code analysis is the process of inspecting code for both quality and weaknesses that can be exploited. There are two approaches to this – static code analysis and dynamic code analysis. The primary difference is that a static analysis looks at the code as it exists in files, whether it is clear text, byte code or object code. A dynamic analysis looks at the program as it is executing in real-time.
As we stated, a static code analysis inspects code without executing it. This can be carried out manually through a code review or automatically using various scanning tools. The type of automated tool used depends on the state of the code, but all usually use pattern matching against a known list of vulnerability syntax and data patterns to detect vulnerabilities.
A source code analyzer looks at source code, while a bytecode scanner looks at bytecode. A binary code scanner or a binary analyzer looks at object code but first disassembles the binary files before carrying out pattern matching. The nice thing about a binary code scanner is that it can detect vulnerabilities and code inefficiencies introduced by the compiler itself, since it examines the result of the compilation process. Both source code analyzers and bytecode scanners look at sources before the compiler has completed its duties.
Think of getting ready to go jogging by putting on a brand-new pair of shoes. You can perform a static analysis by checking for a good fit and making sure the laces are tied properly, but until you get out and start running, only a dynamic analysis carried out at a full run will show you that one foot is quickly developing a blister. In the same manner, a dynamic code analysis inspects code as it is being executed and ensures that a program runs as expected without run-time errors and does not expose weaknesses that could be exploited. This will require a simulated environment that mirrors the production environment, or at least the results of the dynamic analysis can be extrapolated to the production environment.
Each approach has its own pros and cons. A static analysis can show errors and vulnerabilities early in the life cycle and can be addressed before deployment. Static analysis capabilities are often built into the integrated development environment, or IDE, and help to provide immediate feedback to the development team. A static approach does not require an actual environment to be executed in such as needed for a dynamic analysis. On the other hand, automated static tools often generate a huge number of false positives and negatives.
As a case in point, I once ran a static code analysis
using a third-party tool that generated approximately 250 vulnerabilities. After examining each reported issue in-depth, it turned out that only four issues were real. The exercise was still valuable though, as those four issues would have otherwise remained hidden. Just don’t expect to trust the raw output of such tools.
The dynamic approach is more expensive as it requires a dedicated environment for the duration of the test, and the testing tools can be quite expensive.
However, they will be able to detect real problems, and the false negatives and positives will be quite lower than a static code analysis. Furthermore, the problems a dynamic analysis will uncover are very actionable and will more than likely surface if not proactively detected.
Chapter 40: The Engineering Management Role
The best engineering managers have a strong grasp of technology and in fact used to be developers themselves before moving into the management track. But, just because someone is a good developer does NOT make then a good manager. I have seen many great developers turned into quivering masses of ruined brain matter after making the decision to try out management. It is very true that it will be hard for an engineering manager to gain the respect of a development team if he or she does not understand the more technical nuances of software development.
The reason the engineering manager role is crucial is that the processes surrounding development must be paid attention to and championed. Development teams will not have the power to enact change, architects need to spend their time on driving proper implementation, and project managers will not understand the technical underpinnings of the software. Only the engineering manager who is fully-equipped and versed in technology but understands the importance of process will be successful in this area.
Versioning, or Configuration Management
Software assurance occurs when we can deliver secure software using a combination of processes and technologies. To achieve, it takes skilled and trained people who understand how to design, develop and deploy secure software. We can break the processes down into three areas – versioning, analysis and reviews. Analysis (both static and dynamic) is covered in the Architect role, while code reviews are covered under the Developer role. But versioning is very process-dependent, and only an engineering manager will have both the understanding and authority to ensure it is carried out properly.
If your project is not using some type of source code repository that tracks changes, just stop what you are doing and fix it. There’s no point in continuing to code until you can get a handle on code versioning, as you will only frustrate both your developers and the customer.
Versioning happens when a source code repository groups multiple files into a single version. There are four primary benefits to using such a configuration management tool – change tracking, rollback, preventing regenerative bugs, and calculating RASQ.
Configuration management allows developers to check-in source code files as each is created. When modifications are required, the developer must request a file lock on the source code file before changes may be made by executing a check-out, followed by another check-in when completed. Some systems allow the developer to perform a reserved check-out, in which the system flags the file as being ‘worked on’ but allows other developers to ‘work on’ the same file simultaneously. When reserved files are checked back in, a merge is carried out that reconciles changes made by multiple developers. By keeping track of each and every change to all files, the system provides a complete history of who made what change and when. Whenever a bug or malicious change is detected, we can then go back in time and find out who the culprit was. This feature is called change tracking.
Because configuration management allows us to collect all files at a given date and time and ‘tag’ them as belonging to a ‘version’, we can rollback to a previous version at any time we wish. Say we release version 2.3.1 to production, and then start working on 2.3.2. Two weeks later we discover a really nasty bug in the production environment. Without version control, we would have to fix the issue in our code that now has two weeks of additional, untested changes, resulting in a ‘fix’ that in reality breaks five other things. But since we have version control, one developer simply rolls back his copy of the source code to 2.3.1, makes the fix, and after successful testing deploys to production. He then reloads 2.3.2 on his desktop and continues working. If we happen to release a version that turns out to be particularly buggy, we can use this same capability to rollback the production environment to a previous stable release.
Version management also allows us to avoid regenerative bugs. A regenerative bug is a defect that is fixed in one release but appears to become broken again in the next release. In reality it did not ‘get broken’ again, we simply deployed the compiled source code before the fix was applied in subsequent versions. This is a direct result of not being able to manage the versions of source code files. Using our previous example, the developer fixed the 2.3.1 version, checked it back in, deployed to production, and then continued working on 2.3.2. When 2.3.2 is rolled out, guess what happens to his bug fix? It ‘disappears’ because the fix was never included in the 2.3.2 version of code. Version management avoids this by requi
ring that the same 2.3.1 fix be automatically merged into 2.3.2 when it is checked in. This is a simplification of the actual process, but it works through the magic of branching and hot fixes, which is outside the scope of this book.
One last advantage that versioning, or configuration management, provides is the ability to establish a RASQ for any given build. If we do not have the capability to properly define what a version consists of, then a RASQ will be meaningless. Versioning allows us to calculate a RASQ for a given version at any time, even after one has been deployed.
Figure 117: Software Lifecycle Stakeholders
Secure Software Implementation/Coding
Security is not solely the developer’s responsibility. Everyone involved in the project must contribute before software or a system can be magically awarded the ‘secure’ label. Ultimately the entire organization will be blamed for producing an insecure product. There are up to 13 unique stakeholders involved in any given project as shown in Figure 117.
In no particular order, they are:
Top management
Business unit heads
IT manager
Security specialists
Application owners
Developers
Project managers and team leads
Technical architects
QA managers
Business analysts
Industry group delivery heads
Client-side project management
Auditors
Why is this subject brought up as part of the Engineering manager role? Because the engineering manager will be one of the few people in a position to ensure that all stakeholders are being represented. While it should be the responsibility of Product or Project to make sure that all stakeholders have been contacted and are actively working on the project, the reality is that often the engineering manager is the first one to notice gaps forming between