Accessing ZAP API service from two remote machines

917 views
Skip to first unread message

Jones Michael

unread,
Jul 1, 2014, 9:14:17 AM7/1/14
to zaprox...@googlegroups.com
Hi,

1st,  this is a really sweet tool!!!


Is there a way when utilizing a remote ZAP API service programmatically, you can make REST service calls to it programmatically from a different machine?  For instance, I'm using the java client API in which there is a class ClientApi.java which builds the rest URL and sends the request.  When it builds the URL for every REST service request it constructs it like this:

 private static URL buildZapRequestUrl(
            String format,
            String component,
            String type,
            String method,
            Map<String, String> params) throws MalformedURLException {
        StringBuilder sb = new StringBuilder();
        sb.append("http://zap/");
        sb.append(format);
        sb.append('/');
        sb.append(component);
        sb.append('/');
        sb.append(type);
        sb.append('/');
        sb.append(method);
        sb.append('/');
        if (params != null) {
            sb.append('?');
            for (Map.Entry<String, String> p : params.entrySet()) {
                sb.append(encodeQueryParam(p.getKey()));
                sb.append('=');
                if (p.getValue() != null) {
                    sb.append(encodeQueryParam(p.getValue()));
                }
                sb.append('&');
            }
        }

        return new URL(sb.toString());
    }
          

As you can observe, its constructing the REST URL in such a way where a user can only make a REST service request locally as the URL will always have sb.append("http://zap/").  I need a way where I can call the ZAP REST API service hosted on a remote ZAP instance vs. locally.  Does ZAP support this or can ZAP API only be used from the local machine hosting ZAP?  Or possibly there is some network configuration I can do in order to accomplish this? 



Simon Bennetts

unread,
Jul 1, 2014, 9:32:09 AM7/1/14
to zaprox...@googlegroups.com
This should work right now, but you will need to change ZAP to listen on the correct IP address instead of localhost (via Options/Local Proxy).
Then initialize ClientApi using the ClientApi (String zapAddress, int zapPort, boolean debug) constructor.

I'd also strongly recommend that you generate a random API key (via Options/API) and use that on all actions.

Cheers,

Simon

Jones Michael

unread,
Jul 1, 2014, 10:01:05 AM7/1/14
to zaprox...@googlegroups.com
Ahhh I see.  Kool thanks!

I'm happy you brought up the apikey as I never see it being used when invoking the REST calls.  For instance, in Core.java it has services you can call such as :

public ApiResponse newSession(String apikey, String name, String overwrite) throws ClientApiException {
Map<String, String> map = null;
map = new HashMap<String, String>();
map.put("name", name);
map.put("overwrite", overwrite);
return api.callApi("core", "action", "newSession", map);
}


You see the apikey is a required parameter but its never used?  There are a lot of REST service methods like this.  Please elaborate on how to pass/use it?  The REST API doc is kind of challenging to know how to construct required key:values.

Jones Michael

unread,
Jul 1, 2014, 10:22:00 AM7/1/14
to zaprox...@googlegroups.com
Actually I am using that constructor but using  ClientApi (String zapAddress, int zapPort) which calls the one you are referring to.  If I called that directly I would be using the same values.  Let me make sure the remote ZAP doesn't have localhost as thh value vs. actual IP as you suggested.


public ClientApi (String zapAddress, int zapPort) {
this(zapAddress, zapPort, false);
}
public ClientApi (String zapAddress, int zapPort, boolean debug) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(zapAddress, zapPort));
this.debug = debug;
}


On Tuesday, July 1, 2014 9:32:09 AM UTC-4, Simon Bennetts wrote:

psiinon

unread,
Jul 1, 2014, 10:34:14 AM7/1/14
to zaprox...@googlegroups.com
The apikey is optional in the code, but if you set an apikey in ZAP then its required, otherwise its ignored :)
All of the ACTION calls should support it, eg see https://code.google.com/p/zaproxy/source/browse/trunk/src/org/zaproxy/clientapi/gen/Ascan.java#118
Its not required on VIEW requests.

