The Main Tenets of DevOps: “Infrastructure as Code”
Security in DevOps
At this point, most everyone in the IT industry is aware of the term DevOps or Development Operations. DevOps is a fundamental shift in the way we build, test and deploy our applications and services.
When performed properly, the benefits are many for both the builder and the users of the application. However, as DevOps has increased our delivery velocity, there is a real possibility that security can be left behind. There is some truth to that as traditional security checks and gates can slow the release process down and therefore are often saved for only ‘big releases’.
Infrastructure as Code
One the main tenets of DevOps is “Infrastructure as Code”. This is accomplished by defining your infrastructure (servers, network, storage) in a programming language and via tools that deploy that infrastructure automatically. By doing so, infrastructure can now benefit from software engineering practices like version control, code review, and unit testing.
Building on this theme has been the introduction of “Security as Code”. As expected, this is the automation of security checks and gates via code and integrated into the overall DevOps process again following software engineering practices. Of course, saying it is easier than doing it, so we’ll cover the major points and provide direction.
Even if your application’s release cadence doesn’t require the speed that automation provides, the benefits of consistency and the elimination of manual steps alone can improve security.
Continuous Integration and Continuous Delivery (CI/CD)
Commonly referred as ‘CI/CD’, both are fundamental to integrating Security as Code.
Continuous Integration is a core practice of Agile development where all changes to the code are automatically built and verified allowing problems to be caught quickly. Continuous Delivery builds on this practice and is the automation framework that powers DevOps.
In turn, Security as Code uses Continuous Delivery as its control backbone for automating security and compliance checks.
How do we get started? Just like when first introducing DevOps, there is planning involved before you start modifying your pipelines. To start, you need to understand what your application is potentially vulnerable to.
A common approach is threat modeling to help determine your potential threats, vulnerabilities, and attacks vectors. Time spent here will help inform the security checks that you should be performing as part of the process.
Another key factor is secure coding standards. What are acceptable coding practices (see Pro Tip below), and how will your development team peer review themselves to maintain the standard? What tools can you use as part of your Continuous Delivery to support these standards and practices and alert when deviated from?
Finally, and based heavily on your threat model, what attack simulation do you want to expose your application to. How often and for what type of releases?
Pro Tip: The OWASP Foundation provides many tools and guidance to help developers and organizations with application security. The key initiatives which support designing, developing and deploying secure applications are:
- OWASP ASVS 2.0 is security verification framework to help define security requirements early.
- OWASP Proactive Controls are a set of development practices for creating secure applications.
- OWASP Testing Guidelines provide guidance for creating security test cases.
This includes the development activities leading up to the commit of new source to the source repository and is driven by the developer. Key activities for the developer are:
- Review and update the Threat Model. Does the new code expand the application’s attack surface? What are the potential abuse cases? Are there additional security checks needed because of this change?
- Static Code Analysis (SAST) executed by the developer within their development environment if available. This can catch bugs and security problems early before committing the code giving the quickest possible feedback.
- Peer-review to have a second set (or maybe many sets) of eyes on the code. Does the change follow adopted secure coding standards? Does it introduce a problem the developer missed?
This is the Continuous Integration phase when automated. Here we want to leverage quick analysis to look for problems missed by the developer and give rapid feedback. Important activities are:
- Clean builds (no failures obviously), but also no warnings. Any warnings in builds should be examined and corrected (preferred) or accepted and suppressed on a case by case basis.
- Incremental Static Code Analysis (SAST) of newly committed code with alerts fired for high-risk changes. Beyond alerting, this provides for reporting to review the overall health of the current source branch.
- Unit checks for security. Functional unit checks will already be in place, so these are the additional tests to support checking for vulnerabilities and that proper countermeasures have been coded where needed.
- Code coverage analysis since it’s unlikely 100% of the code base can be covered by unit tests, but monitoring is needed to ensure it as close as possible.
This is often called integration testing where the application is deployed to a fresh test environment using the same deployment automation as production. Ideally most of the functional and integration testing for the application occurs here with automated test scripts. Leveraging that scripting we include here:
- Security smoke tests to catch problems introduced in configuration and deployment.
- Targeted dynamic scanning (DAST). Also based on the threat model this looks specifically at the most vulnerable parts of the application with the highest risk.
- Specific functional and integration security testing will verify for specific abuse cases as defined by the threat model.
- Automated security attacks. There are several tools available that do this. Not specific to the application threat model but check common methods of attack for against various types of applications and services.
- Probably not every time…
- Deep static analysis
- Fuzzing of files, APIs, inter-process communication
- Manual pen testing
The application is working, and it’s secure (or it should be). However, the job of security is never done, and there are important activities here as well.
- Security smoke tests (again) to catch problems introduced in configuration and deployment.
- Checking of runtime asserts via automated monkey testing (invalid inputs)
- Monitoring/feedback of the environment and application. Ensure logging is enabled and working.
- Postmortems of the process. Did anything go wrong? Were security issues found and corrected? How to improve?
- Extra credit…
- Red Teaming. Creating a team (internal or external) to maliciously attack the application or service. Parameters can be defined, but this can provide a real-world view as to how the application would survive if actually attacked.
- Bug bounties. Offering rewards for any security vulnerability found and verified as exploitable. Helps ensure vulnerabilities are reported to you and not sold to cyber criminals.
It was a big and not necessarily easy step for many organizations to introduce DevOps, but most or even all are receiving the benefits from making that leap. Similar benefits are available by introducing Security as Code into your DevOps process.
The good news is adding security into a functioning DevOps Continuous Delivery process is incremental and builds on the same principles and tenants already used. If you are interested in how VerSprite can help integrate security into your DevOps, feel free to contact us to learn more.
We solve unique problems for clients plagued with security noise, limited resources, or costly 3rd party tools that under-deliver. Learn More →