0
votes

I want to use the ZAP API to perform authenticated scans against a number of different web applications. These web applications each have different mechanisms to login and I do not want to perform the tedious process of logging in via a number of different forms which each need to be manually configured.

The easier solution is to use the HTTP session cookies for each application to perform these authenticated scans, however I cannot see a mechanism to perform this without creating a context with an associated user.

I attempted to add a new session via the http sessions, despite them not being for this use case:

def add_session(self, session_name, session_tokens):
        self.zap.httpsessions.create_empty_session(self.target_url, session_name, apikey=self.api_key)
        for token_name, token_value in session_tokens:
            self.zap.httpsessions.set_session_token_value(self.target_url, session_name,  token_name, token_value, apikey=self.api_key)
        self.zap.httpsessions.add_session_token(self.target_url, session_name, apikey=self.api_key)
        self.zap.httpsessions.set_active_session(self.target_url, session_name, apikey=self.api_key)

However, when performing a scan any manually added cookies are not added to the subsequent requests to the server.

For example, when performing a spider the session information is ignored:

def spider(self):
    scanid = self.zap.spider.scan(self.target_url, apikey=self.api_key)
    while (int(self.zap.spider.status(scanid)) < 100):
        print 'Spider progress %s%% ' % self.zap.spider.status(scanid)
        time.sleep(1.0)
    return self.zap.spider.full_results(scanid)

Is it possible to perform scans by adding cookies to requests via the ZAP API?

Or is the only option to manually add the form data and context for each website to which I want to login and scan?

1

1 Answers

1
votes

Yes it is possible - we do this at Mozilla. The snippet of code I use is:

zap.httpsessions.add_session_token(target + ":443", "sessionid")
zap.httpsessions.create_empty_session(target + ":443", "testsession")
zap.httpsessions.set_session_token_value(target + ":443", "testsession", "sessionid", session_cookie)
zap.httpsessions.set_active_session(target + ":443", "testsession")

That works with both spidering and active scanning, no context required. I use the Auth Stats (https://github.com/zaproxy/zap-extensions/wiki/HelpAddonsAuthstatsAuthStats) add-on to check that the authentication is working as expected.

Cheers, Simon