Cheers,

Simon


--
You received this message because you are subscribed to the Google Groups "OWASP ZAP User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to zaproxy-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
OWASP ZAP Project leader

Jones Michael

unread,
Jul 1, 2014, 10:53:18 AM7/1/14
to zaprox...@googlegroups.com
So you are saying if the API KEY option is enabled then this method would have to add the apikey to map such as :

public ApiResponse scan(String apikey, String url, String recurse, String inscopeonly) throws ClientApiException {
                Map<String, String> map = null;
                map = new HashMap<String, String>();
                map.put("url", url);
                map.put("recurse", recurse);
                map.put("inScopeOnly", inscopeonly); map.put("apikey", apikey);
                return api.callApi("ascan", "action", "scan", map);
        }
 
If not then I'm like where is it being used?  If we do have to add map that means we would have to modify code and rebuild it right?

Simon Bennetts

unread,
Jul 1, 2014, 11:01:34 AM7/1/14
to zaprox...@googlegroups.com
No. That should be there now. Its a bug :((

I've just raised an issue for it: https://code.google.com/p/zaproxy/issues/detail?id=1251

I'll look at fixing that asap.

Cheers,

Simon

Jones Michael

unread,
Jul 1, 2014, 11:21:55 AM7/1/14
to zaprox...@googlegroups.com
Ahhh OK.  Happy to help out :-)

Well one more thing that seemed not right (might be possible bug) is in the ClientApi.java class in the method:

public byte[] callApiOther (String component, String type, String method,
Map<String, String> params) throws ClientApiException {
try {
URL url = buildZapRequestUrl("other", component, type, method, params);
if (debug) {
debugStream.println("Open URL: " + url);
}
HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy);
.........

                        .........
} catch (Exception e) {
throw new ClientApiException(e);
}
}

the proxy value in HttpURLConnection uc = (HttpURLConnection)url.openConnection(proxy); is defined above in class with hardcoded localhost and port:

private Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8090));
Is that right?  If so, why are we doing this?

Simon Bennetts

unread,
Jul 1, 2014, 11:39:27 AM7/1/14
to zaprox...@googlegroups.com
If you fancy trying to fix the code then the generator is https://code.google.com/p/zaproxy/source/browse/trunk/src/org/zaproxy/zap/extension/api/JavaAPIGenerator.java
I suspect testing it will take longer than implementing the fix, and as you have an environment set up... ;)

Re the proxy initialization, I dont _think_ its a bug (but reserve the right to be completely wrong;).
The 'proxy' is _defaulted_ to localhost/8090 on line 63, but if you use the constructor I mentioned then its changed to use the values you pass in: https://code.google.com/p/zaproxy/source/browse/trunk/src/org/zaproxy/clientapi/core/ClientApi.java#85

Cheers,

Simon

Jones Michael

unread,
Jul 1, 2014, 3:02:19 PM7/1/14
to zaprox...@googlegroups.com
lol...I'm not trying to fix the code...just trying to get it working remotely.  On another note, I'll def contribute in any way I can simply because we are using this and see its benefit.  

I basically disabled API KEY option and it still doesn't work.  It doesn't even work if I configure local FF browser to proxy through remote ZAP.  So I know if it doesn't work that way then aint no hell in way it should work underneath the surface.  Did you guys test this on your end?  Just curious as possibly its a bug there.  Please check on your end and I'll be happy to run some tests on my end.  Thanks for all your vast responses!  That's what I'm talkin bout!      

Simon Bennetts

unread,
Jul 2, 2014, 5:23:46 AM7/2/14
to zaprox...@googlegroups.com
Yes, we have tested this before, and I've just retested it now and its working fine for me (without using the API key).
That was using the Java API on a Windows 8 box accessing ZAP running on Linux :)
Note that I did need to change the Linux boxes firewall to allow access to the ZAP port, so that might be something to check on your side.

But I can confirm that the apikey does NOT currently work via the Java API.
I'm looking at fixing that now.

