Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

authhelper: Sync collections to address concurrency issues #6280

Merged
merged 1 commit into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addOns/authhelper/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### Fixed
- Bug where some of the data structures were not being reset when the session changed.
- Address concurrent modification exceptions.

## [0.23.0] - 2025-03-04
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,29 +160,32 @@ public class AuthUtils {
* the last known good value, in the case where we don't see the token set in the authentication
* response.
*/
private static Map<Integer, Map<String, String>> requestTokenMap = new HashMap<>();
private static Map<Integer, Map<String, String>> requestTokenMap =
Collections.synchronizedMap(new HashMap<>());

/**
* The best verification request we have found for a context. There will only be a verification
* request recorded if the user has indicated that they want ZAP to auto-detect one by: setting
* session management to auto-detect, setting the checking strategy to "poll" but not specified
* a URL.
*/
private static Map<Integer, VerificationRequestDetails> contextVerifMap = new HashMap<>();
private static Map<Integer, VerificationRequestDetails> contextVerifMap =
Collections.synchronizedMap(new HashMap<>());

/**
* The best session management request we have found for a context. There will only be a
* verification request recorded if the user has indicated that they want ZAP to auto-detect one
* by setting session management to auto-detect.
*/
private static Map<Integer, SessionManagementRequestDetails> contextSessionMgmtMap =
new HashMap<>();
Collections.synchronizedMap(new HashMap<>());

/**
* The URLs (and methods) we've checked for finding good verification requests. These will only
* be recorded if the user has set verification to auto-detect.
*/
private static Map<Integer, Set<String>> contextVerificationMap = new HashMap<>();
private static Map<Integer, Set<String>> contextVerificationMap =
Collections.synchronizedMap(new HashMap<>());

public static long getTimeToWaitMs() {
return timeToWaitMs;
Expand Down Expand Up @@ -1056,7 +1059,7 @@ public static void processVerificationDetails(
+ details.getMsg().getRequestHeader().getURI().toString();

if (contextVerificationMap
.computeIfAbsent(context.getId(), c -> new HashSet<>())
.computeIfAbsent(context.getId(), c -> Collections.synchronizedSet(new HashSet<>()))
.add(methodUrl)) {
// Have not already checked this method + url
getExecutorService().submit(new VerificationDetectionProcessor(context, details, rule));
Expand All @@ -1067,20 +1070,22 @@ public static void recordRequestSessionToken(Context context, String key, String
recordRequestSessionToken(context.getId(), key, value);
}

private static Map<String, String> computeIfAbsent(
Map<Integer, Map<String, String>> inputMap, int contextId) {
return inputMap.computeIfAbsent(
contextId, c -> Collections.synchronizedMap(new HashMap<>()));
}

public static void recordRequestSessionToken(int contextId, String key, String value) {
requestTokenMap
.computeIfAbsent(contextId, c -> new HashMap<>())
.put(key.toLowerCase(Locale.ROOT), value);
computeIfAbsent(requestTokenMap, contextId).put(key.toLowerCase(Locale.ROOT), value);
}

public static String getRequestSessionToken(Context context, String key) {
return getRequestSessionToken(context.getId(), key);
}

public static String getRequestSessionToken(int contextId, String key) {
return requestTokenMap
.computeIfAbsent(contextId, c -> new HashMap<>())
.get(key.toLowerCase(Locale.ROOT));
return computeIfAbsent(requestTokenMap, contextId).get(key.toLowerCase(Locale.ROOT));
}

static class AuthenticationBrowserHook implements BrowserHook {
Expand Down