Redirects causing duplicate alerts when scanning an API

179 views
Skip to first unread message

Cameron Swords

unread,
Apr 2, 2020, 1:47:26 AM4/2/20
to OWASP ZAP User Group

Hi, 

I've noticed a problem with ZAP handling redirects on the API scan.

WARN-NEW: PII Disclosure [10062] x 3 

http://192.168.1.105/ (200 OK)

http://192.168.1.105/v1 (200 OK)

http://192.168.1.105/v1/trees (200 OK)


Requesting the / and /v1 URLS above using a HTTP GET actually returns a 302 Moved Temporarily, not a 200 OK as indicated by ZAP. The /v1/trees response has a credit card number on it (hence the alert), and is the only URL that returns a 200 OK. I have verified this using Wireshark.

This is causing duplicate alerts.

Has anyone else seen this, or does anyone have any recommendations?

This can be reproduced using the following steps:
  1. Download the files attached to this issue (nginx.conf, open-api-v2.json)
  2. Replace the host in the OpenAPI spec with your IP Address
  3. Start the API server docker run --rm -v "$PWD/nginx.conf":"/etc/nginx/conf.d/default.conf" -p 80:80 -d nginx:1.17.6-alpine
  4. Run a ZAP Scan docker run -ti -v "$PWD:/zap/wrk" --rm owasp/zap2docker-weekly:w2020-02-17 /zap/zap-api-scan.py -t open-api-v2.json -f openapi
Cheers
Cam
nginx.conf
open-api-v2.json

kingthorin+owaspzap

unread,
Apr 2, 2020, 5:01:32 AM4/2/20
to OWASP ZAP User Group
If they're different URLs that have responded 200 then they're different results.

Cameron Swords

unread,
Apr 2, 2020, 7:53:24 AM4/2/20
to OWASP ZAP User Group


Hi kingthorn,

Thanks for your reply.

I understand that different URLs that return 200 are different results, however I'm talking about URLs that return 302, and redirect:

Wireshark
No. Time      Source        Destination   Protocol Length Info
27  12.187973 192.168.1.105 192.168.1.105 HTTP     262    GET / HTTP/1.1 
29  12.189453 192.168.1.105 192.168.1.105 HTTP     399    HTTP/1.1 302 Moved Temporarily  (text/html)
31  12.195820 192.168.1.105 192.168.1.105 HTTP     264    GET /v1 HTTP/1.1 
33  12.196834 192.168.1.105 192.168.1.105 HTTP     405    HTTP/1.1 302 Moved Temporarily  (text/html)
35  12.199113 192.168.1.105 192.168.1.105 HTTP     270    GET /v1/trees HTTP/1.1 
37  12.200094 192.168.1.105 192.168.1.105 HTTP     428    HTTP/1.1 200 OK  (application/json)
... (other requests omitted, no / or /v1 requests return 200)


If /v1/trees has an alert, would you also expect an alert for / and /v1?

When you say URLs that "responded 200", I don't know whether you're automatically following redirects or not.

Cheers
Cam

kingthorin+owaspzap

unread,
Apr 2, 2020, 10:29:54 AM4/2/20
to OWASP ZAP User Group
The WII scanner is passive so it's looking at the response content. Redirect responses "shouldn't" have content but that isn't always true.

In wireshark look at the actual content of the traffic, the ZAP alerts should also list the specific strings that are being picked up.

kingthorin+owaspzap

unread,
Apr 2, 2020, 10:30:07 AM4/2/20
to OWASP ZAP User Group
*PII

Cameron Swords

unread,
Apr 2, 2020, 6:38:30 PM4/2/20
to OWASP ZAP User Group

Fair point, I've had a look at the response body content.

The redirects for URLs /, /v1 are simple NGINX rewrites, and have the following response body:

<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.17.6</center>
</body>
</html>

If I export the JSON report, you can see the evidence for these redirect URLs contains a credit card. The credit card is actually returned in the response body of /v1/trees.

{
  "pluginid": "10062",
  "alert": "PII Disclosure",
  "name": "PII Disclosure",
  "riskcode": "3",
  "confidence": "3",
  "riskdesc": "High (High)",
  "desc": "<p>The response contains Personally Identifiable Information, such as CC number, SSN and similar sensitive data.<\/p>",
  "instances": [
    {
      "method": "GET",
      "evidence": "378282246310005"
    },
    {
      "uri": "http://192.168.1.105/",
      "method": "GET",
      "evidence": "378282246310005"
    },
    {
      "uri": "http://192.168.1.105/v1",
      "method": "GET",
      "evidence": "378282246310005"
    }
  ],
  "count": "3",
  "solution": "<p><\/p>",
  "otherinfo": "<p>Credit Card Type detected: American Express<\/p>",
  "reference": "<p><\/p>",
  "cweid": "359",
  "wascid": "13",
  "sourceid": "3"
}

Do you see what I'm getting at? I'm trying to establish whether this behaviour is intended. To me, it looks like a duplicate finding, but maybe there are use cases that make this behaviour worthwhile.

Cheers
Cam




On Friday, April 3, 2020 at 1:30:07 AM UTC+11, kingthorin+owaspzap wrote:
*PII

kingthorin+owaspzap

