How to view all 200 responses from zap-api-scan?

290 views
Skip to first unread message

Josh Reitz

unread,
Nov 24, 2021, 10:00:03 AM11/24/21
to OWASP ZAP User Group
Hello,

I ran a zap-api-scan on an OpenAPI-defined target and was able to successfully scan all of the paths. However, I was wondering if there was some way I could see the total number of successful 200 responses during the scan as a way of verifying that all of the requests are properly authenticated. 

Thanks for you help,
Josh

Simon Bennetts

unread,
Nov 24, 2021, 10:05:24 AM11/24/21
to OWASP ZAP User Group
Hi Josh,

You can make any ZAP API calls you like via scan hooks including retrieving all of the requests and responses, but in this case I'd just recommend reading the ZAP stats.
These include request counts by response code, and also the auth state if you have set ZAP up to handle authentication.

Cheers,

Simon

Josh Reitz

unread,
Nov 24, 2021, 10:22:35 AM11/24/21
to OWASP ZAP User Group
Thanks a lot for the quick response!
What is the keyPrefix parameter seen here (https://www.zaproxy.org/docs/api/#zap-api-stats)? I'm having trouble making a successful request. How can I get results specific to the scans that I ran?

Simon Bennetts

unread,
Nov 24, 2021, 10:28:48 AM11/24/21
to OWASP ZAP User Group
The the key (or start of a key) as given on https://www.zaproxy.org/docs/internal-statistics/

So if you give a keyPrefix of "stats.ascan.0.alerts" then you will just get the number of alerts raised by the Directory Browsing rule (alert IDs are given on https://www.zaproxy.org/docs/alerts/)
But if you give a keyPrefix of "stats.ascan" then you will get all stats with a key that starts with "stats.ascan".

You can run the ZAP desktop and interact with the API via the API Web UI to get a better feel for it.

Re results specific to scans - can you explain what you're asking here?

Cheers,

Simon

Josh Reitz

unread,
Nov 24, 2021, 11:23:19 AM11/24/21
to OWASP ZAP User Group
I see, thank you.

My question was how I could receive the stats for a specific scan, but if I now understand correctly, I would add the scan hook file that makes the API call for a specific statistic to a scan that I run (using Docker) and the counter would gather the information from that command. Then I would be able to see that statistic outputted along with my scan results.

As a side question, if I generate an API key using the Desktop UI, can I use that key in these scan hooks for statistics? Or is there a separate method of obtaining the API key that is preferred?

Thanks much,
Josh

Simon Bennetts

unread,
Nov 24, 2021, 12:35:06 PM11/24/21
to OWASP ZAP User Group
You dont really need to use an API key if you are running ZAP in docker and theres no external access to ZAP :)
But if you do start ZAP with an API key then yes, you will need to use that in your API calls.
However that wont be necessary via the packaged scans as they explicitly disable the API key.

Cheers,

Simon

Josh Reitz

unread,
Nov 24, 2021, 2:30:39 PM11/24/21
to OWASP ZAP User Group
Thanks again, Simon.

I am running ZAP without an API key through Docker. How will I be able to use the API call then? From here (https://www.zaproxy.org/docs/api/#scriptactionsetglobalvar), I see a header variable that requires an API key. How can I make this request in my scan hook without this variable?

Josh Reitz

unread,
Nov 24, 2021, 2:36:35 PM11/24/21
to OWASP ZAP User Group
Also, my plan is to make this API request in the scan hook "pre_exit" since this would run after the scan has completed and I would be able to see the results of the scan in my API call. Is this the correct hook to target?

Thank you,
Josh

Simon Bennetts

unread,
Nov 25, 2021, 4:31:35 AM11/25/21
to OWASP ZAP User Group
Hi Josh,

The header variable is only required if an API key is required, which is not the case when ZAP is being run via one of the packaged scans.

The pre_exit hook is called at the very end and you'll see that it doesnt have a 'zap' parameter - thats because ZAP will have been shut down at this point.
You should use the 'zap_pre_shutdown' hook.

Cheers,

Simon

Josh Reitz

unread,
Nov 30, 2021, 4:53:24 PM11/30/21
to OWASP ZAP User Group
Hello! I'm still trying to view these statistics but am having difficulty. I created a scan python file that overwrites the pre_shutdown hook, but the requests to the stats endpoints are failing. Here is some output I see.
-------------------

2021-11-30 21:33:27,534 Trigger hook: zap_pre_shutdown, args: 1

Pre shutdown method begin <----- (prints from within my hook file)

2021-11-30 21:33:27,535 Starting new HTTP connection (1): zap:80

ERROR HTTPConnectionPool(host='zap', port=80): Max retries exceeded with url: /JSON/stats/view/stats/?keyPrefix=stats.auth.success (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f3e83b748b0>: Failed to establish a new connection: [Errno -2] Name or service not known'))

2021-11-30 21:33:27,640 I/O error: HTTPConnectionPool(host='zap', port=80): Max retries exceeded with url: /JSON/stats/view/stats/?keyPrefix=stats.auth.success (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f3e83b748b0>: Failed to establish a new connection: [Errno -2] Name or service not known'))

Traceback (most recent call last):

  File "/usr/local/lib/python3.8/dist-packages/urllib3/connection.py", line 158, in _new_conn

    conn = connection.create_connection(

  File "/usr/local/lib/python3.8/dist-packages/urllib3/util/connection.py", line 57, in create_connection

    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):

  File "/usr/lib/python3.8/socket.py", line 918, in getaddrinfo

    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):

socket.gaierror: [Errno -2] Name or service not known

----------------------

So I can't make a request to the proper endpoint. I also tried /JSON/stats/view/stats/, as well as other endpoints, but receive the same errors.


Thanks for your help!!


thc...@gmail.com

unread,
Nov 30, 2021, 6:32:51 PM11/30/21
to zaprox...@googlegroups.com
Hi.

The problem is that the ZAP API client can't connect to ZAP.

The connection configuration does not seem right (e.g. is ZAP on port 80?).

Could you share the script you are using?

Best regards.
>>>>>>>>> <https://www.zaproxy.org/docs/docker/scan-hooks/> including
>>>>>>>>> retrieving all of the requests and responses, but in this case I'd just
>>>>>>>>> recommend reading the ZAP stats
>>>>>>>>> <https://www.zaproxy.org/docs/internal-statistics/>.

Josh Reitz

unread,
Nov 30, 2021, 8:49:08 PM11/30/21
to OWASP ZAP User Group
Absolutely. I just made a pretty simple script that just makes the GET request. 

-----
import requests


def zap_pre_shutdown(zap):
print("Pre shutdown method begin")
#payload = {'keyPrefix': 'stats.auth.success'}

print('----------------------')
print(r.json())

------

thc...@gmail.com

unread,
Dec 1, 2021, 4:10:00 AM12/1/21
to zaprox...@googlegroups.com
You should use the zap variable instead, e.g.:
zap.stats.stats("stats.auth.success")

More details in:
https://www.zaproxy.org/docs/api/

Best regards.

Josh Reitz

unread,
Dec 1, 2021, 9:37:28 AM12/1/21
to OWASP ZAP User Group
Sorry, but I'm still having trouble. If I access that value in the same script, I see this error output.

-----------------------------

2021-12-01 14:27:01,187 Trigger hook: zap_pre_shutdown, args: 1

Pre shutdown method begin

2021-12-01 14:27:01,189 Starting new HTTP connection (1): localhost:38059

2021-12-01 14:27:01,192 http://localhost:38059 "GET http://zap/JSON/stats/view/stats/?keyPrefix=stats.auth.success HTTP/1.1" 200 2

ERROR <class 'StopIteration'>

2021-12-01 14:27:01,192 Unexpected error: <class 'StopIteration'>

Traceback (most recent call last):

  File "/zap/zap-api-scan.py", line 589, in main

    trigger_hook('zap_pre_shutdown', zap)

  File "/zap/zap_common.py", line 131, in trigger_hook

    response = hook_fn(*args_list, **kwargs)

  File "/zap/wrk/zap-view-stats.py", line 14, in zap_pre_shutdown

    print(zap.stats.stats("stats.auth.success"))

  File "/usr/local/lib/python3.8/dist-packages/zapv2/stats.py", line 37, in stats

    return six.next(six.itervalues(self.zap._request(self.zap.base + 'stats/view/stats/', params)))

StopIteration


Reply all
Reply to author
Forward
0 new messages