Why we need developer tools for security and not security tools for developers
- DevSecOps and shifting left gains
- Developer tools for security
- Does it work in my CI?
- 1. Be fast
- 2. Be simple
- 3. Donât be rude
- 4. Support a test matrix
- 5. Use JUnit as a report format
- 6. Consider SARIF for static analysis
- 7. Have output ready for deep dives
- 8. Be composable (AKA UNIX philosophy)
- 9. Be easy to set up
- 10. Auto-update is magic, but itâs also surprising
- 11. No context switches
- 12. Work on any OS
- 13. Have great documentation
- 14. The pit of success
- 15. Be responsive
- 16. Have that âoh coolâ factor
- IDE integration
- Precommit
- CI
- What about threat modeling?
- Summary
The further down the line we discover a software defectâââthe more it costs to fix and recover from it, whether itâs a bug that leads to visual error like a spacecraft crash or a more day-to-day bug, human error, or plainly scale issues, that leads to a service being down.
Source: Schiaparelli Impact Site on Mars, in Color
In fact, thereâs plenty of research and writing about software bugs, their cost, and their real cost. A few examples you can find here, here and here.
As an industry having to ship software faster and faster each day with limited attention span as a huge, fast moving organismâââit has been a slow realization: with the growth of âsoftware eats the worldâ, software defectsâââand more critically security defectsâââare becoming a bigger problem as well.
Security defects have a unique trait built into themâââthey are always searched for, probed and exploited by an adversaryâââas long as you have something worth exploiting. The cost for a security defect and the probability that the worst-case scenario will actually happen, unlike a traditional software defect, could be very real and unfortunately be very big.
This is why, in a similar effort that was invested to tame software defects, the industry as a whole is looking to tame security defects, or security vulnerabilities at the start of software production and also in the design phases, or for a more popular termâââshifting left security.
Shifting left security means adoption and adaptation of very much the same processes, practices, tools and capabilities that exist in the parallel world of âtraditionalâ software testing and mitigating defects into security testing and mitigating security vulnerabilities.
The big game-changes that we can borrow from the testing world are:
- Understanding developers, developer tools, developer workflow and processes (AKA in the testing world: unit testing, e2e tests, stories, and above all the right tools for that)
- Pushing traditional security processes to the âleftâ of the software production process (AKA: shift left)
- Putting security tools, awareness, and practices in the hands of developers (AKA: empowering developers)
- An org structure to support the radical shift to the left, e.g. DevSecOps (AKA in the testing/agile world: squads, guilds, matrix structure)
DevSecOps and shifting left gains
The premise of DevSecOps and shifting left security is the same: align security with the rest of the software development lifecycle.
The immediate gains of shifting the discovery of security defects left are:
- Detecting and mitigating security issues as early as coding time. This makes it similar to the gains already made in the software testing domain.
- Moving from security as an afterthought to security by-design, getting better feedback at the right time of software creation: design and build phase.
In the general sense, weâve already seen one of the most disruptive changes to our industry alreadyâââthe move from Ops to DevOps.
Developer tools for security
For someone looking to build developer-first security tools, or integrating them, or is through the process of selecting and designing their own solution based on those we need to answer the following:
- How to build or evaluate tools for a developer-first approach? Where do we start?
- Security tools for developers vs developer tools for security? What is the difference?
The criteria or checklist that we need revolves specifically around:
- CIâââwhatâs important to consider in your dev workflows and processes
- Toolingâââhow to evaluate these tools in the context of your dev day to day
- Feedback cycleâââthe other types of feedback cycle opportunity developers might want
- Processesâââor more specifically threat modeling meets dev, meets security experts meets product.
Does it work in my CI?
One of the popular criteria for determining the fit of a security tool to be a developer friendly tool is the question: âdoes it work in my CI?â.
Many security tools have CI integration challenges that stem from their design. A funny viewpoint of this, is where Abhay Bhargav talked about the phenomenon of security tool narcissism -
âRun MY tool, see MY dashboard!â
This self-centric and developer-unfriendly approach inverts control over where you want to exercise your guards. Sometimes developers just want to run a tool. Period.
The fact that you need to fiddle with a UI to accomplish a taskâââdestroys the chances of shifting left security. Want to run a scan? Use the UI. Want to see results? Log into the system. Want quick feedback? Log into the system, see status. These ALL are bothersome, and miss the point of building to the zen of development.
In addition some of these security tools have inherent security design flaws when running against your securely kept assets. Whether itâs at the code analysis stage or deployment stage (such as a building a Docker container ready for deployment), a tool that moves your assets (such as your code) off-perimeter, essentially copying everything to a remote system that doesnât belong to you for the sake of a security analysisâââis painfully dangerous: if you have a security issue (such as exposing sensitive customer data, credit cards, or secrets), it now exists in two physical places, one is yours, and one is stored at a vendor that is not you.### 16 Essentials for building tools for developers
1. Be fast
Many, if not all CI systems meter by the minute , and some of them have OS specific multipliers. Github Actions for example, as of the time of this writingâââbills using 10x times multiplier per minute on macOS than on Linux. If a tool takes a long time to run, it may become ineffective and expensive to run.
CI is all about creating the primary feedback cycle for a team. The major concern is the speed of your feedback cycle for a given team. CI workflows tend to start lean, and as the team and codebase evolve, they become heavy and long running.
When building a CI friendly security tool you think about investing in a technology that can run quickly, and keeping the overall CI times in check.
If you went through this process once or twice in your career of watching a fast CI workflow become dead slowâââyou learned to keep in mind that every additional tool and process affects CI job time.
2. Be simple
Fancy, cryptic, hacker tools exist only in movies. In real life, when we hit a problem we want to understand it in simple terms and fix it in simple term s. This means:
- Textual outputâââno fancy reports
- Point directly to the problem and show me how to fix it (save me from forensics if possible)
- Fancy reports uploaded as artifacts for extra information
- Give me the raw data and give me context
- Donât take too many keys, and donât require privileged access if possible
- Be familiarâââthe way the tool runs in CI should be similar to the way it runs in development
When running in my CI, donât copy my assets off premise, donât phone home without my knowledge, and donât send my data anywhere else.
3. Donât be rude
In addition, donât break my existing security guards such as:
- Dumping CI environment variables by mistake (which might contain sensitive tokens or secrets)
- Donât run with privileges you donât have, werenât given, or donât need
4. Support a test matrix
To support the benefits of such a test matrix, if youâre building or adopting a tool for your CI, it should be able to run on many operating systems, and many architectures (did someone say ARM ?).
CI systems support a test matrix and using it is one of CIâs best values: test the same thing over a matrix of possibilitiesâââquickly. This is exactly the thing a developer cannot do reliably on their machine due to hardware and existing software differences, or wouldnât want to invest time in (I certainly wonât).
5. Use JUnit as a report format
It is almost unbelievable that JUnit test reports are the standard of reporting in all modern CI systems; JUnit being the archetype and workhorse of modern unit testing frameworks, it didnât disappoint here as well.
A tool that behaves well on CI, should be able to output a JUnit format output even though it doesnât really run unit tests. The format is so flexible so that every form of testing can be baked into itâââincluding security testing.
6. Consider SARIF for static analysis
With that said, for security-specific reporting, we now have the relatively new SARIF format for static analysis results (stands for: Static Analysis Results Interchange Format). A rather new but powerful format to generate output for, with the primary consumer at the time of this writingâââGithub.
7. Have output ready for deep dives
A CI system being out of your reach sometimes (such as a cloud CI service) may require a deeper look into a run session. In that case, a tool should be able to output deeper reports, more data so that it can be handled offlineâââfor debugging or understanding the interaction between the CI system, the asset under analysis, and the tool doing the analysis.
When youâve found an issueâââan exit code should exist to signal an error state. Examining exit codes is a basic step in composing processes.
For example, a CI system that uses containers as a virtualization mechanism, might change its base image without your notice or attention, and suddenly things will start breaking in surprising ways.
8. Be composable (AKA UNIX philosophy)
Often youâd want to compose new workflows in your CI. Most CI systems already take into account streaming and exit codes, and so the expectation is that developer and CI friendly tools would behave in an expected way.
9. Be easy to set up
A well-behaving developer tool should have as little dependencies as possible. Ideally it should be a self-contained binary. Even though you can build container images that wrap everything, and you can set up CI processes with all the required dependencies? These break as dependencies shift, as CI systems evolve, and as your code and requirements change. You donât want to be investing time in CI set up every time one of those changes.
10. Auto-update is magic, but itâs also surprising
Donât surprise me. Principle of least surprise in short here:
âPeople are part of the system. The design should match the userâs experience, expectations, and mental modelsâ.
For a developer tool context; one of the utmost concerns is for a tool to be always accessible and behave exactly the same as was the last time youâve used it; given that you use other tools in your toolbox from time to time (but not all the time).
An old flag is missing in the new release, or it breaks because a feature was removed. Or even, try to use it and it now decides to auto-updateâââand youâre staring at your screen now (looking at you, Windows!). This all impairs productivity, which if you take any given developer time-stress these daysâââis already impaired by the fatigue of the likes of Slack, email, JIRA, information overload, tech complexity, bad project management, and more.
PS: This excludes the special and important case of critical updates and security updatesâââwhich in any case, I expect to be transparent, non-breaking, non-removing and non-surprising updates.
11. No context switches
Donât force me to use a UI to perform an action on my way to getting my job done. Put these steps in the tool, in the CLI (e.g. register, login, authenticate, main value, reporting).
Imagine if you wanted to publish a package on NPM, but to do that you had to leave your terminal, go to your browser, log in, copy some kind of token back, set up a configuration file, and then get back to publishing; just to realize its the wrong account youâve logged into on your browser because you have your non-work profile there.
Nope. You log in through your tool that youâre using and all that happens automatically. Donât force me to use a UI meansâââdonât force me to context switch in any case on the way to getting value from your tool.
An exception in this case would be an MFA login, which by-design forces you to add another factor and then possibly context switch to your phone or any other form of authenticator that you might have.
12. Work on any OS
Support all operating systems. I donât want to set up a VM for you, I donât want to run in docker. Cross compilation is easy and cheapâââyou just have to pick the right programming language for it.
Have great docs for your tool, in addition to having great docs for your product.
Some tools and programming language cargo cult their platform gaps. Whether itâs tools that rose to fame on Windows (SDR, Software Defined Radio tools have their best version only on Windows), or on Linux. As a developer, Iâm using all these platforms with the primary one being my mac.
Itâs not uncommon for my best tools to go with me everywhere; the tools I highly appreciateâââIâll use on my mac, Linux and Windows development workflows.
13. Have great documentation
Developer documentation should have a product manager too (that might be you). The times of man-pages and âdryâ docs are gone. Treat your docs like a product, and use JTBD to gather requirements for it. If you use this same model, youâll realize that you want code samples in your docs, and troubleshooting advice in the same paragraph.
When youâre authoring docs to display everything youâve got, as opposed to letting someone perform a given task with the help of the text youâre just writing nowâââit makes a whole lot of difference.
14. The pit of success
When Iâm not in the mood for reading the docs, tell me whatâs the right next step in the CLI itself. Also -help should do what you would expect.
The pit of success principle means, that if iâve learned to do the first step with your tool, this step should teach me whatâs the next reasonable step to perform. A tool should not only do a certain job, but it also has the role of an educator; such an educator that I get only the right information, on the right time.
15. Be responsive
Nielsen has put 3 important limits for usability engineering:
0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.
1.0 second is about the limit for the userâs flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data.
10 seconds is about the limit for keeping the userâs attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.
Out of which, with developer tools, you want to adopt the 100ms of UI responsiveness limit. Where it is not only critical in graphical interfaces, but it is also important in the much neglected realm of developersâââthe terminal.
Thereâs no denying that when you use a fast tool it makes this fuzzy impression on you that you want to keep it. Speaking of fuzzyâââfzf is such a great example (no pun intended), itâs one of the fastest fuzzy searching tools that I keep using as a replacement for the standard history feature in shells.
Startup time makes a difference, and run time makes a difference. You canât use Java for CLI tools; you canât bring up a mammoth VM for a quick ride (not counting GraalVM and latest Leyden), and then it may not even get to JITting at all.
16. Have that âoh coolâ factor
- Teach me things I donât know
- Work well with my existing tools. Install via Homebrew, integrate with Husky, work well with Vim.
- No set up ceremoniesâââno âwhat did I do wrongâ after install
- Have somewhere I can complain, and be listening and responsive to my complaints### The various speeds of feedback cycles
Developers have a few places to get great, fast feedback; choosing which to use depends heavily on the nature of the analysis we want to do, and if the security tool can allow running under that specific context (some security tools canât run on a dev machine because theyâre too heavy).
Common to the different feedback cycles and their speed, is the following:
- Speedââfeedback must reach me quickly, in order to maintain my productivity, also it must not disrupt others
- Correctnessââthe feedback must be correct. Many times for security tools this means false positive and the handling of it
- Actionableââfeedback must be actionable. For security tools this should be a clear explanation of the issue and its mitigation as well as education.
IDE integration
This would seem as the fastest feedback cycle a developer can have. Sometimes it isâââyou get errors as you type, and indeed many code linters, which are a different type of analyzers do this. Some other times, this might be something we need to skip in favor of a bit slower feedback cycle; most commonly when someone is working and the work isnât âdoneâ yet. In other wordsââââI know Iâm not ready, please donât bother me, clippyâ.
In this case, itâs more appropriate to approach the feedback cycle just as youâd approach development unit tests. In the same way unit tests run, you can run security tools.
Only one big deal requirement hereââârun fast. This may become a big requirement for current generation tools based on heavy AST data flow analysis, and for some an impossible requirement as it may take these hours to complete a run. Even a few minutes may be too much.
Precommit
Other than unit tests, there is the staging step. In this step developers are reviewing their work and ready to stage the work into a codebase to be shared with others. In this staging step, we can use a git-hook. A pre-commit hook will trigger evaluation of the material thatâs about to be committed and possibly block a commit if there is a violation.
CI
This about ends the story on the developer machine. The next step is to create a feedback cycle on the CI system itself. Weâre in the developer realm but it also means such a given feedback cycle is now in theâââseveral minutes toâââtens of minutes time frame -.
Weâre also taking two new risks:
- A security risk where a material we have may end up in foreign-owned central store (e.g. credit cards)
- A productivity risk where weâre competing with time shares from the CI system, and from fellow engineers to review our work manually, or to block other peopleâs work if the branching model is such that work in various stages can block others (dev branch, but no PR branches or no concept of âPR reviewâ, for example)
What about threat modeling?
Whatever tool youâre running in your pipeline now, it should correlate with some concept of threat, and be able to assist in risk mitigation and its prioritization.
Does this now mean that threat modeling becomes a bottleneck? If everything runs super fast, tools are being a great citizen in your CI and developer endpoints and deliver great security value.
The answer is yes and no. Just like when software moved to BDD and TDD, and away from âQA on productionâ, and later ops moved to infrastructure as code (and still is moving) and away from âclick to bring up a clusterâ, a few roles became overloaded, and a few years-old processes needed a refresh or were killed altogether.
Source: https://hangoutagile.com/popular-agile-methodologies-wave-1/
Aligning security processes with the TDD movement, as well as with the IaC movement, and cloud-native movement.
There is a trend hereâââas software understanding improves, weâre able to create more software that pushes production and design of software to the natural place that it should live inâââlike any other form of engineeringâââdesign stage.
Because we donât experience âwasteâ in software engineering, other than the ever-illusive loss of time, weâve never been really keen on pushing this so strongly. Compare that to a carpenter that keeps building furniture but never measures, delivers a cabinet just to see itâs crooked, and then goes back to rebuild, throwing away a lot of woodâââthis person sees the material being wasted.
In fact, itâs inevitable that this role of the threat-modeler is going to move to be strained. Therefore it has to align with some kind of more agile process; as critics of STRIDE already sawâââwe need some common sense for where and how to apply threat modeling.
And so, as you shape up your developer tools for security, you need to do the same for your developer processes for security.
- Run a threat modeling session in pre-planning, like you perform all other risk-assessment activities (capacity planning, architecture and others)
- Bring up and document evil user stories (or â misuse casesâ or â abuser storiesâ) to serve as the working cases
- For a more systematic approach for developing these stories (and of course based on the effort you can invest)âââpick STRIDE or Wardly models to guide you through a complex and risky system
- Tracking and applying these stories is a different kind of thing: some people go to extremes and use gherkin to write, track, and (possibly) execute these, with an ode to BDD. However, it does require a significant investment with tooling and techniques to run efficiently and properly; and again it goes back to developer tools for security (ever ran Zap as a part of a pipeline and had to automate UI? how did you deal with crashes?)
Summary
Some great open source developer-first and CI friendly security tooling that you should check:
- TellerâââSecret management for developers and production workflows (which we made!)
- tfsecâââSecurity scanner for your Terraform code (which we sponsor and love!)
- kube-scoreâââKubernetes object analysis with recommendations for improved reliability and security
- Clairâââvery familiar and in use by many other security toolsâââstatic analysis for containers
- gosecâââsecurity checker for Golang
And a few takeaways if youâre planning on integrating or building developer-friendly security tools:
- For every security tool that you know, there is probably another emerging tool that takes a developer-first approach. If not that, you can at least make sure it has features that allow you to build a developer-first pipeline with the existing tools today. You should now know what to look for.
- Identify your existing processes, know that once you shift-left some of them might start becoming bottlenecks. Itâs a good time to experiment with lean and agile processes for your security planning too (e.g. threat modeling)
- If you intend to build tools for your pipeline, you know now what kind of trade-offs to take, and what to do and what not to do.Originally published at https://spectralops.io on April 19, 2021.