Generate Access token for API testing

605 views
Skip to first unread message

Niladri Bihari Sahu

unread,
Oct 26, 2018, 3:14:40 AM10/26/18
to OWASP ZAP Developer Group
Hi ,

I have the requirements as below:

1. Need to generate access token using a HTTP Post request.
2. After that I need to set the token in the header of every HTTP request while doing the active scan.

I tried the below things.

1. I tried to enable the script based authentication but it does not lunch after getting 401 status code in response.
2. Also I was trying to send a HTTP Post request from the HTTP sender script but I am not able to use XMLHttpRequest inside the script.Getting some dependency error"XMLHttpRequest is not defined".

Can you please suggest how I can make it work either way mentioned above.

Thanks,
Neel

kingthorin+owaspzap

unread,
Oct 26, 2018, 4:03:40 AM10/26/18
to OWASP ZAP Developer Group
You can probably find what you need in the community scripts repo.

https://github.com/zaproxy/community-scripts

You don't find XMLHttpRequest because ZAP isn't a browser.

Niladri Bihari Sahu

unread,
Oct 26, 2018, 4:14:07 AM10/26/18
to OWASP ZAP Developer Group
Hi ,

How Can I send a post request from HTTP Sender script?
Can you please give some idea.

Thanks,
Neel 

hauschu...@gmail.com

unread,
Oct 26, 2018, 5:00:05 AM10/26/18
to OWASP ZAP Developer Group
The name 'HTTPsender' may seem a bit confusing, it doesn't create NEW requests. It simply allows the option to modify every single request that ZAP processes, whether it is in the proxy, spider, fuzzer, etc. 

It sounds like we should try to help troubleshooting your authentication script! What are your settings? What are you seeing when you receive a 401 response?

thc...@gmail.com

unread,
Oct 26, 2018, 5:06:36 AM10/26/18
to zaproxy...@googlegroups.com
But it can create and send new requests, the default template shows that:
> // New requests can be made like this:
> // msg2 = msg.cloneAll() // msg2 can then be safely changed as required without affecting msg
> // helper.getHttpSender().sendAndReceive(msg2, false);
> // print('msg2 response=' + msg2.getResponseHeader().getStatusCode())

so the access token can be (re)generated from within the HTTP Sender
script and injected to the message being sent.


Agreed though, getting the authentication script working might be better.

Best regards.

Niladri Bihari Sahu

unread,
Oct 27, 2018, 3:15:57 AM10/27/18
to OWASP ZAP Developer Group
There is nothing in the script console after getting the 401 response code.
Attaching the the authentication script and session property images so that it will be easy for you to answer.

The Script:

function authenticate(helper, paramsValues, credentials) {
    println("Authenticating via JavaScript script...");
    importClass(org.parosproxy.paros.network.HttpRequestHeader);
    importClass(org.parosproxy.paros.network.HttpHeader);
    importClass(org.apache.commons.httpclient.URI);

    var authHelper = new OAuthAuthenticator(helper, paramsValues, credentials);

    return authHelper.login();
}

function getRequiredParamsNames(){
return [ "APP_URL", "client_id", "client_secret", "scope" ,"audience", "realm", "grant_type", "Username", "Password"];
}

function getOptionalParamsNames(){
    return [];
}

function getCredentialsParamsNames(){
    return [];
}

function OAuthAuthenticator(helper, paramsValues, credentials) {

    this.helper = helper;
    this.loginApiUrl = paramsValues.get('API_URL');
    this.userName = paramsValues.get('Username');
    this.password = paramsValues.get('Password');
    this.clientId = paramsValues.get('client_id');
    this.clientSecret = paramsValues.get('client_secret');
    this.scope = paramsValues.get('scope');
    this.audience = paramsValues.get('audience');
    this.realm = paramsValues.get('realm');  
    this.grantType = paramsValues.get('grant_type');
    return this;
}

