Authenticate AJAX-spider via selenium script for docker packaged scan

274 views
Skip to first unread message

Kris

unread,
Nov 28, 2022, 9:08:18 AM11/28/22
to OWASP ZAP User Group
Hi all,

I am trying to scan a single-page webapp that uses Microsoft Azure B2C for authentication. I was able to automate the authentication process in the GUI with a selenium script, that is enabled in the scripts tree tab . When I run the ajax spider in the GUI, the browsers all authenticate successfully and the ajax spider is able to scan the app.

Unfortunately I was not able to reproduce that with a docker packaged scan. The script seems to be loaded but not executed.

This is the command I run to start the container and the baseline scan:

docker run --rm -v
$(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py -t [TARGET_URL] -n session.context -z '-configfile /zap/wrk/options.conf' -d -j -s


The options.conf file contains the following:

script.scripts.name="B2C_Login"
script.scripts.engine="Oracle Nashorn"
script.scripts.type=selenium
script.scripts.enabled=true
script.scripts.file="b2c_login.js"

Below you can see an excerpt from the zap.log that shows that the options.conf file was successfully loaded and the contents are beeing processed.

zap_log.PNG

i was able to verify that the script could be loaded, as there is an error message in the log when i specify an invalid script name.

My questions are:
  • Is it possible to authenticate the ajax spider via a selenium script when using docker packaged scans?
  • If so, what am I doing wrong?
  • If not is there a recommended way to perform authentication via b2c?
  • Is it possible to write the selenium script output to the cli when running a docker packaged scan?
If someone could help me here i would really appreciate it. Thank you so much in advance!

Kris

unread,
Dec 7, 2022, 5:04:46 AM12/7/22
to OWASP ZAP User Group
Hi all,

here's an update to my problem.

I was not able to figure out why the selenium script is not running in docker with a packaged scan. The script is loaded, there're no errors in the zap.log and still the ajax spider is not able to get beyond the B2C login page. As mentioned, the script works in the GUI.

Next, I tried to get authentication working via the GUI using authentication and session management scripts in case only plain selenium scripts are not working with the packaged scans. I used this video from Simon Bennett https://play.vidyard.com/TMcBcuhyPt57sUqPcJUtpv as a guideline.

So as described by him, I start a browser with Selenium in the authentication script to perform the login. As soon as I want to load a page via webDriver.get(url), the browser just hangs and doesn't load the site.

If I do the same in a stand alone script it works. I believe I can also see this behavior in the video at minute 17 with him.

Does anyone have the same problem or can tell me what it could be?

Also, I would still be interested to know if and how I can pass script output to the CLI output from Docker Packaged Scan to check if scripts are being executed.

Thank you, best regards

Simon Bennetts

unread,
Dec 7, 2022, 5:36:52 AM12/7/22
to OWASP ZAP User Group
Hi Kris,

Sorry, your original email was on my list to reply to, but I hadnt got to it yet.
Thanks for the update.
The fact that you can reproduce this with the desktop will definitely help.
Can you share the scripts you are using?

Many thanks,

Simon

Kris

unread,
Dec 7, 2022, 6:11:39 AM12/7/22
to OWASP ZAP User Group

Hi Simon,

thanks for the reply.

The original selenium script that is working in the GUI but not in docker is:

```
function browserLaunched(ssutils) {
    var By = Java.type('org.openqa.selenium.By');
    var Thread = Java.type('java.lang.Thread');

    logger(ssutils.getBrowserId() + ' was launched...\n');

    var driver = ssutils.getWebDriver();
    driver.get('targetURL');
    ssutils.waitForURL(5000);

    logger('B2C loaded. Waiting for site to build up...\n');

    Thread.sleep(3000);

    logger('Sending credentials...\n');

    var usernameInput = driver.findElement(By.id('signInName'));
    var passwordInput = driver.findElement(By.id('password'));
    var submitButton = driver.findElement(By.id('next'));

    usernameInput.sendKeys('username');
    passwordInput.sendKeys('password');
    submitButton.click();

    logger('Credentials were sent. Waiting to be redirected...\n');

    Thread.sleep(10000);

    logger('Session should now be established...\n');
}

function logger() {
    print('[' + this['zap.script.name'] + '] ' + arguments[0]);
}
```
It's really simple but works like a charm with the ajax-spider. At least in the GUI...

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

The authentication script I used last in the GUI based on the one you showed in the video and in which selenium does not work as expected is:

```
var By = Java.type('org.openqa.selenium.By');
var URI = Java.type('org.apache.commons.httpclient.URI');
var Thread = Java.type('java.lang.Thread');
var HttpHeader = Java.type('org.parosproxy.paros.network.HttpHeader');
var HttpRequestHeader = Java.type('org.parosproxy.paros.network.HttpRequestHeader');
var scriptVars = Java.type('org.zaproxy.zap.extension.script.ScriptVars');

function authenticate(helper, paramsValues, credentials){
    logger('starting authentication...');

    var selenium = org.parosproxy.paros.control.Control.getSingleton().
        getExtensionLoader().getExtension(
        org.zaproxy.zap.extension.selenium.ExtensionSelenium.class);

// ------------
// Here's the problem
// ------------
var driver = selenium.getWebDriverProxyingViaZAP(5, 'firefox');
// The browser starts as expected
driver.get('targetURL');
// The browser now just hangs and does not load the page
driver.close();

logger('verifying if authenticated...');

var requestURI = new URI('verificationURL');
var requestMethod = HttpRequestHeader.GET;
var requestHeader = new HttpRequestHeader(requestMethod, requestURI, HttpHeader.HTTP11);
var msg = helper.prepareMessage();

msg.setRequestHeader(requestHeader);
helper.sendAndReceive(msg);

logger('got message: ' + msg.getResponseBody().toString());
return msg;
}

function getRequiredParamsNames(){
    return [];
}

function getOptionalParamsNames(){
    return [];
}

function getCredentialsParamsNames(){
    return ["username", "password"];
}

function logger() {
    print('[' + this['zap.script.name'] + '] ' + arguments[0]);
}
```
-----------------------------------------------------------------------------------------------

Basically the same thing works in a stand alone script:

```
var By = Java.type('org.openqa.selenium.By');
var Thread = Java.type('java.lang.Thread');
var selenium = org.parosproxy.paros.control.Control.getSingleton().
    getExtensionLoader().getExtension(
        org.zaproxy.zap.extension.selenium.ExtensionSelenium.class);

var driver = selenium.getWebDriverProxyingViaZAP(5, 'firefox');
driver.get('targetURL');
Thread.sleep(3000);

driver.findElement(By.id('signInName')).sendKeys('username');
driver.findElement(By.id('password')).sendKeys('password');
driver.findElement(By.id('next')).click();
```

Thanks again for taking the time!

Kris

unread,
Dec 14, 2022, 4:47:17 AM12/14/22
to OWASP ZAP User Group
Hi,

here's another update from me.

The selenium script could be enabled via a zap_hook. So instead of writing

script.scripts.name="B2C_Login"
script.scripts.engine="Oracle Nashorn"
script.scripts.type=selenium
script.scripts.enabled=true
script.scripts.file="b2c_login.js"

to a configfile and loading it with -z '-configfile /zap/wrk/[thefilename]'  I used this scan-hook in a file named zap_started_hook.py:

def zap_started(zap, target):
    zap.script.load('b2c_login.js', 'selenium', 'Oracle Nashorn', '/zap/wrk/b2c_login.js')
    zap.script.enable('b2c_login.js')

and loaded it with --hook /zap/wrk/zap_started_hook.py

The ajax-spider now works as expected.

Nevertheless I could not yet figure out, why the selenium driver.get() method is not working in an authentication-script. So if anyone knows that... Let me know.
Reply all
Reply to author
Forward
0 new messages