From b133431a2fb37aa530f3dea3e45cfc5935bf613e Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:26:16 -0800 Subject: [PATCH 1/9] feat: Bambda to filter authorization values not equal to jwt bearer --- .../FilterAuthenticatedNonBearerTokens.bambda | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda new file mode 100644 index 0000000..ac227b5 --- /dev/null +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -0,0 +1,56 @@ +/** + * Filter when an Authorization header is present, not empty and does not include a traditional bearer token (beginning with "ey") + * + * @author GangGreenTemperTatum (https://github.com/GangGreenTemperTatum) + **/ + +var configNoFilter = true; +var configNotInScopeOnly = true; +var sessionCookieName = ""; +var sessionCookieValue = ""; + +if (!requestResponse.hasResponse()) { + return false; +} + +var request = requestResponse.request(); +var response = requestResponse.response(); + +if (!response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS)) { + return false; +} + +var authHeader = request.hasHeader("Authorization"); +var authHeaderValue = authHeader ? request.headerValue("Authorization") : null; + +var excludeAuthorization = authHeader && + authHeaderValue.toLowerCase().contains("bearer") && + authHeaderValue.toLowerCase().contains("ey"); + +var sessionCookie = request.headerValue("Cookie") != null && + !sessionCookieName.isEmpty() && + request.hasParameter(sessionCookieName, HttpParameterType.COOKIE) && + (sessionCookieValue.isEmpty() || sessionCookieValue.equals(request.parameter(sessionCookieName, HttpParameterType.COOKIE).value())); + +var path = request.pathWithoutQuery().toLowerCase(); +var mimeType = requestResponse.mimeType(); +var filterDenyList = mimeType != MimeType.CSS && + mimeType != MimeType.IMAGE_UNKNOWN && + mimeType != MimeType.IMAGE_JPEG && + mimeType != MimeType.IMAGE_GIF && + mimeType != MimeType.IMAGE_PNG && + mimeType != MimeType.IMAGE_BMP && + mimeType != MimeType.IMAGE_TIFF && + mimeType != MimeType.UNRECOGNIZED && + mimeType != MimeType.SOUND && + mimeType != MimeType.VIDEO && + mimeType != MimeType.FONT_WOFF && + mimeType != MimeType.FONT_WOFF2 && + mimeType != MimeType.APPLICATION_UNKNOWN && + !path.endsWith(".js") && + !path.endsWith(".gif") && + !path.endsWith(".jpg") && + !path.endsWith(".png") && + !path.endsWith(".css"); + +return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter || filterDenyList) && (!configNotInScopeOnly || request.isInScope()); \ No newline at end of file From 79131f201542c558e49ac14cae5b5bffd5f34b55 Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 06:56:51 -0800 Subject: [PATCH 2/9] fix: rename in-scope var --- Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index ac227b5..091fad7 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -5,7 +5,7 @@ **/ var configNoFilter = true; -var configNotInScopeOnly = true; +var configInScopeOnly = false; var sessionCookieName = ""; var sessionCookieValue = ""; @@ -53,4 +53,4 @@ var filterDenyList = mimeType != MimeType.CSS && !path.endsWith(".png") && !path.endsWith(".css"); -return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter || filterDenyList) && (!configNotInScopeOnly || request.isInScope()); \ No newline at end of file +return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter || filterDenyList) && (!configInScopeOnly || request.isInScope()); \ No newline at end of file From e18223303181ff71ad2fb5c737e4023535c65a03 Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 07:50:27 -0800 Subject: [PATCH 3/9] chore: add comments to vars --- Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index 091fad7..19a7f6d 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -5,9 +5,9 @@ **/ var configNoFilter = true; -var configInScopeOnly = false; -var sessionCookieName = ""; -var sessionCookieValue = ""; +var configInScopeOnly = false; // If set to false, won't show out-of-scope items +var sessionCookieName = ""; // If given, will look for a cookie with that name. +var sessionCookieValue = ""; // If given, will check if cookie with sessionCookieName has this value. if (!requestResponse.hasResponse()) { return false; From 2e29a16ff3328f69e54973a470aea352a9f397a8 Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 07:57:41 -0800 Subject: [PATCH 4/9] fix: set configinscope var to true --- Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index 19a7f6d..5931697 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -5,7 +5,7 @@ **/ var configNoFilter = true; -var configInScopeOnly = false; // If set to false, won't show out-of-scope items +var configInScopeOnly = true; // If set to true, won't show out-of-scope items var sessionCookieName = ""; // If given, will look for a cookie with that name. var sessionCookieValue = ""; // If given, will check if cookie with sessionCookieName has this value. From a5952c976eae5796a10031a9d38cad61f531558f Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:14:02 -0800 Subject: [PATCH 5/9] chore: remove unnecessary mimetype logic --- .../FilterAuthenticatedNonBearerTokens.bambda | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index 5931697..d467f20 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -33,24 +33,5 @@ var sessionCookie = request.headerValue("Cookie") != null && (sessionCookieValue.isEmpty() || sessionCookieValue.equals(request.parameter(sessionCookieName, HttpParameterType.COOKIE).value())); var path = request.pathWithoutQuery().toLowerCase(); -var mimeType = requestResponse.mimeType(); -var filterDenyList = mimeType != MimeType.CSS && - mimeType != MimeType.IMAGE_UNKNOWN && - mimeType != MimeType.IMAGE_JPEG && - mimeType != MimeType.IMAGE_GIF && - mimeType != MimeType.IMAGE_PNG && - mimeType != MimeType.IMAGE_BMP && - mimeType != MimeType.IMAGE_TIFF && - mimeType != MimeType.UNRECOGNIZED && - mimeType != MimeType.SOUND && - mimeType != MimeType.VIDEO && - mimeType != MimeType.FONT_WOFF && - mimeType != MimeType.FONT_WOFF2 && - mimeType != MimeType.APPLICATION_UNKNOWN && - !path.endsWith(".js") && - !path.endsWith(".gif") && - !path.endsWith(".jpg") && - !path.endsWith(".png") && - !path.endsWith(".css"); - -return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter || filterDenyList) && (!configInScopeOnly || request.isInScope()); \ No newline at end of file + +return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); \ No newline at end of file From d2dc6814b95f4c1d78575468347405347e69dcce Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:26:11 -0800 Subject: [PATCH 6/9] chore: restructure hasHeader() and remove ternary i received some errors when simply removing the ternary so resulted in using casting instead --- Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index d467f20..15ae9dd 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -21,17 +21,17 @@ if (!response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS)) { } var authHeader = request.hasHeader("Authorization"); -var authHeaderValue = authHeader ? request.headerValue("Authorization") : null; +var authHeaderValue = authHeader ? String.valueOf(request.headerValue("Authorization")).toLowerCase() : null; var excludeAuthorization = authHeader && - authHeaderValue.toLowerCase().contains("bearer") && - authHeaderValue.toLowerCase().contains("ey"); + authHeaderValue.contains("bearer") && + authHeaderValue.contains("ey"); var sessionCookie = request.headerValue("Cookie") != null && !sessionCookieName.isEmpty() && request.hasParameter(sessionCookieName, HttpParameterType.COOKIE) && - (sessionCookieValue.isEmpty() || sessionCookieValue.equals(request.parameter(sessionCookieName, HttpParameterType.COOKIE).value())); + (sessionCookieValue.isEmpty() || sessionCookieValue.equals(String.valueOf(request.parameter(sessionCookieName, HttpParameterType.COOKIE).value()))); var path = request.pathWithoutQuery().toLowerCase(); -return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); \ No newline at end of file +return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); From 3b976edd95d694ee439de370e72071992292acf0 Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:32:47 -0800 Subject: [PATCH 7/9] chore: move request isinscope check to beginning for code efficiency --- Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index 15ae9dd..14d39ae 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -9,14 +9,10 @@ var configInScopeOnly = true; // If set to true, won't show out-of-scope items var sessionCookieName = ""; // If given, will look for a cookie with that name. var sessionCookieValue = ""; // If given, will check if cookie with sessionCookieName has this value. -if (!requestResponse.hasResponse()) { - return false; -} - var request = requestResponse.request(); var response = requestResponse.response(); -if (!response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS)) { +if (!request.isInScope() || !response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS) || !requestResponse.hasResponse()) { return false; } @@ -34,4 +30,4 @@ var sessionCookie = request.headerValue("Cookie") != null && var path = request.pathWithoutQuery().toLowerCase(); -return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); +return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); \ No newline at end of file From 2b62caf457b54bd345d74dbab4d4dd8a775dc39e Mon Sep 17 00:00:00 2001 From: GangGreenTemperTatum <104169244+GangGreenTemperTatum@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:38:46 -0800 Subject: [PATCH 8/9] fix: nullpointerexception runtime errors invoking on null var --- Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index 14d39ae..0f224d0 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -12,7 +12,7 @@ var sessionCookieValue = ""; // If given, will check if cookie with sessionCooki var request = requestResponse.request(); var response = requestResponse.response(); -if (!request.isInScope() || !response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS) || !requestResponse.hasResponse()) { +if (response == null || !request.isInScope() || !response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS) || !requestResponse.hasResponse()) { return false; } @@ -30,4 +30,4 @@ var sessionCookie = request.headerValue("Cookie") != null && var path = request.pathWithoutQuery().toLowerCase(); -return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); \ No newline at end of file +return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); From 0de5cfe1e47dd0870f0ed71ab40fd9dd1159194b Mon Sep 17 00:00:00 2001 From: Hannah-PortSwigger <58562826+Hannah-PortSwigger@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:34:32 +0000 Subject: [PATCH 9/9] Update FilterAuthenticatedNonBearerTokens.bambda --- .../FilterAuthenticatedNonBearerTokens.bambda | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda index 0f224d0..2a0f9af 100644 --- a/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda +++ b/Proxy/HTTP/FilterAuthenticatedNonBearerTokens.bambda @@ -4,7 +4,6 @@ * @author GangGreenTemperTatum (https://github.com/GangGreenTemperTatum) **/ -var configNoFilter = true; var configInScopeOnly = true; // If set to true, won't show out-of-scope items var sessionCookieName = ""; // If given, will look for a cookie with that name. var sessionCookieValue = ""; // If given, will check if cookie with sessionCookieName has this value. @@ -12,14 +11,22 @@ var sessionCookieValue = ""; // If given, will check if cookie with sessionCooki var request = requestResponse.request(); var response = requestResponse.response(); -if (response == null || !request.isInScope() || !response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS) || !requestResponse.hasResponse()) { +if (configInScopeOnly && !request.isInScope()) { return false; } -var authHeader = request.hasHeader("Authorization"); -var authHeaderValue = authHeader ? String.valueOf(request.headerValue("Authorization")).toLowerCase() : null; +if (!requestResponse.hasResponse() || !response.isStatusCodeClass(StatusCodeClass.CLASS_2XX_SUCCESS)) { + return false; +} -var excludeAuthorization = authHeader && +var hasAuthHeader = request.hasHeader("Authorization"); +var authHeaderValue = hasAuthHeader ? String.valueOf(request.headerValue("Authorization")).toLowerCase() : null; + +if (!hasAuthHeader || (authHeaderValue == null || authHeaderValue.isEmpty())) { + return false; +} + +var excludeAuthorization = authHeaderValue.contains("bearer") && authHeaderValue.contains("ey"); @@ -28,6 +35,4 @@ var sessionCookie = request.headerValue("Cookie") != null && request.hasParameter(sessionCookieName, HttpParameterType.COOKIE) && (sessionCookieValue.isEmpty() || sessionCookieValue.equals(String.valueOf(request.parameter(sessionCookieName, HttpParameterType.COOKIE).value()))); -var path = request.pathWithoutQuery().toLowerCase(); - -return (authHeader && authHeaderValue != null && authHeaderValue.length() > 0 && !excludeAuthorization || sessionCookie) && (configNoFilter) && (!configInScopeOnly || request.isInScope()); +return !excludeAuthorization || sessionCookie;