OAuthAuthenticator.prototype = {
    login: function () {
        
        var loginToken,
            requestBody = 'username=' + this.userName + '&password=' + this.password + '&client_id=' + this.clientId+ '&client_secret=' + this.clientSecret+ '&scope=' + this.scope+ '&audience=' + this.audience+ '&realm=' + this.realm+ '&grant_type=' + this.grantType,
            response = this.doRequest(
                this.loginApiUrl,
                HttpRequestHeader.POST,
                requestBody
            ),
            parsedResponse = JSON.parse(response.getResponseBody().toString());
        
        if (parsedResponse.error == 'Unauthorized') {
            println('Authentication failure to ' + this.loginApiUrl + ' with : Username = ' + this.userName + ' Password = ' + this.password);
        }
        else {
            println('Authentication succes. Token = ' + parsedResponse.token);
            org.zaproxy.zap.extension.script.ScriptVars.setGlobalVar("logintoken",parsedResponse.token)
        }
        return response;
    },

    doRequest: function (url, requestMethod, requestBody) {
        var msg,
            requestUri = new URI(url, false);
            requestHeader = new HttpRequestHeader(requestMethod, requestUri, HttpHeader.HTTP10);

        msg = this.helper.prepareMessage();
        msg.setRequestHeader(requestHeader);
        msg.setRequestBody(requestBody);

        this.helper.sendAndReceive(msg);

        return msg;
    }
};
SessionProperty1.JPG
SessionProperty2.JPG

Niladri Bihari Sahu

unread,
Oct 27, 2018, 3:18:41 AM10/27/18
to OWASP ZAP Developer Group
I am trying the same way but as the Http request to generate oauth token will be completly different from the zap Message.Thats why I am creating my own message in side the http sender script using helper.preparemessage(); but getting error :
<eval>:26 TypeError: helper.prepareMessage is not a function<eval>:26 TypeError: helper.prepareMessage is not a function

The Script I am using as below
 var msg1,
            requestUri = new URI(loginApiUrl, false);
            requestHeader = new HttpRequestHeader("POST", requestUri, HttpHeader.HTTP10);

        msg1 = helper.prepareMessage();
        msg1.setRequestHeader(requestHeader);
        msg1.setRequestBody(requestBody);       
helper.getHttpSender().sendAndReceive(msg1, false);
print('message1 response=' + msg1.getResponseHeader().getStatusCode());
print('Message Response='+msg1.getResponseBody().toString());

thc...@gmail.com

unread,
Oct 27, 2018, 6:39:29 AM10/27/18
to zaproxy...@googlegroups.com
You need to define logged in/out indicators otherwise ZAP will not try
to authenticate:
https://github.com/zaproxy/zap-core-help/wiki/HelpStartConceptsAuthentication

Worth checking that all other requirements are fulfilled as well (e.g.
include in context).


The Authorization panel is for a different functionality than
authentication, it's used in:
https://github.com/zaproxy/zap-extensions/wiki/HelpAddonsAccessControlConcepts


Best regards.

thc...@gmail.com

unread,
Oct 27, 2018, 6:42:09 AM10/27/18
to zaproxy...@googlegroups.com
fyi, the HTTP Sender script does not have direct access to the user
(i.e. no preparedMessage available), although you can prepare the
message yourself by getting the user from the message being sent and set
it to the new message.

Best regards.

Niladri Bihari Sahu

unread,
Oct 28, 2018, 7:28:41 AM10/28/18
to OWASP ZAP Developer Group
I already tried that.But no luck.
Actually I am trying to do API testing importing from openapi definitions from files.So there is no login screen.I am trying to test the APIs from the backend server.Thats why I need to do script based authentiaction to generate the access token which i can send in the HTTP header for every request.

Thanks,
Neel

thc...@gmail.com

unread,
Oct 30, 2018, 5:31:42 AM10/30/18
to zaproxy...@googlegroups.com
Could you provide more details on what you did? Isn't the authentication
script running after setting the logged out indicator?

Is the API key being sent in an Authorization header? Was the session
management changed to HTTP Authentication Session Management?
https://github.com/zaproxy/zap-core-help/wiki/HelpStartConceptsSessionManagement

Best regards.
Reply all
Reply to author
Forward
0 new messages