Hacking with a Heads Up Display


By David Scrobonia

Security tools are not user friendly. This is a problem in a world where the security community is trying to “push security left” and integrate into development culture. Developers don’t want to use tools that have a poor user experience and add friction to their daily workflows. By ignoring UX, security tools are preventing teams from making their organizations more secure.

The team behind the Zed Attack Proxy (ZAP), a popular OSS attack proxy for testing web apps, worked on addressing this problem with our application. As a result we came up with three takeaways for improving the UX of security tools.

So What’s the Problem?

Let’s walk through using ZAP to scan a web app for vulnerabilities. Our goal is to add the target application to our scope of attack, spider the site to discover all of the pages, and run the active scanner. So we would:

  1. Look in the Site Tree pane of ZAP to find our target (http://localhost:8000 in this case)

  2. Right click on the target and select the “Include in Context” 

  3. This opens a new menu asking you to select an existing context to add our app to scope (or create a new one)

  4. This opens another configuration menu that prompts you to define any regex rules before adding the application to scope 

  5. Now that our app is in scope, we click the target icon to hide other applications from the Site Tree

  6. To start the spider right click on our application and hover over the “Attack” option in this list to expose a sub-context menu

  7. Click the newly exposed “Spider” option to open a configuration menu and press “Start Scan”.

  8. To start an active scan, we again right click on our app and hover over “Attack” to expose a menu

  9. Click “Active Scan” to open a configuration menu and finally press “Start Scan” to begin

Scanning an app with ZAP

Whew! This is not a simple workflow. It requires us to hunt through hidden context-menus, click through several different menus, and assumes that the user understands all of the configuration options. And this is for the most commonly used feature!

While this is not a great experience, ZAP is far from the least usable security tool available. Ask anybody on your security team about their experience with enterprise static analysis tools and they’ll be sure to give you an earful about a product still stuck in a pre-Y2K user interface.  In contrast to these commercial tools, ZAP is free, open source, and maintained by a handful of people working part time. This presents a huge gap in time and money that left us wondering where we should start in order to improve our user experience. To keep our efforts efficient we focused on three things.

3 Ways to Improve the UX of Security Tools

1. Make it Native

When assessing the security of a web app, you're frequently switching between ZAP and your browser. This quickly becomes distracting. Let's look at how we intercept requests with ZAP, another common feature, to see why.

  1. In the browser, navigate and use the feature they want to test

  2. Go back to ZAP to observe the requests that were sent and turn on the “Break” feature to start intercepting messages

  3. Go back to the browser and reuse the feature they wanted to test

  4. Go back to ZAP to see the intercepted message, modify the request, and then press “Continue”

  5. Go back to the app to see if modified request changed the behaviour in the app

  6. Rinse and repeat for as many requests needed to test the feature.

Intercepting HTTP messages with ZAP

Everytime we just want to intercept a request we have to go back and forth between browser and ZAP five times! This may not seem like a lot at first, but considering that you may intercept hundreds of messages testing for vulnerabilities, this becomes a headache.

The problem is that we are constantly changing contexts between ZAP and the native context for testing, the browser. I like to compare this to how a fighter pilot operates a jet. Their native context for flying the plane is looking through the windshield, so all of the important information they need to make decisions is presented on a heads up display (HUD). Imagine trying to survive a dog fight if all of the feedback about altitude, acceleration, and weapons status was only available in a dashboard of knobs and gauges. It would be impossible if you were continually having to monitor a separate context. 

A fighter jet’s HUD efficiently displays information

To provide a natively integrated experience in ZAP, we took inspiration from a fighter jet’s heads up display.

The ZAP Heads Up Display is new UI overlaid on the target page you are testing, providing the functionality of ZAP in the browser.

Intercepting HTTP messages with the HUD

Making this change wasn’t a simple “lift and shift”, however. It required us to get creative with how we approached our design. We knew we didn’t want to implement the HUD as a browser plugin, which would require us to support multiple code bases that were bound to the restrictions of their plugin APIs. Even then we wouldn’t be able to support all browsers. This was a non-starter for a small development team with a global user base that uses a variety of browsers.

Instead of a browser plugin, we leveraged ZAP’s all powerful position as a proxy to inject the HUD into the target application. When ZAP intercepts an HTTP response from a server, it modifies the HTML to include an extra script tag. The source of this script is a javascript file that is served from ZAP. When this script is executed in the web app it adds several iframes to the DOM which make up the components of the ZAP HUD.

ZAP modifies the HTTP responses of the target application

This approach allows us to add the HUD to any target application running in any modern browser. By making the HUD native we’ve created a frictionless experience, which is essential if you want users to adopt your work. 

2. Sacrifice Power for Accessibility

When looking at ZAP there are a lot of powerful features, but where to find and how to access them isn’t immediately intuitive. To access a common feature like “Active Scan” we had to tediously crawl into a context menu, parse a large list, and click through a sub-menu. This inconvenience is multiplied when you consider there are multiple places in the UI you can find new features. To start a scan you can also navigate to the bottom pane, open a new tab, choose the “Active Scan” feature, and proceed through the configuration menus that way. 

Accessing features via context menus

Accessing features via the bottow drawer

Presenting features in multiple places in the UI is disorienting for a new user trying to figure out how to navigate the application. Will the next feature be found by opening a new tab, or will it be found in a sublayer of a context menu?

To address our complex UI we made a trade off - limit features by simplifying their interfaces. We tossed away the ability to configure features upfront, eliminated multiple entry points into features, and forced scattered ZAP features into consistent UX elements. The HUD now presents features as tools, the discrete buttons on either side of the Heads Up Display.

This consistency creates the same experience when using different tools. Now, when a user wants to find more features, they know exactly where to find it - in another tool! 

Remember how complicated the “Include in Context” flow was? Now with HUD tools, all of these features have been built into the “Scope” tool. Simply click tool, select “Add to Scope”, and we’re done! You’re now ready to attack the application. And how would we start spidering the site? You guessed it - click the Spider tool, select “Start Spider”, and it will start to run!

Scanning an app with the HUD

The simplified tools interface does not provide the same level of feature depth that ZAP traditionally provides. We can’t define a scope regex or define the maximum depth of a spider crawl right out of the box. This is the trade off we choose though: to forfeit feature power for accessibility.

There is a lot happening behind the scenes to enable all of the functionality of ZAP within our simpler “tool” interface. To keep the HUD responsive we aren’t loading all of the functionality into the iframes. Instead, the HUD leverages a service worker, a background javascript process similar to a web worker, to handle most of the heavy lifting so the iframes can be lightweight and responsive. Service workers are more privileged than web workers and can persist across multiple page loads, meaning we only have to load our javascript once and keep it tucked away in the background.* The service worker hosts all of tool logic and exposes it to the different UI iframes via the postMessage API, a browser API for inter-window (and cross origin) communication. 

Not all of the functionality of the tools is stored in the service worker, though. Because we’re already running ZAP we make heavy use of its existing features via the ZAP API. ZAP’s API is very thorough and enables developers to run almost the entire application via a simple REST API. The service worker communicates with this API along with a websocket API that streams events captured in ZAP so that the HUD can have live, up to date notifications. 

The Heads Up Display uses several different technologies

A great way to see all of these pieces in motion is with the new “Break” tool. When the Break tool is clicked in the HUD, a postMessage is sent from the UI frame to the service worker where the tool logic is running, which sends an API request to ZAP to start intercepting messages. When the user tries to open a new page ZAP will intercept the message, use the websocket API to notify the service worker that it just intercepted a new message, and then the service worker will notify an iframe to display the intercepted message. 

All of these technologies help to keep the HUD accessible. If a user can’t figure out how to use your software, it doesn’t matter how good it is at solving a problem it won’t be used. 

3. Keep it Flexible

Even with an improved interface for accessing ZAP, we didn’t want to assume how users would interact with the HUD. To prevent locking our users into rigid workflows we made the UI as configurable as possible and made it easy for users to add more functionality to the HUD.

Applications come in all shapes and sizes and we don’t want the HUD’s display to get in the way. To prevent usability issues users can arrange the tools however they like, or remove tools that get in the way. The entire HUD can even be temporarily hidden from view. The ultimate goal is to have a fully customizable drag and drop interface where users can manage the HUD like its the home screen of their smartphone: changing fonts, adding widgets, and changing the layout.

Users can also quickly add features to the HUD, so they aren’t stuck using only the default tools. Developers often have custom testing or build scripts and connecting them to the HUD would make testing that much easier. That's something we can do in just a few minutes using only ZAP.

ZAP has a “Scripts” plugin that allows users to hook custom scripts into various points of the application. Scripts can be used to modify requests or responses, add active scanning rules, or change any other ZAP behaviour. The plugin also provides access to the HUD code, allowing users to quickly copy, paste, and modify the code for an existing tool. By tweaking just a few lines we can create a tool that uses the ZAP API to start running any user defined script: a developer’s custom testing scripts, a QA’s web automation script, or a hacker’s favorite tool.

Users can add custom functionality to the HUD in a few minutes

In the example above we have a script called “Hack it!” that replaces the text “Juice Shop” with “HACKED”. After quickly modifying an existing tool, we change a ZAP API call to enable our defined script, and when we restart the HUD you can see that the new “Hack it!” tool is now available to be added to our display.

Although this is a simple example, the scripting feature can be used to add any functionality to the HUD and supports several different scripting languages.


By focusing on three things we were able to make a powerful security tool much more accessible to a wider audience. By making it native we empower users in the environment their most comfortable in. By sacrificing power for accessibility we enable users of all levels to quickly start security testing. By keeping it flexible our tool adapts to a user’s specific needs.

While these design concepts aren’t revolutionary, or even that original, they highlight a fundamental gap between how the security community talks about security and how we practice security. If we honestly want to “push security left” we must leverage these principles to provide frictionless security for our users. 


The HUD is now in Alpha release! If you would like to test fly the HUD visit https://github.com/zaproxy/zap-hud to get up and running in a few minutes and see how it works. This is still a very early release so it may buggy, but please share your feedback on usability, reliability, and feature requests. If you’re interested in helping out with the project please reach out to us via the Github project or on Twitter at @david_scrobonia or @zaproxy.

* Service worker savvy readers will know that service workers are event driven, and that the lifecycle of a service worker expects them to be constantly terminated and activated, requiring all dependencies to be imported each time this happens. To prevent this we have hacked around this spec by sending the service worker a heart beat to keep it alive while the HUD is active.

The state of personalization 2023

The State of Personalization 2023

Our annual look at how attitudes, preferences, and experiences with personalization have evolved over the past year.

Recommended articles


Want to keep updated on Segment launches, events, and updates?