unread,
Apr 2, 2020, 8:50:52 PM4/2/20
to OWASP ZAP User Group
Can you provide the full scenario from original request through 2 (or 3) redirects to completion so that we can mock it up? Or, are you able to mock it up and send us source of some sort (php/python is likely most portable)?

kingthorin+owaspzap

unread,
Apr 2, 2020, 9:45:56 PM4/2/20
to OWASP ZAP User Group
I've tried to create this.

I made a php pages that takes one get parameter and passes redirects to another page (including the param) where it is echoed in the response body. It only alerts on the second page.
I then modified the first page to set a cookie with the value and still redirect and echo on the second page. It only alerts on the second page.
I then modified the first page to redirect, set a cookie, and echo the value to the 302 body while still redirecting. It then alerted on both pages (URLs).

You'll probably need to recreate the issue in the GUI or access the details via the API so that you can get the exact responses that ZAP is alerting on. (Note if you recreate via the GUI depending on the exact details the highlight could be incorrect as it highlights first occurrence in the response, which may not necessarily be the actual occurrence causing the alert so make sure you review fully.)

Cameron Swords

unread,
Apr 2, 2020, 10:39:34 PM4/2/20
to OWASP ZAP User Group

Thanks kingthorin.

Can you provide the full scenario from original request through 2 (or 3) redirects to completion so that we can mock it up? 

The example steps in my first message completely reproduces the scenario, as the NGINX conf contains all of the canned redirects and responses.

I've tried to create this.

Thanks for trying. I should say that when running similar scenarios using zap-baseline.py I had no redirect issues, I've only seen this with API scans. I haven't been able to reproduce this on my ZAP GUI, because for some reason I'm missing a bunch of passive scan rules (even though I have version 27.0.0 of the rules installed)  ¯\_(ツ)_/¯


No stress, just highlighting a potential issue. I might get a chance to look at this again sometime soon.

Cheers
Cam

kingthorin+owaspzap

unread,
Apr 3, 2020, 12:14:38 PM4/3/20
to OWASP ZAP User Group
The detail I'm missing from your scenario is what starts the process an API get? Post? Is the CC param passed along in the requests, if so how?

If you're using the default install of ZAP you'll only have release status passive and active rules, hit up the marketplace (3 colored cubes icon on the main toolbar) for the beta and alpha packages.

Cameron Swords

unread,
Apr 3, 2020, 8:23:35 PM4/3/20
to OWASP ZAP User Group

what starts the process an API get? Post? Is the CC param passed along in the requests, if so how?

The URLs / and /v1 are defined in the OpenAPI specification to return 302 responses. When the specification is imported, ZAP parses the file and extracts URLs. After import, the URLs are passively scanned, and the ZAP alerts are created. 

The URLs are GETs in the specification, and this is the kind of request ZAP makes. I'm not sure what you mean by CC param?



hit up the marketplace ... for the beta and alpha packages.

Cheers, I did this, and reproduced what happened in the GUI. I got this working by running Steps 1, 2 and 3 in my first message, and then importing an OpenAPI definition from my local file system. I used http://[my-ip-address] as the target.

This does look incorrect to me. ZAP shows the response as a 200 OK, when in actual fact the response is a 302 Moved Temporarily. It looks like redirects are being automatically followed, and the response of the last request GET /v1/trees is being applied to the first request GET /.


Screenshot 2020-04-04 11.15.36.pngScreenshot 2020-04-04 11.15.57.png

thc...@gmail.com

unread,
Apr 20, 2020, 2:47:58 PM4/20/20
to 'Cameron Swords' via OWASP ZAP User Group
Hi.

> This does look incorrect to me. ZAP shows the response as a 200 OK,
when in
> actual fact the response is a 302 Moved Temporarily. It looks like
> redirects are being automatically followed, and the response of the last
> request *GET /v1/trees* is being applied to the first request *GET /*.

Right, that's the problem.

Thanks for reporting.

Best regards.

On 04/04/2020 01:23, 'Cameron Swords' via OWASP ZAP User Group wrote:
>
>
>> what starts the process an API get? Post? Is the CC param passed along in
>> the requests, if so how?
>
>
> The URLs */* and */v1* are defined in the OpenAPI specification to return
> 302 responses. When the specification is imported, ZAP parses the file and
> extracts URLs. After import, the URLs are passively scanned, and the ZAP
> alerts are created.
>
> The URLs are GETs in the specification, and this is the kind of request ZAP
> makes. I'm not sure what you mean by CC param?
>
>
>
> hit up the marketplace ... for the beta and alpha packages.
>
>
> Cheers, I did this, and reproduced what happened in the GUI. I got this
> working by running Steps 1, 2 and 3 in my first message, and then importing
> an OpenAPI definition from my local file system. I used
> http://[my-ip-address] as the target.
>
> This does look incorrect to me. ZAP shows the response as a 200 OK, when in
> actual fact the response is a 302 Moved Temporarily. It looks like
> redirects are being automatically followed, and the response of the last
> request *GET /v1/trees* is being applied to the first request *GET /*.
>
>
> [image: Screenshot 2020-04-04 11.15.36.png][image: Screenshot 2020-04-04
> 11.15.57.png] <about:invalid#zClosurez>
Reply all
Reply to author
Forward
0 new messages