Cheers,

Simon

Simon Bennetts

unread,
Jul 2, 2014, 5:49:10 AM7/2/14
to zaprox...@googlegroups.com
I've fixed the bug and uploaded a new version of the client API to support the apikey to https://sourceforge.net/projects/zaproxy/files/client-api/ (zap-api-v2-8.jar)
Let me know how you get on with it.
Note that the Python API (and possibly the others) also have this bug.
We'll look at fixing them asap.

Cheers,

Simon

Jones Michael

unread,
Jul 9, 2014, 8:49:13 AM7/9/14
to zaprox...@googlegroups.com
Sorry for the late response...was on vacation (July 4th Independence holiday).  In any case, it Works :-)  Thanks for the quick turnaround.  One quick question though, does ZAP support concurrency?  Such as, can I have multiple sessions (e.g. scans) happening at the same time via concurrent threads?  


--
You received this message because you are subscribed to a topic in the Google Groups "OWASP ZAP User Group" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/zaproxy-users/VN3Q-Lk21tU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to zaproxy-user...@googlegroups.com.

Simon Bennetts

unread,
Jul 9, 2014, 8:54:58 AM7/9/14
to zaprox...@googlegroups.com
No problem.

ZAP 2.3.1 doesnt support concurrent scans via the API I'm afraid :(
But the latest weekly release does support concurrent spidering and the changes to support concurrent active scans are in progress :)

Cheers,

Simon
To unsubscribe from this group and all its topics, send an email to zaproxy-users+unsubscribe@googlegroups.com.

Jones Michael

unread,
Jul 9, 2014, 9:59:01 AM7/9/14
to zaprox...@googlegroups.com
OK kool...looking forward for that.  Thanks again for the fast response....


To unsubscribe from this group and all its topics, send an email to zaproxy-user...@googlegroups.com.

Jones Michael

unread,
Jul 22, 2014, 11:17:05 AM7/22/14
to zaprox...@googlegroups.com
Hi Simon, hope all is well.  Sorry for extending thread with another question reported elsewhere but I didn't get an answer.  Possibly you can share information on thread:



Simon Bennetts

unread,
Jul 23, 2014, 4:44:51 AM7/23/14
to zaprox...@googlegroups.com
Looks like thc202 beat me to it :)

Jones Michael

unread,
Jul 23, 2014, 8:26:51 AM7/23/14
to zaprox...@googlegroups.com
Yup... tkx though!



To unsubscribe from this group and all its topics, send an email to zaproxy-user...@googlegroups.com.

Kim Carter

unread,
Apr 19, 2015, 10:42:10 PM4/19/15
to zaprox...@googlegroups.com
Does now though with 2.4.0 :-)
To unsubscribe from this group and all its topics, send an email to zaproxy-user...@googlegroups.com.

Jones Michael

unread,
Apr 20, 2015, 4:26:52 PM4/20/15
to zaprox...@googlegroups.com
Yes! Yes! Yes!  I actually just looked last week and saw this.  I'm updating our internal test framework just now to test this out in addition to the new support for multiple sessions as this was a previously a limitation.  I'll keep you guys updated if I find any issues.

Thanks again for the update!  You guys rock!


Jones Michael

unread,
Apr 21, 2015, 11:57:57 AM4/21/15
to zaprox...@googlegroups.com
Hi Guys,

Thus far I'm updating project to leverage latest code.  I'm using:

 zap-api-2.4-v1.jar

in addition to the Java client API for OWASP ZAP
<groupId>net.continuumsecurity</groupId>
    <artifactId>proxy</artifactId>
    <version>2.4-SNAPSHOT</version>
Ran into an issue where I'm tracking here:


This is currently blocking further testing.  If anything I can update clear() with what should be there and continue to go further...

I also have questions around getLastScannerScanId() & getLastSpiderScanId() but I'll wait till I'm past this issue as my question just may be answered once I bypass issue.  Thanks!
Reply all
Reply to author
Forward
0 new messages