Home > English, work > Using ZAP-proxy and nginx to debug and tamper with HTTP traffic – Emulate timeouts and other unexpected behaviour

Using ZAP-proxy and nginx to debug and tamper with HTTP traffic – Emulate timeouts and other unexpected behaviour

I recently ran into a problem where I was unable to set a proxy in an application. I wanted to use this proxy as a man-in-the-middle proxy to debug an external web service call. I solved this problem by using nginx to redirect the traffic to the proxy. Since 99 out of 100 articles about nginx proxies are about reverse proxies I decided to write about a forward proxy to save you some time and show you some of the features of a man-in-the-middle proxy.

The proxy was of course the Zed Attack Proxy (ZAP for short). Before ZAP I used a tool known as WebScarab on numerous occasions. WebScarab is superseded by ZAP. Both tools are able to show HTTP traffic and tamper with requests/responses. It is also possible to track TLS traffic, but for this article I’ll leave this feature in the ZAP toolbox.

Our application showed some strange errors on long running requests to an external web service. When I tried to redirect the traffic to ZAP (to slow down traffic) I wasn’t able to change the proxy settings (probably because it was abstracted away by the many layers of frameworks in the application). Using the (MacOS) system proxy also was fruitless. I was however able to change the address of the external web service, so I changed the address to an nginx server.

Redirecting traffic to ZAP in nginx

Setting a real HTTP proxy in nginx was a bit of a conundrum since most people on the internet want to use nginx as a reverse proxy. I finally found a stackoverflow post that gave me 90% of the directions. The last 10% I found here.
It is extremely important to have your slashes right. When something doesn’t work as expected: check your slashes first!

Update your nginx configuration (/usr/local/etc/nginx/nginx.conf if you used brew on MacOS) :

server {
	listen					18226;

   location / {
       proxy_set_header Host $host:8226/;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header Request-URI $request_uri;

In this example nginx runs on port 18226 (the number is not important, but it is smart to relate this to the original service you’re calling). 18226 is the port number is you configure in your application. The original web service runs on port 8226, this port is set in the Host header. Note that this header ends with a slash! (Thanks Danny the Flame for saving me a lot of time).
At proxy_pass the address of ZAP is configured. ZAP runs on port 8080 by default (you can change it at settings, local proxy).

The old and new situation are depicted in the diagram below.

When you’re running on MacOS stay away from the hostname localhost in your configurations. I’m still not sure what the problem is, but this hostname doesn’t always work as expected. That’s the reason I use, it should be exactly the same as localhost, but it isn’t.

Setting a breakpoint and editing the request/response in ZAP

For my next experiment I changed the Host header (proxy_set_header Host) to google.com. When ZAP is running and you point your browser to you should be redirected to https://www.google.com. Note that I use http in this example because your browser has some https-tricks which will complicate things for this demo.
When the redirect happens you should see an entry in the history tab in ZAP. When you right click the entry, pick Break… and hit save. ZAP will now detect the url and stops (just like a debugger in an IDE).

Go to again. ZAP now stops at this breakpoint. The first pause at the breakpoint allows you to edit the request, when you hit the play button (the one without the bar in front of it) the edited request is sent and now you can edit the response. In the response change http://www.google.com to http://www.bing.com and hit play again. You will be redirected to the bing site.

Visit Zed Attack Proxy – Intercepting Traffic and Modifying with Breakpoints on YouTube for a more elaborate explanation on how to set a breakpoint.

Other uses for breakpoints

This was of course a simple example. It gets interesting when you edit response codes or break json structures.

Another option when ZAP hits a breakpoint is to do nothing or wait a while to see what happens. This way you can emulate timeouts or slow responses.


ZAP is an enormous toolbox from which I used just a simple screw driver.

A few tips :

  • Be very careful with slashes in nginx
  • Mac users should refrain from using localhost, is a better idea

Be careful when you’re redirecting production traffic through ZAP. You might want to use the upstream module of nginx to partially tap traffic to ZAP.

Categories: English, work Tags: ,
  1. MrErne
    6 February 2019 at 10:23


    How can we do this tricks on HTTPS ?

    Thank you for your answer

    • Jeroen van Wilgenburg
      6 February 2019 at 17:35

      maybe this link will help (search for “If you want to intercept HTTPS traffic” in the article)

  2. MrErne
    6 February 2019 at 18:44

    I know how to use Zap to Intercept HTTPS Trafic. however I want to setup this configuration : http://puu.sh/CIdfL/52119914ea.png
    I need to push to the client my own Certificate
    How I can do that ?

  1. 17 April 2020 at 11:30

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: