Skip to content

Commit

Permalink
Client Script Based Auth (WIP)
Browse files Browse the repository at this point in the history
Signed-off-by: kingthorin <[email protected]>

# Conflicts:
#	addOns/authhelper/CHANGELOG.md
  • Loading branch information
kingthorin committed Jan 23, 2025
1 parent 1845b96 commit a1cbcf7
Show file tree
Hide file tree
Showing 12 changed files with 1,030 additions and 47 deletions.
3 changes: 3 additions & 0 deletions addOns/authhelper/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- Ignore non-displayed fields when selecting the user name and password.

### Added
- Added support for Client Script Authentication when used in conjunction with the Ajax Spider add-on.

## [0.17.0] - 2025-01-09
### Changed
- Update minimum ZAP version to 2.16.0.
Expand Down
23 changes: 21 additions & 2 deletions addOns/authhelper/authhelper.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ zapAddOn {
dependencies {
addOns {
register("spiderAjax") {
version.set(">=23.15.0")
version.set(">=23.23.0")
}
}
}
Expand All @@ -29,7 +29,16 @@ zapAddOn {
dependencies {
addOns {
register("client") {
version.set(">=0.10.0")
version.set(">=0.12.0")
}
register("spiderAjax") {
version.set(">=23.23.0")
}
register("scripts") {
version.set(">=45.9.0")
}
register("zest") {
version.set(">=48.1.0")
}
}
}
Expand Down Expand Up @@ -69,6 +78,16 @@ dependencies {
zapAddOn("selenium")
zapAddOn("spiderAjax")
zapAddOn("client")
zapAddOn("zest")

implementation("org.zaproxy:zest:0.22.0") {
// Provided by commonlib add-on.
exclude(group = "com.fasterxml.jackson")
// Provided by Selenium add-on.
exclude(group = "org.seleniumhq.selenium")
// Provided by ZAP.
exclude(group = "net.htmlparser.jericho", module = "jericho-html")
}

testImplementation(project(":testutils"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,8 @@ static SessionManagementRequestDetails findSessionTokenSource(String token) {
return findSessionTokenSource(token, -1);
}

static SessionManagementRequestDetails findSessionTokenSource(String token, int firstId) {
public static SessionManagementRequestDetails findSessionTokenSource(
String token, int firstId) {
ExtensionHistory extHist = AuthUtils.getExtension(ExtensionHistory.class);
int lastId = extHist.getLastHistoryId();
if (firstId == -1) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Zed Attack Proxy (ZAP) and its related class files.
*
* ZAP is an HTTP/HTTPS proxy for assessing web application security.
*
* Copyright 2025 The ZAP Development Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.zaproxy.addon.authhelper.client;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.zaproxy.addon.authhelper.AuthUtils;
import org.zaproxy.addon.authhelper.client.ClientScriptBasedAuthenticationMethodType.ClientScriptBasedAuthenticationMethod;
import org.zaproxy.addon.network.ExtensionNetwork;
import org.zaproxy.addon.network.server.ServerInfo;
import org.zaproxy.zap.authentication.AuthenticationMethod;
import org.zaproxy.zap.extension.selenium.BrowserHook;
import org.zaproxy.zap.extension.selenium.ExtensionSelenium;
import org.zaproxy.zap.extension.selenium.SeleniumScriptUtils;
import org.zaproxy.zap.extension.spiderAjax.AuthenticationHandler;
import org.zaproxy.zap.model.Context;
import org.zaproxy.zap.users.User;
import org.zaproxy.zest.impl.ZestBasicRunner;

public class ClientScriptBasedAuthHandler implements AuthenticationHandler {

private static final Logger LOGGER = LogManager.getLogger(ClientScriptBasedAuthHandler.class);

private BrowserHook browserHook;
private static ZestBasicRunner zestRunner;

@Override
public boolean enableAuthentication(User user) {
Context context = user.getContext();
if (context.getAuthenticationMethod()
instanceof
ClientScriptBasedAuthenticationMethodType.ClientScriptBasedAuthenticationMethod) {

if (browserHook != null) {
throw new IllegalStateException("BrowserHook already enabled");
}
browserHook = new AuthenticationBrowserHook(context, user);

AuthUtils.getExtension(ExtensionSelenium.class).registerBrowserHook(browserHook);

return true;
}
return false;
}

@Override
public boolean disableAuthentication(User user) {
if (browserHook != null) {
AuthUtils.getExtension(ExtensionSelenium.class).deregisterBrowserHook(browserHook);
browserHook = null;
return true;
}
return false;
}

static class AuthenticationBrowserHook implements BrowserHook {

private ClientScriptBasedAuthenticationMethod csaMethod;
private Context context;

AuthenticationBrowserHook(Context context, User user) {
this.context = context;
AuthenticationMethod method = context.getAuthenticationMethod();
if (!(method instanceof ClientScriptBasedAuthenticationMethod)) {
throw new IllegalStateException("Unsupported method " + method.getType().getName());
}
csaMethod = (ClientScriptBasedAuthenticationMethod) method;
}

private static ZestBasicRunner getZestRunner() {
if (zestRunner == null) {
zestRunner = new ZestBasicRunner();
// Always proxy via ZAP
ServerInfo mainProxyInfo =
AuthUtils.getExtension(ExtensionNetwork.class).getMainProxyServerInfo();
zestRunner.setProxy(mainProxyInfo.getAddress(), mainProxyInfo.getPort());
}
return zestRunner;
}

@Override
public void browserLaunched(SeleniumScriptUtils ssUtils) {
ZestBasicRunner runner = getZestRunner();
runner.addWebDriver("ClientScriptBasedAuthHandler", ssUtils.getWebDriver());
try {
runner.run(csaMethod.getZestScript(), null);
} catch (Exception e) {
LOGGER.warn(
"An error occurred while trying to execute the Client Script Authentication script: {}",
e.getMessage());
LOGGER.debug(e);
}
}
}
}
Loading

0 comments on commit a1cbcf7

Please sign in to comment.