Scanning APIs with ZAP - replacer with regex

959 views
Skip to first unread message

Rafał Grzegorek

unread,
Feb 28, 2021, 10:51:53 AM2/28/21
to OWASP ZAP User Group
Hello,

I'm trying to use API scanner Docker image as described here: https://www.zaproxy.org/blog/2017-06-19-scanning-apis-with-zap/ and I want to do some requests replacement using regexp. I'm using command:

docker run -v $(pwd):/zap/wrk/:rw --network=host -t owasp/zap2docker-weekly zap-api-scan.py --hook=/zap/wrk/authentication-hooks.py -t docs/openapi.yaml -f openapi  -w output/oppenapi.md -z "-configfile /zap/wrk/zapproxy.prop" -d

with "zapproxy.prop":

replacer.full_list(0).description=customerId
replacer.full_list(0).enabled=true
replacer.full_list(0).matchtype=REQ_HEADER_STR
replacer.full_list(0).matchstr=/api/customers/\d+
replacer.full_list(0).regex=true
replacer.full_list(0).replacement=/api/customers/1

and the replacement doesn't work for URL I want to modify: GET /api/customers/10.  The same rule used via GUI works just fine. 

I've also tried:

replacer.full_list(0).description=customerId
replacer.full_list(0).enabled=true
replacer.full_list(0).matchtype=REQ_HEADER_STR
replacer.full_list(0).matchstr=/api/customers/10
replacer.full_list(0).regex=false
replacer.full_list(0).replacement=/api/customers/1

it also works fine.

Is there something that I need to do to pass this regex correctly?

-- 

Rafal


Simon Bennetts

unread,
Mar 1, 2021, 4:16:33 AM3/1/21
to OWASP ZAP User Group
Have a look at how the rule is stored in the config.xml file - that should have it correctly escaped: https://www.zaproxy.org/faq/how-do-you-find-out-what-key-to-use-to-set-a-config-value-on-the-command-line/

Cheers,

Simon

Rafał Grzegorek

unread,
Mar 1, 2021, 12:42:43 PM3/1/21
to OWASP ZAP User Group
I've actually checked before your answer:

<full_list>

            <description>customerId</description>

            <enabled>true</enabled>

            <matchtype>REQ_HEADER_STR</matchtype>

            <matchstr>/api/customers/\d+</matchstr>

            <regex>true</regex>

            <replacement>/api/customers/1</replacement>

            <initiators/>

        </full_list>

As you can see - there's no difference. 

I also Googled for examples with API scans (via Docker) with replacer using regexp, but without any luck. :( Any hints for debuging this issue?

kingthorin+owaspzap

unread,
Mar 1, 2021, 1:42:39 PM3/1/21
to OWASP ZAP User Group
The details you provided in the first post don't match the details (and escaping) in the document Simon mentioned.

Rafał Grzegorek

unread,
Mar 1, 2021, 5:00:26 PM3/1/21
to OWASP ZAP User Group
Can you be more specific, please?

I followed the instructions from document Simon provided.

In config.xml i got this:

Zrzut ekranu 2021-03-1 o 22.53.07.png

You can see the path to "full_list" at the bottom. I've just tried again and passed the following "zaproxy.prop" file:

replacer.full_list(3).description=clientId
replacer.full_list(3).enabled=true
replacer.full_list(3).matchtype=REQ_HEADER_STR
replacer.full_list(3).matchstr=/api/customers/\d+
replacer.full_list(3).regex=true
replacer.full_list(3).replacement=/api/customers/1

What's wrong with escaping here?

I've also tried:

replacer.full_list(0).description=clientId

replacer.full_list(0).enabled=true
replacer.full_list(0).matchtype=REQ_HEADER_STR
replacer.full_list(0).matchstr=/api/customers/\d+
replacer.full_list(0).regex=true
replacer.full_list(0).replacement=/api/customers/1

Both without success.


Rafał Grzegorek

unread,
Mar 2, 2021, 2:43:36 PM3/2/21
to OWASP ZAP User Group
@Simon any other ideas what's could be wrong? 

kingthorin+owaspzap

unread,
Mar 2, 2021, 8:30:21 PM3/2/21
to OWASP ZAP User Group
So it only fails to work when you're using regex? If you do a literal string replacement it's fine?

Try your pattern with escaped slashes: \/api\/customer\/\d+

Rafał Grzegorek

unread,
Mar 3, 2021, 4:55:46 PM3/3/21
to OWASP ZAP User Group
Thank you very much :)

This is the solution (this tools was very helpful https://www.regexplanet.com/advanced/java/index.html):

replacer.full_list(0).description=clientId
replacer.full_list(0).enabled=true
replacer.full_list(0).matchtype=REQ_HEADER_STR
replacer.full_list(0).matchstr=/api/customers/\\d+
replacer.full_list(0).regex=true
replacer.full_list(0).replacement=/api/customers/2

Maybe adding info to the docs would be good idea?

Cheers

kingthorin+owaspzap

unread,
Mar 3, 2021, 7:03:50 PM3/3/21
to OWASP ZAP User Group
Great, glad you got it sorted out.

I'll look into adding an example to the docs or something.

Message has been deleted

Vikash Choudhary

unread,
Nov 26, 2022, 7:22:33 PM11/26/22
to OWASP ZAP User Group
Hi Rafal,
Could you please share the detailed steps that you have followed to generate the config? I have tried following the steps from the source but not seeing the expected outcome. Although provided config by you looks good to me.

My requirement is to match the request header and set the token to the "Authorization" header but doesn't seem to be working.

Many thanks in advance!
Reply all
Reply to author
Forward
0 new messages