From 001eccc53bf6976d13bcb1fbbc7097b81c019f30 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 18 Feb 2024 15:11:01 +0200 Subject: [PATCH 01/20] Dockerized the example project. --- CHANGELOG.md | 3 +++ Dockerfile | 27 +++++++++++++++++++++++++++ web/pom.xml | 19 +++++++++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 Dockerfile diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c26562..46138099 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## [vX.XX.X](https://github.com/PerimeterX/perimeterx-java-sdk/compare/X.XX.X...HEAD) (YYYY-MM-DD) +- Added Dockerfile for web application example. + ## [v6.11.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.11.0...HEAD) (2024-02-18) * Added base64-encoded request http method to captcha script query parameters on block pages diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..a09839ce --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM maven:3.8.6-openjdk-11-slim as builder +WORKDIR /app + +# Building the SDK. +COPY pom.xml . +COPY src/main/resources src/main/resources +RUN mvn verify clean -f pom.xml +COPY src ./src +RUN mvn clean install -DskipTests=true + +# Building the Demo app. +COPY web/pom.xml web/pom.xml +RUN mvn verify clean -f web/pom.xml +COPY web ./web +RUN mvn clean install war:war -DskipTests=true -f web/pom.xml + +FROM tomcat:9.0.68 + +COPY --from=builder /app/web/target/web-1.0.0 /usr/local/tomcat/webapps/ROOT + +## Enforcer configuration json file is located at: +## /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/src/main/resources/enforcer_config.json +COPY web/src/main/resources/ /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/src/main/resources + +EXPOSE 8080 + +CMD ["catalina.sh", "run"] \ No newline at end of file diff --git a/web/pom.xml b/web/pom.xml index be1c8aa9..f944028d 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -44,8 +44,23 @@ 1.2.17 - - + + + + maven-war-plugin + 3.4.0 + + + + src/main/java/templates + ** + /templates + + + + + + 8 8 From dd0cfa31b3775d56161e3588549d4274b350ee74 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 18 Feb 2024 19:58:34 +0200 Subject: [PATCH 02/20] align config --- .../credentialsIntelligenceconfig/PathType.java | 4 +++- web/src/main/java/com/web/Config.java | 13 ++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/perimeterx/models/configuration/credentialsIntelligenceconfig/PathType.java b/src/main/java/com/perimeterx/models/configuration/credentialsIntelligenceconfig/PathType.java index f7c41789..b0b7aab0 100644 --- a/src/main/java/com/perimeterx/models/configuration/credentialsIntelligenceconfig/PathType.java +++ b/src/main/java/com/perimeterx/models/configuration/credentialsIntelligenceconfig/PathType.java @@ -5,5 +5,7 @@ public enum PathType { @JsonProperty("regex") - REGEX + REGEX, + @JsonProperty("exact") + EXACT } diff --git a/web/src/main/java/com/web/Config.java b/web/src/main/java/com/web/Config.java index 24ed4bbc..6d8f023a 100644 --- a/web/src/main/java/com/web/Config.java +++ b/web/src/main/java/com/web/Config.java @@ -1,6 +1,5 @@ package com.web; -import com.google.gson.Gson; import com.perimeterx.api.additionalContext.credentialsIntelligence.CIProtocol; import com.perimeterx.api.additionalContext.credentialsIntelligence.loginresponse.LoginResponseValidationReportingMethod; import com.perimeterx.models.configuration.ModuleMode; @@ -35,7 +34,7 @@ public PXConfiguration getPxConfiguration() { case "px_logger_auth_token": builder.loggerAuthToken(enforcerConfig.getString(key)); break; - case "px_enabled": + case "px_module_enabled": builder.moduleEnabled(enforcerConfig.getBoolean(key)); break; case "px_encryption_enabled": @@ -47,7 +46,7 @@ public PXConfiguration getPxConfiguration() { case "px_sensitive_headers": builder.sensitiveHeaders(jsonArrayToSet(enforcerConfig.getJSONArray(key))); break; - case "px_max_buffer_length": + case "px_max_buffer_len": builder.maxBufferLen(enforcerConfig.getInt(key)); break; case "px_s2s_timeout": @@ -59,7 +58,7 @@ public PXConfiguration getPxConfiguration() { case "px_send_async_activities": builder.sendPageActivities(enforcerConfig.getBoolean(key)); break; - case "px_server_url": + case "px_backend_url": builder.serverURL(enforcerConfig.getString(key)); break; case "px_custom_logo": @@ -89,8 +88,8 @@ public PXConfiguration getPxConfiguration() { case "px_first_party_enabled": builder.firstPartyEnabled(enforcerConfig.getBoolean(key)); break; - case "px_collector_url": - builder.serverURL(enforcerConfig.getString(key)); + case "px_backend_collector_url": + builder.collectorUrl(enforcerConfig.getString(key)); break; case "px_module_mode": if (enforcerConfig.getString(key).equals("active_blocking")) { @@ -99,7 +98,7 @@ public PXConfiguration getPxConfiguration() { builder.moduleMode(ModuleMode.MONITOR); } break; - case "px_static_files": + case "px_filter_by_extension": builder.staticFilesExt(jsonArrayToSet(enforcerConfig.getJSONArray(key))); break; case "px_remote_configuration_interval_ms": From 9c43dad18e538d8435df27264afa0633bf6c4e2b Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Tue, 20 Feb 2024 13:45:37 +0200 Subject: [PATCH 03/20] Sensitive headers are now case-insensitive. --- CHANGELOG.md | 1 + .../models/configuration/PXConfiguration.java | 17 ++++++- .../com/perimeterx/utils/ActivityUtil.java | 3 +- .../models/PXConfigurationTest.java | 44 +++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46138099..c46860b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [vX.XX.X](https://github.com/PerimeterX/perimeterx-java-sdk/compare/X.XX.X...HEAD) (YYYY-MM-DD) - Added Dockerfile for web application example. +- Bugfix - Sensitive headers are now case-insensitive. ## [v6.11.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.11.0...HEAD) (2024-02-18) * Added base64-encoded request http method to captcha script query parameters on block pages diff --git a/src/main/java/com/perimeterx/models/configuration/PXConfiguration.java b/src/main/java/com/perimeterx/models/configuration/PXConfiguration.java index 4443f37f..a17fc9ca 100644 --- a/src/main/java/com/perimeterx/models/configuration/PXConfiguration.java +++ b/src/main/java/com/perimeterx/models/configuration/PXConfiguration.java @@ -38,6 +38,7 @@ import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; import static com.perimeterx.utils.Constants.*; @@ -87,7 +88,7 @@ public static void setPxLoggerSeverity(LoggerSeverity severity) { @Builder.Default @JsonProperty("px_sensitive_headers") - private Set sensitiveHeaders = new HashSet<>(Arrays.asList("cookieOrig", "cookies")); + private Set sensitiveHeaders = new HashSet<>(Arrays.asList("cookieorig", "cookies")); @Builder.Default @JsonProperty("px_max_buffer_length") @@ -404,5 +405,19 @@ public PXConfigurationBuilder appId(String appId) { } return this; } + + public PXConfigurationBuilder sensitiveHeaders(Set headers) { + if (headers == null) { + this.sensitiveHeaders$value = new HashSet<>(); + } else { + this.sensitiveHeaders$value = headers + .stream() + .map(String::toLowerCase) + .collect(Collectors.toSet()); + } + + this.sensitiveHeaders$set = true; + return this; + } } } diff --git a/src/main/java/com/perimeterx/utils/ActivityUtil.java b/src/main/java/com/perimeterx/utils/ActivityUtil.java index bad93f0a..21cd6261 100644 --- a/src/main/java/com/perimeterx/utils/ActivityUtil.java +++ b/src/main/java/com/perimeterx/utils/ActivityUtil.java @@ -13,7 +13,8 @@ public class ActivityUtil { return null; } return headers.entrySet().stream() - .filter(entry -> !sensitiveHeaders.contains(entry.getKey())) + .filter(entry -> entry != null && entry.getKey() != null) + .filter(entry -> !sensitiveHeaders.contains(entry.getKey().toLowerCase())) .map(entry -> new ActivityHeader(entry.getKey(), entry.getValue())).collect(Collectors.toList()); } diff --git a/src/test/java/com/perimeterx/models/PXConfigurationTest.java b/src/test/java/com/perimeterx/models/PXConfigurationTest.java index ba4e8f72..15f4ccac 100644 --- a/src/test/java/com/perimeterx/models/PXConfigurationTest.java +++ b/src/test/java/com/perimeterx/models/PXConfigurationTest.java @@ -39,4 +39,48 @@ public void testMergeConfigurations() throws FileNotFoundException { Assert.assertEquals(pxConfiguration.getModuleMode(), ModuleMode.MONITOR); Assert.assertEquals(pxConfiguration.getRemoteConfigurationInterval(), 1); } + + @Test + public void testSensitiveHeadersDefaultValue() { + PXConfiguration configuration = PXConfiguration.builder() + .appId("appId") + .cookieKey("cookieKey") + .authToken("authToken") + .build(); + + Assert.assertEquals(configuration.getSensitiveHeaders(), new HashSet<>(Arrays.asList("cookieorig", "cookies"))); + } + @Test + public void testSensitiveHeadersNonDefaultValues() { + PXConfiguration configuration = PXConfiguration.builder() + .appId("appId") + .cookieKey("cookieKey") + .authToken("authToken") + .sensitiveHeaders(new HashSet<>(Arrays.asList("a","b","c"))) + .build(); + + Assert.assertEquals(configuration.getSensitiveHeaders(), new HashSet<>(Arrays.asList("a","b","c"))); + } + @Test + public void testSensitiveHeadersNonDefaultWithUpperCaseValues() { + PXConfiguration configuration = PXConfiguration.builder() + .appId("appId") + .cookieKey("cookieKey") + .authToken("authToken") + .sensitiveHeaders(new HashSet<>(Arrays.asList("a","B","c"))) + .build(); + + Assert.assertEquals(configuration.getSensitiveHeaders(), new HashSet<>(Arrays.asList("a","b","c"))); + } + @Test + public void testSensitiveHeadersNullValue() { + PXConfiguration configuration = PXConfiguration.builder() + .appId("appId") + .cookieKey("cookieKey") + .authToken("authToken") + .sensitiveHeaders(null) + .build(); + + Assert.assertEquals(configuration.getSensitiveHeaders(), new HashSet<>()); + } } From f335f4b522a156faf5c081eda11178a1331b648a Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Tue, 20 Feb 2024 17:32:59 +0200 Subject: [PATCH 04/20] Block page align to spec. --- CHANGELOG.md | 1 + px_metadata.json | 2 -- src/main/java/com/perimeterx/models/PXContext.java | 2 +- .../api/blockhandler/templates/captcha_template.mustache | 5 +---- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c46860b1..6cae3b86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [vX.XX.X](https://github.com/PerimeterX/perimeterx-java-sdk/compare/X.XX.X...HEAD) (YYYY-MM-DD) - Added Dockerfile for web application example. - Bugfix - Sensitive headers are now case-insensitive. +- Block page HTML align with spec. ## [v6.11.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.11.0...HEAD) (2024-02-18) * Added base64-encoded request http method to captcha script query parameters on block pages diff --git a/px_metadata.json b/px_metadata.json index 548bdd6f..a0732a64 100644 --- a/px_metadata.json +++ b/px_metadata.json @@ -49,8 +49,6 @@ "test_block_page_captcha_response_contains_http_reason_phrase", "test_cookie_v3_cookie_decryption_failed_iterations_above_max_allowed_value", "test_cookie_v3_cookie_validation_failed_big_cookie", - "test_block_page_captcha_response_mobile", - "test_block_page_captcha_response_web", "test_block_page_captcha_response_with_special_char_request_web" ] } diff --git a/src/main/java/com/perimeterx/models/PXContext.java b/src/main/java/com/perimeterx/models/PXContext.java index bdd0f242..ece56cff 100644 --- a/src/main/java/com/perimeterx/models/PXContext.java +++ b/src/main/java/com/perimeterx/models/PXContext.java @@ -530,7 +530,7 @@ private boolean checkSensitiveRouteRegex(Set sensitiveRoutes, String uri } public String getCollectorURL() { - return String.format("%s%s%s", Constants.API_COLLECTOR_PREFIX, appId, Constants.API_COLLECTOR_POSTFIX); + return pxConfiguration.getCollectorUrl(); } public void setCookieVersion(String cookieVersion) { diff --git a/src/main/resources/com/perimeterx/api/blockhandler/templates/captcha_template.mustache b/src/main/resources/com/perimeterx/api/blockhandler/templates/captcha_template.mustache index 74fb7f95..4a1503bf 100644 --- a/src/main/resources/com/perimeterx/api/blockhandler/templates/captcha_template.mustache +++ b/src/main/resources/com/perimeterx/api/blockhandler/templates/captcha_template.mustache @@ -6,7 +6,7 @@ Access to this page has been denied {{#cssRef}} - + {{/cssRef}} @@ -20,7 +20,6 @@ window._pxJsClientSrc = '{{{jsClientSrc}}}'; window._pxMobile = {{isMobile}}; window._pxFirstPartyEnabled = {{firstPartyEnabled}}; - var pxCaptchaSrc = '{{{blockScript}}}'; var script = document.createElement('script'); script.src = pxCaptchaSrc; @@ -29,7 +28,6 @@ var onScriptErrorCalled; document.head.appendChild(script); var timeoutID = setTimeout(onScriptError, 5000); - function onScriptLoad() { clearTimeout(timeoutID); setTimeout(function() { @@ -59,7 +57,6 @@ function isCaptchaNotLoaded() { return !document.querySelector('div'); } - window._pxOnError = function () { var style = document.createElement('style'); style.innerText = '@import url(https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap);body{background-color:#fafbfc}.px-captcha-error-container{position:fixed;height:340px;background-color:#fff;font-family:Roboto,sans-serif}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:67px 0 33px;font-weight:500;line-height:.83;text-align:center}.px-captcha-error-message{color:#f0f1f2;font-size:18px;margin:0 0 29px;line-height:1.33;text-align:center}.px-captcha-error-button{text-align:center;line-height:48px;width:253px;margin:auto;border-radius:50px;border:solid 1px #f0f1f2;font-size:20px;color:#f0f1f2}.px-captcha-error-wrapper{margin:18px 0 0}div.px-captcha-error{margin:auto;text-align:center;width:400px;height:30px;font-size:12px;background-color:#fcf0f2;color:#ce0e2d}img.px-captcha-error{margin:6px 8px -2px 0}.px-captcha-error-refid{border-top:solid 1px #f0eeee;height:27px;margin:13px 0 0;border-radius:0 0 3px 3px;background-color:#fafbfc;font-size:10px;line-height:2.5;text-align:center;color:#b1b5b8}@media (min-width:620px){.px-captcha-error-container{width:530px;top:50%;left:50%;margin-top:-170px;margin-left:-265px;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (min-width:481px) and (max-width:620px){.px-captcha-error-container{width:85%;top:50%;left:50%;margin-top:-170px;margin-left:-42.5%;border-radius:3px;box-shadow:0 2px 9px -1px rgba(0,0,0,.13)}}@media (max-width:480px){body{background-color:#fff}.px-captcha-error-header{color:#f0f1f2;font-size:29px;margin:55px 0 33px}.px-captcha-error-container{width:530px;top:50%;left:50%;margin-top:-170px;margin-left:-265px}.px-captcha-error-refid{position:fixed;width:100%;left:0;bottom:0;border-radius:0;font-size:14px;line-height:2}}@media (max-width:390px){div.px-captcha-error{font-size:10px}.px-captcha-error-refid{font-size:11px;line-height:2.5}}'; From b87423f2664e613b138d5a1af99a2f716c257ed2 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Wed, 21 Feb 2024 17:15:35 +0200 Subject: [PATCH 05/20] Demo app supports special characters in URL --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index a09839ce..e1ab3293 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,4 +24,6 @@ COPY web/src/main/resources/ /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/src/ EXPOSE 8080 +ENV CATALINA_OPTS="-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true" + CMD ["catalina.sh", "run"] \ No newline at end of file From 3ff0e85ca56db3ace8c34e85789b5ce9a149cde9 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Thu, 22 Feb 2024 16:57:14 +0200 Subject: [PATCH 06/20] CI Process --- .github/workflows/ci_e2e.yaml | 147 ++++++++++++++++++++++++++++++++ CHANGELOG.md | 1 + ci_files/build_cluster.sh | 65 ++++++++++++++ ci_files/enforcer-config.json | 120 ++++++++++++++++++++++++++ ci_files/enforcer-values.yaml | 4 + ci_files/spec-tests-values.yaml | 5 ++ px_metadata.json | 3 +- 7 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci_e2e.yaml create mode 100755 ci_files/build_cluster.sh create mode 100644 ci_files/enforcer-config.json create mode 100644 ci_files/enforcer-values.yaml create mode 100644 ci_files/spec-tests-values.yaml diff --git a/.github/workflows/ci_e2e.yaml b/.github/workflows/ci_e2e.yaml new file mode 100644 index 00000000..ff815d4c --- /dev/null +++ b/.github/workflows/ci_e2e.yaml @@ -0,0 +1,147 @@ +name: E2E Tests + +on: + pull_request + +jobs: + + extract_metadata: + runs-on: ubuntu-latest + name: Extract supported_features + outputs: + supported-features: ${{ steps.supported-features.outputs.value }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + - name: extract supported features + id: supported-features + run: echo "value=$(node -p -e "require('./px_metadata.json').supported_features?.join(' or ') || ''")" >> "$GITHUB_OUTPUT" + + + CI: + name: "E2E tests" + env: + MOCK_COLLECTOR_IMAGE_TAG: 1.3.5 + SAMPLE_SITE_IMAGE_TAG: 1.0.0 + ENFORCER_SPEC_TESTS_IMAGE_TAG: 1.8.1 + + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: + - extract_metadata + + steps: + + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Set up Docker + uses: docker/setup-buildx-action@v3 + + - name: Build local cluster + run: ./ci_files/build_cluster.sh + + - name: Build Enforcer Docker image + run: | + docker build . -t localhost:5001/java-enforcer-sample-site:$SAMPLE_SITE_IMAGE_TAG && \ + docker push localhost:5001/java-enforcer-sample-site:$SAMPLE_SITE_IMAGE_TAG + + - uses: azure/setup-helm@v3 + with: + version: '3.14.1' + + - name: Clone helm charts repo - mock-collector + uses: actions/checkout@v4 + with: + repository: PerimeterX/connect-helm-charts + token: ${{ secrets.CONNECT_PULL_TOKEN }} + ref: mock-collector-0.1.1 + path: ./deploy_charts/mock-collector + + + - name: Clone helm charts repo - enforcer-tests + uses: actions/checkout@v4 + with: + repository: PerimeterX/connect-helm-charts + token: ${{ secrets.CONNECT_PULL_TOKEN }} + ref: enforcer-spec-tests-0.7.1 + path: ./deploy_charts/enforcer-spec-tests + + + - name: Clone helm charts repo - sample-site + uses: actions/checkout@v4 + with: + repository: PerimeterX/connect-helm-charts + token: ${{ secrets.CONNECT_PULL_TOKEN }} + ref: sample-site-0.5.0 + path: ./deploy_charts/sample-site + + - name: Set up Google Cloud SDK + id: 'auth' + uses: 'google-github-actions/auth@v2' + with: + credentials_json: '${{ secrets.GCR_SA_KEY }}' + + - name: Configure Docker credentials + run: | + gcloud auth configure-docker gcr.io + + - name: pull mock collector image + run: | + docker pull gcr.io/px-docker-repo/connecteam/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG && \ + docker tag gcr.io/px-docker-repo/connecteam/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG localhost:5001/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG && \ + docker push localhost:5001/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG + + - name: deploy mock collector + run: | + helm install mock-collector ./deploy_charts/mock-collector/charts/mock-collector \ + --set image.repository=localhost:5001/mock-collector \ + --set image.tag=$MOCK_COLLECTOR_IMAGE_TAG \ + --set imagePullPolicy=Always --wait + + - name: set secrets in enforcer config + run: | + cat ./ci_files/enforcer-config.json |\ + jq '.px_app_id="${{ secrets.PX_APP_ID }}"' |\ + jq '.px_cookie_secret="${{ secrets.TEST_COOKIE_SECRET }}"' |\ + jq '.px_auth_token="${{ secrets.PX_AUTH_TOKEN }}"' > /tmp/enforcer-config.json + + - name: log enforcer config + run: cat /tmp/enforcer-config.json + + - name: deploy java enforcer + run: | + helm install java-enforcer ./deploy_charts/sample-site/charts/sample-site \ + -f ./ci_files/enforcer-values.yaml \ + --set image.name=localhost:5001/java-enforcer-sample-site \ + --set image.tag=$SAMPLE_SITE_IMAGE_TAG \ + --set-file enforcerConfig.content=/tmp/enforcer-config.json \ + --wait + + - name: pull enforcer tests image + run: | + docker pull gcr.io/px-docker-repo/connecteam/enforcer-specs-tests:$ENFORCER_SPEC_TESTS_IMAGE_TAG && \ + docker tag gcr.io/px-docker-repo/connecteam/enforcer-specs-tests:$ENFORCER_SPEC_TESTS_IMAGE_TAG localhost:5001/enforcer-spec-tests:$ENFORCER_SPEC_TESTS_IMAGE_TAG && \ + docker push localhost:5001/enforcer-spec-tests:$ENFORCER_SPEC_TESTS_IMAGE_TAG + + - name: run enforcer tests + run: | + helm install enforcer-spec-tests ./deploy_charts/enforcer-spec-tests/charts/enforcer-spec-tests \ + --set image.tag=$ENFORCER_SPEC_TESTS_IMAGE_TAG \ + --set cookieSecret=${{ secrets.TEST_COOKIE_SECRET }} \ + --set supportedFeatures="${{ needs.extract_metadata.outputs.supported-features }}" \ + --set authToken="${{ secrets.PX_AUTH_TOKEN }}" \ + --set appId=${{ secrets.PX_APP_ID }} \ + --set-file enforcerMetadataContent=./px_metadata.json \ + -f ./ci_files/spec-tests-values.yaml \ + --wait \ + --timeout 60m0s \ + --wait-for-jobs + + - name: get tests results + if: ${{ always() }} + run: kubectl logs job/enforcer-spec-tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cae3b86..ac9df244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Added Dockerfile for web application example. - Bugfix - Sensitive headers are now case-insensitive. - Block page HTML align with spec. +- Automatically running e2e tests on pull request. ## [v6.11.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.11.0...HEAD) (2024-02-18) * Added base64-encoded request http method to captcha script query parameters on block pages diff --git a/ci_files/build_cluster.sh b/ci_files/build_cluster.sh new file mode 100755 index 00000000..429bcc09 --- /dev/null +++ b/ci_files/build_cluster.sh @@ -0,0 +1,65 @@ +#!/bin/sh +set -o errexit + + +# 2. Create registry container unless it already exists +reg_name='kind-registry' +reg_port='5001' +if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then + docker run \ + -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ + registry:2 +fi + +# 3. Create kind cluster with containerd registry config dir enabled +# extraPortMapping - for mapping traffic from outside the cluster to the localstack inside the cluster. +# by that, every traffic to localhost:4566 will arrive to the cluster and will be map inside the cluster to port 31566 - localstack. +cat < Date: Sun, 25 Feb 2024 11:47:02 +0200 Subject: [PATCH 07/20] Custom parameters in demo app (implemented according to tests). --- px_metadata.json | 1 - web/src/main/java/com/web/Config.java | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/px_metadata.json b/px_metadata.json index f7d5495a..63d94547 100644 --- a/px_metadata.json +++ b/px_metadata.json @@ -39,7 +39,6 @@ "header_based_logger" ], "excluded_tests": [ - "test_custom_parameters_custom_param_appear_in_activities", "test_pxde_extraction_(s2s|unverified|verified)", "test_risk_cookie_valid_cookie_with_user_agent_of_max_length", "test_path_parsing_in_(block|page_requested|risk_api|additional_s2s)\\[with_dots", diff --git a/web/src/main/java/com/web/Config.java b/web/src/main/java/com/web/Config.java index 6d8f023a..1d7333f6 100644 --- a/web/src/main/java/com/web/Config.java +++ b/web/src/main/java/com/web/Config.java @@ -5,6 +5,7 @@ import com.perimeterx.models.configuration.ModuleMode; import com.perimeterx.models.configuration.PXConfiguration; import com.perimeterx.models.configuration.credentialsIntelligenceconfig.CILoginMap; +import com.perimeterx.models.risk.CustomParameters; import org.json.JSONArray; import org.json.JSONObject; @@ -163,6 +164,17 @@ public PXConfiguration getPxConfiguration() { } + builder.customParametersExtraction(req -> { + CustomParameters customParameters = new CustomParameters(); + customParameters.customParam1 = "test1"; + customParameters.customParam2 = "test2"; + customParameters.customParam3 = "3"; + customParameters.customParam4 = "4"; + customParameters.customParam5 = "5"; + customParameters.customParam6 = "6"; + return customParameters; + }); + return builder.build(); } From ff7b89a5dc0ee359fcfed25747b48309580d68af Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 25 Feb 2024 12:00:08 +0200 Subject: [PATCH 08/20] Removing test_block_page_captcha_response_with_special_char_request_web from excluded tests --- px_metadata.json | 1 - 1 file changed, 1 deletion(-) diff --git a/px_metadata.json b/px_metadata.json index 63d94547..d5c76f18 100644 --- a/px_metadata.json +++ b/px_metadata.json @@ -48,7 +48,6 @@ "test_block_page_captcha_response_contains_http_reason_phrase", "test_cookie_v3_cookie_decryption_failed_iterations_above_max_allowed_value", "test_cookie_v3_cookie_validation_failed_big_cookie", - "test_block_page_captcha_response_with_special_char_request_web", "test_client_ip_extraction_order_risk_api" ] } From 0dc31265f260727542484062651263988959ac5d Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 25 Feb 2024 14:54:48 +0200 Subject: [PATCH 09/20] Adding CI process to versions on PR to master. --- .github/workflows/ci_verify_version.yaml | 44 ++++++++++++++++++++++++ CHANGELOG.md | 3 +- ci_files/verify-version-inc.sh | 8 +++++ web/pom.xml | 3 +- 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci_verify_version.yaml create mode 100755 ci_files/verify-version-inc.sh diff --git a/.github/workflows/ci_verify_version.yaml b/.github/workflows/ci_verify_version.yaml new file mode 100644 index 00000000..9fcd468a --- /dev/null +++ b/.github/workflows/ci_verify_version.yaml @@ -0,0 +1,44 @@ +name: Verify version +on: + pull_request: + branches: + - master +jobs: + verify-version: + name: Verify version + runs-on: ubuntu-latest + steps: + - name: Checkout code - ${{ github.base_ref }} + uses: actions/checkout@v4 + with: + ref: ${{ github.base_ref }} + + - name: Get ${{ github.base_ref }} SDK version + id: base-version + run: echo "project=$( mvn help:evaluate -Dexpression=project.version -q -DforceStdout )" >> "$GITHUB_OUTPUT" + + - name: Checkout code - current commit + uses: actions/checkout@v4 + + - name: Get current SDK versions + id: new-version + run: | + echo "project=$( mvn help:evaluate -Dexpression=project.version -q -DforceStdout )" >> "$GITHUB_OUTPUT" && \ + echo "px_metadata=$( cat px_metadata.json | jq -r '.version' )" >> "$GITHUB_OUTPUT" && \ + echo "demo_app_dependency=$( mvn help:evaluate -Dexpression=com.perimeterx.version -q -DforceStdout -f web/pom.xml)" >> "$GITHUB_OUTPUT" + + - name: Verify same version + run: | + [ $PROJECT_VERSION = $PX_METADATA_VERSION ] && \ + [ $PROJECT_VERSION = $DEMO_APP_DEPENDENCY_VERSION ] + env: + PROJECT_VERSION: ${{ steps.new-version.outputs.project }} + PX_METADATA_VERSION: ${{ steps.new-version.outputs.px_metadata }} + DEMO_APP_DEPENDENCY_VERSION: ${{ steps.new-version.outputs.demo_app_dependency }} + + - name: Verify version increment + run: ./ci_files/verify-version-inc.sh $BASE_VERSION $NEW_VERSION + env: + NEW_VERSION: ${{ steps.new-version.outputs.project }} + BASE_VERSION: ${{ steps.base-version.outputs.project }} + diff --git a/CHANGELOG.md b/CHANGELOG.md index ac9df244..aefb1899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,8 @@ - Added Dockerfile for web application example. - Bugfix - Sensitive headers are now case-insensitive. - Block page HTML align with spec. -- Automatically running e2e tests on pull request. +- Automatically running e2e tests on pull request. +- Automatically verify version on pull request to master. ## [v6.11.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.11.0...HEAD) (2024-02-18) * Added base64-encoded request http method to captcha script query parameters on block pages diff --git a/ci_files/verify-version-inc.sh b/ci_files/verify-version-inc.sh new file mode 100755 index 00000000..30a349b7 --- /dev/null +++ b/ci_files/verify-version-inc.sh @@ -0,0 +1,8 @@ +versionlte() { + [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ] +} +versionlt() { + [ "$1" != "$2" ] && versionlte "$1" "$2" +} + +versionlt "$1" "$2" \ No newline at end of file diff --git a/web/pom.xml b/web/pom.xml index f944028d..536fd145 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -25,7 +25,7 @@ com.perimeterx perimeterx-sdk - 6.11.0 + ${com.perimeterx.version} compile @@ -64,6 +64,7 @@ 8 8 + 6.11.0 From 6aaaed6beae29d02ec0fb4848a0857fa195981db Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 25 Feb 2024 12:44:51 +0200 Subject: [PATCH 10/20] Auto deploy --- .github/workflows/cd.yaml | 36 ++++++++++++++++++++++++++++++++++++ CHANGELOG.md | 1 + 2 files changed, 37 insertions(+) create mode 100644 .github/workflows/cd.yaml diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml new file mode 100644 index 00000000..6623b701 --- /dev/null +++ b/.github/workflows/cd.yaml @@ -0,0 +1,36 @@ +name: Deploy to maven +on: + push: + branches: + - master +jobs: + deploy: + name: Deploy to maven + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'adopt' + + - name: Import GPG key + run: echo -n "$GPG_SIGNING_KEY" | base64 --decode | gpg --import + env: + # To generate a new GPG key run the following command in your local terminal: + # gpg --export-secret-keys -a "" | base64 + GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} + - name: Log GPG keys + run: gpg --list-secret-keys --keyid-format LONG + + - name: Deploy a new version + run: mvn clean deploy -P build-extras,sign --settings deploy/mvnsettings.xml + env: + GPG_KEY_NAME: ${{ vars.GPG_KEY_NAME }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + OSSRH_JIRA_USERNAME: ${{ secrets.OSSRH_JIRA_USERNAME }} + OSSRH_JIRA_PASSWORD: ${{ secrets.OSSRH_JIRA_PASSWORD }} + diff --git a/CHANGELOG.md b/CHANGELOG.md index aefb1899..f3e5d50d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Block page HTML align with spec. - Automatically running e2e tests on pull request. - Automatically verify version on pull request to master. +- Automatically deploying a new release on merge to master. ## [v6.11.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.11.0...HEAD) (2024-02-18) * Added base64-encoded request http method to captcha script query parameters on block pages From be26734dc4b1437c8ef18ba182b481cd3df51ea6 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 25 Feb 2024 16:19:05 +0200 Subject: [PATCH 11/20] Auto create release on merge to master --- .github/workflows/cd.yaml | 40 +++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 6623b701..01a1173d 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -1,15 +1,48 @@ -name: Deploy to maven +name: CD on: push: branches: - master jobs: - deploy: + extract_version: + runs-on: ubuntu-latest + name: Extract release version + outputs: + version: ${{ steps.version.outputs.value }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18.x' + - name: Get package version + id: version + run: echo "value=$(node -p -e "require('./px_metadata.json').version")" >> "$GITHUB_OUTPUT" + + create_release: + runs-on: ubuntu-latest + needs: extract_version + name: Create release on GitHub + permissions: + contents: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - run: gh release create v${{ needs.extract_version.outputs.version }} --generate-notes -t "Version ${{ needs.extract_version.outputs.version }}" + env: + GITHUB_TOKEN: ${{ github.TOKEN }} + shell: bash + name: Creates a release in GitHub + + publish: name: Deploy to maven + needs: + - create_release runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up JDK 8 uses: actions/setup-java@v3 @@ -33,4 +66,3 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} OSSRH_JIRA_USERNAME: ${{ secrets.OSSRH_JIRA_USERNAME }} OSSRH_JIRA_PASSWORD: ${{ secrets.OSSRH_JIRA_PASSWORD }} - From 16d0673d94abb17cfec7db3f88af14e976cc5e79 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Sun, 25 Feb 2024 17:26:12 +0200 Subject: [PATCH 12/20] Release 6.12.0 --- CHANGELOG.md | 2 +- README.md | 2 +- pom.xml | 2 +- px_metadata.json | 2 +- web/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3e5d50d..c5ace89a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [vX.XX.X](https://github.com/PerimeterX/perimeterx-java-sdk/compare/X.XX.X...HEAD) (YYYY-MM-DD) +## [v6.12.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.12.0...HEAD) (2024-02-25) - Added Dockerfile for web application example. - Bugfix - Sensitive headers are now case-insensitive. - Block page HTML align with spec. diff --git a/README.md b/README.md index 62b8ab47..6e65477a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # [PerimeterX](http://www.perimeterx.com) Java SDK -> Latest stable version: [v6.11.0](https://search.maven.org/#artifactdetails%7Ccom.perimeterx%7Cperimeterx-sdk%7C6.10.0%7Cjar) +> Latest stable version: [v6.12.0](https://search.maven.org/#artifactdetails%7Ccom.perimeterx%7Cperimeterx-sdk%7C6.12.0%7Cjar) ## Table of Contents diff --git a/pom.xml b/pom.xml index 9c097abe..583bdef2 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ PerimeterX JAVA SDK com.perimeterx perimeterx-sdk - 6.11.0 + 6.12.0 jar PerimeterX Java SDK diff --git a/px_metadata.json b/px_metadata.json index d5c76f18..1172ab20 100644 --- a/px_metadata.json +++ b/px_metadata.json @@ -1,5 +1,5 @@ { - "version": "6.11.0", + "version": "6.12.0", "supported_features": [ "advanced_blocking_response", "bypass_monitor_header", diff --git a/web/pom.xml b/web/pom.xml index 536fd145..df937f8c 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -64,7 +64,7 @@ 8 8 - 6.11.0 + 6.12.0 From 16cb5199e1552895775fb6b64046d8c5b5378957 Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Wed, 20 Mar 2024 14:03:18 +0200 Subject: [PATCH 13/20] update log4j -> log4j-core --- web/pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/pom.xml b/web/pom.xml index df937f8c..5861b4d0 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -38,10 +38,11 @@ slf4j-log4j12 1.7.25 + - log4j - log4j - 1.2.17 + org.apache.logging.log4j + log4j-core + 2.23.1 From cb4dde213bded77b0c96efbc233d52a34f25cdcc Mon Sep 17 00:00:00 2001 From: guyeisenbach Date: Wed, 20 Mar 2024 14:21:59 +0200 Subject: [PATCH 14/20] upgrade snakeyaml to 2.0 --- examples/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pom.xml b/examples/pom.xml index 0ba42d4e..ef5bdd88 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -70,7 +70,7 @@ org.yaml snakeyaml - 1.28 + 2.0 From bbdae2d99dadf7c164db13e06713792c8f5df8c9 Mon Sep 17 00:00:00 2001 From: Dan Bezalel Date: Wed, 20 Mar 2024 14:59:01 +0200 Subject: [PATCH 15/20] Upgraded spring-web to 5.3.7 --- examples/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pom.xml b/examples/pom.xml index ef5bdd88..9b4fe988 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -58,7 +58,7 @@ org.springframework spring-web - 5.3.6 + 5.3.7 From abd25a7ba08f298e434f4c73908bd962d313806a Mon Sep 17 00:00:00 2001 From: Dan Bezalel Date: Thu, 21 Mar 2024 16:23:32 +0200 Subject: [PATCH 16/20] Added Enforcer Fuzzer to CI --- .github/workflows/fuzzer.yaml | 170 ++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 .github/workflows/fuzzer.yaml diff --git a/.github/workflows/fuzzer.yaml b/.github/workflows/fuzzer.yaml new file mode 100644 index 00000000..3481378e --- /dev/null +++ b/.github/workflows/fuzzer.yaml @@ -0,0 +1,170 @@ +name: Fuzzing Test + +on: + pull_request + +jobs: + + extract_version: + runs-on: ubuntu-latest + name: Extract release version + outputs: + supported-features: ${{ steps.version.outputs.value }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 'latest' + - name: Get package version + id: version + run: echo "value=$(node -p -e "require('./px_metadata.json').version")" >> "$GITHUB_OUTPUT" + + + Fuzzing: + name: "Fuzzing Test" + env: + MOCK_COLLECTOR_IMAGE_TAG: 1.3.6 + FUZZER_TAG: 1.0.3 + SAMPLE_SITE_IMAGE_TAG: 1.0.0 + ENFORCER_TAG: ${{ needs.extract_version.outputs.version }} + + strategy: + matrix: + mode: [ "url", "first_party", "headers", "cookies", "user_agent" ] + + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: + - extract_version + + steps: + + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Set up Docker + uses: docker/setup-buildx-action@v3 + + - name: Build local cluster + run: ./ci_files/build_cluster.sh + + - name: Build Enforcer Docker image + run: | + docker build . -t localhost:5001/java-enforcer-sample-site:$SAMPLE_SITE_IMAGE_TAG && \ + docker push localhost:5001/java-enforcer-sample-site:$SAMPLE_SITE_IMAGE_TAG + + - uses: azure/setup-helm@v3 + with: + version: '3.14.2' + + - name: Clone helm charts repo - mock-collector + uses: actions/checkout@v4 + with: + repository: PerimeterX/connect-helm-charts + token: ${{ secrets.CONNECT_PULL_TOKEN }} + ref: mock-collector-0.1.1 + path: ./deploy_charts/mock-collector + + - name: Clone helm charts repo - fuzzer + uses: actions/checkout@v4 + with: + repository: PerimeterX/connect-helm-charts + token: ${{ secrets.CONNECT_PULL_TOKEN }} + ref: fuzzer-0.2.0 + path: ./deploy_charts/fuzzer + + - name: Clone helm charts repo - sample-site + uses: actions/checkout@v4 + with: + repository: PerimeterX/connect-helm-charts + token: ${{ secrets.CONNECT_PULL_TOKEN }} + ref: sample-site-0.5.0 + path: ./deploy_charts/sample-site + + - name: Set up Google Cloud SDK + id: 'auth' + uses: 'google-github-actions/auth@v2' + with: + credentials_json: '${{ secrets.GCR_SA_KEY }}' + + - name: Configure Docker credentials + run: | + gcloud auth configure-docker gcr.io + + - name: pull mock collector image + run: | + docker pull gcr.io/px-docker-repo/connecteam/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG && \ + docker tag gcr.io/px-docker-repo/connecteam/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG localhost:5001/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG && \ + docker push localhost:5001/mock-collector:$MOCK_COLLECTOR_IMAGE_TAG + + - name: deploy mock collector + run: | + helm install mock-collector ./deploy_charts/mock-collector/charts/mock-collector \ + --set image.repository=localhost:5001/mock-collector \ + --set image.tag=$MOCK_COLLECTOR_IMAGE_TAG \ + --set imagePullPolicy=Always --wait + + - name: set secrets in enforcer config + run: | + cat ./ci_files/enforcer-config.json |\ + jq '.px_app_id="${{ secrets.PX_APP_ID }}"' |\ + jq '.px_cookie_secret="${{ secrets.TEST_COOKIE_SECRET }}"' |\ + jq '.px_auth_token="${{ secrets.PX_AUTH_TOKEN }}"' > /tmp/enforcer-config.json + + - name: log enforcer config + run: cat /tmp/enforcer-config.json + + - name: deploy java enforcer + run: | + helm install java-enforcer ./deploy_charts/sample-site/charts/sample-site \ + -f ./ci_files/enforcer-values.yaml \ + --set image.name=localhost:5001/java-enforcer-sample-site \ + --set image.tag=$SAMPLE_SITE_IMAGE_TAG \ + --set-file enforcerConfig.content=/tmp/enforcer-config.json \ + --wait + + - name: pull fuzzer image + run: | + docker pull gcr.io/px-docker-repo/connecteam/connect-enforcer-fuzzer:$FUZZER_TAG && \ + docker tag gcr.io/px-docker-repo/connecteam/connect-enforcer-fuzzer:$FUZZER_TAG localhost:5001/connect-enforcer-fuzzer:$FUZZER_TAG && \ + docker push localhost:5001/connect-enforcer-fuzzer:$FUZZER_TAG + + - name: run fuzzer + run: | + helm install fuzzer ./deploy_charts/fuzzer/charts/fuzzer \ + --set image.repository=localhost:5001/connect-enforcer-fuzzer \ + --set image.tag=$FUZZER_TAG \ + --set appId=$PX_APP_ID \ + --set mode=$FUZZ_MODE \ + --set siteURL=$SITE_URL \ + --wait \ + --timeout 60m0s \ + --wait-for-jobs + env: + FUZZ_MODE: ${{ matrix.mode }} + PX_APP_ID: ${{ secrets.PX_APP_ID }} + SITE_URL: "http://java-enforcer-sample-site:3000" + + - name: get tests results + if: ${{ always() }} + run: kubectl logs job/fuzzer-enforcer-fuzzer + + - name: run enforcer tests + run: | + helm install enforcer-spec-tests ./deploy_charts/enforcer-spec-tests/charts/enforcer-spec-tests \ + --set image.tag=$ENFORCER_SPEC_TESTS_IMAGE_TAG \ + --set cookieSecret=${{ secrets.TEST_COOKIE_SECRET }} \ + --set supportedFeatures="${{ needs.extract_metadata.outputs.supported-features }}" \ + --set authToken="${{ secrets.PX_AUTH_TOKEN }}" \ + --set appId=${{ secrets.PX_APP_ID }} \ + --set-file enforcerMetadataContent=./px_metadata.json \ + -f ./ci_files/spec-tests-values.yaml \ + --wait \ + --timeout 60m0s \ + --wait-for-jobs + + - name: get tests results + if: ${{ always() }} + run: kubectl logs job/enforcer-spec-tests From 7f2a6458d7e606cf1190a7382eafa4134d9c042f Mon Sep 17 00:00:00 2001 From: Dan Bezalel Date: Thu, 21 Mar 2024 16:29:44 +0200 Subject: [PATCH 17/20] Updated Fuzzer CI --- .github/workflows/fuzzer.yaml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/fuzzer.yaml b/.github/workflows/fuzzer.yaml index 3481378e..1a074f50 100644 --- a/.github/workflows/fuzzer.yaml +++ b/.github/workflows/fuzzer.yaml @@ -150,21 +150,3 @@ jobs: - name: get tests results if: ${{ always() }} run: kubectl logs job/fuzzer-enforcer-fuzzer - - - name: run enforcer tests - run: | - helm install enforcer-spec-tests ./deploy_charts/enforcer-spec-tests/charts/enforcer-spec-tests \ - --set image.tag=$ENFORCER_SPEC_TESTS_IMAGE_TAG \ - --set cookieSecret=${{ secrets.TEST_COOKIE_SECRET }} \ - --set supportedFeatures="${{ needs.extract_metadata.outputs.supported-features }}" \ - --set authToken="${{ secrets.PX_AUTH_TOKEN }}" \ - --set appId=${{ secrets.PX_APP_ID }} \ - --set-file enforcerMetadataContent=./px_metadata.json \ - -f ./ci_files/spec-tests-values.yaml \ - --wait \ - --timeout 60m0s \ - --wait-for-jobs - - - name: get tests results - if: ${{ always() }} - run: kubectl logs job/enforcer-spec-tests From 1b7dba1d0ecbca42c9b3a44123bdad0926a9b6de Mon Sep 17 00:00:00 2001 From: Dan Bezalel Date: Sun, 24 Mar 2024 10:38:21 +0200 Subject: [PATCH 18/20] Removed unused examples dir --- examples/pom.xml | 87 ------------------- examples/src/main/java/Application.java | 13 --- .../java/controllers/ExampleController.java | 14 --- examples/src/main/java/filters/PXFilter.java | 69 --------------- .../src/main/java/px/CustomBlockHandler.java | 28 ------ 5 files changed, 211 deletions(-) delete mode 100644 examples/pom.xml delete mode 100644 examples/src/main/java/Application.java delete mode 100644 examples/src/main/java/controllers/ExampleController.java delete mode 100644 examples/src/main/java/filters/PXFilter.java delete mode 100644 examples/src/main/java/px/CustomBlockHandler.java diff --git a/examples/pom.xml b/examples/pom.xml deleted file mode 100644 index 9b4fe988..00000000 --- a/examples/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - org.springframework.boot - spring-boot-starter-parent - 2.2.7.RELEASE - - 4.0.0 - jar - examples - - - - - org.springframework.boot - spring-boot-starter-web - 2.2.7.RELEASE - - - - com.perimeterx - perimeterx-sdk - 6.9.5 - - - - commons-io - commons-io - 2.8.0 - - - - com.fasterxml.jackson.core - jackson-databind - 2.11.4 - - - - org.apache.tomcat.embed - tomcat-embed-core - 10.0.5 - - - - junit - junit - 4.13.2 - - - - org.codehaus.plexus - plexus-utils - 3.3.0 - - - - org.springframework - spring-web - 5.3.7 - - - - org.apache.httpcomponents - httpclient - 4.5.13 - - - - org.yaml - snakeyaml - 2.0 - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - diff --git a/examples/src/main/java/Application.java b/examples/src/main/java/Application.java deleted file mode 100644 index 070cd160..00000000 --- a/examples/src/main/java/Application.java +++ /dev/null @@ -1,13 +0,0 @@ -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; - -@SpringBootApplication -@ComponentScan(basePackages = {"controllers", "filters"}) -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/examples/src/main/java/controllers/ExampleController.java b/examples/src/main/java/controllers/ExampleController.java deleted file mode 100644 index 8fd2a4ea..00000000 --- a/examples/src/main/java/controllers/ExampleController.java +++ /dev/null @@ -1,14 +0,0 @@ -package controllers; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class ExampleController { - - @RequestMapping("/") - public String example() { - return "Hello world"; - } - -} diff --git a/examples/src/main/java/filters/PXFilter.java b/examples/src/main/java/filters/PXFilter.java deleted file mode 100644 index 205d4979..00000000 --- a/examples/src/main/java/filters/PXFilter.java +++ /dev/null @@ -1,69 +0,0 @@ -package filters; - -import com.perimeterx.api.PXConfiguration; -import com.perimeterx.api.PerimeterX; -import com.perimeterx.models.configuration.ModuleMode; -import com.perimeterx.models.exceptions.PXException; -import px.CustomBlockHandler; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; -import java.io.IOException; - -/** - * Filter implementation based on PerimeterX SDK - */ -public class PXFilter implements Filter { - - private PerimeterX enforcer; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - // Creating filter configuration - PXConfiguration pxConf = new PXConfiguration.Builder() - .appId("") // Your PerimeterX application ID - .cookieKey("") // Should copy from RiskCookie section in https://console.perimeterx.com/botDefender/admin?page=policiesmgmt - .captchaEnabled(false) // This will trigger captcha validation flow when blocking - .moduleMode(ModuleMode.BLOCKING) - .authToken("") // PX Server request auth token to be copied from Token section in https://console.perimeterx.com/botDefender/admin?page=applicationsmgmt - .build(); - try { - this.enforcer = new PerimeterX(pxConf); - // This will set the blocking handler from the default one to the our custom block handler - // note that when we enable captcha logic we must use a blocking handler that display the appropriate html page with captcha - // for instance CaptchaBlockHandler that is included in the SDK - this.enforcer.setBlockHandler(new CustomBlockHandler()); - } catch (Exception e) { - // Could not init enforcer - } - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - - // The request wrapper enables to read the request multiple times. - request = new RequestWrapper((HttpServletRequest) request); - - // This will apply PerimeterX SDK logic on each request going through this filter - HttpServletResponse httpRes = (HttpServletResponse) servletResponse; - - try { - PXContext ctx = enforcer.pxVerify(httpReq, new HttpServletResponseWrapper(httpRes)); - if (ctx.isVerified()) { - filterChain.doFilter(servletRequest, servletResponse); - } - - // This enables to read the response, it should happen after the response was already sent to the client - response = new ResponseWrapper((HttpServletResponse) response); - pxFilter.pxPostVerify((ResponseWrapper) response, context); - } catch (PXException e) { - // ignoring error for now and passing the request - filterChain.doFilter(servletRequest, servletResponse); - } - } - - @Override - public void destroy() { - } -} diff --git a/examples/src/main/java/px/CustomBlockHandler.java b/examples/src/main/java/px/CustomBlockHandler.java deleted file mode 100644 index 687603af..00000000 --- a/examples/src/main/java/px/CustomBlockHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package px; - -import com.perimeterx.api.blockhandler.BlockHandler; -import com.perimeterx.models.PXContext; -import com.perimeterx.models.exceptions.PXException; - -import javax.servlet.http.HttpServletResponseWrapper; -import java.io.IOException; - -/** - * This will implement the BlockHandler interface which can later be set in PerimeterX object initializtion - */ -public class CustomBlockHandler implements BlockHandler { - - /** - * Simple block handler which set status code to be 403 add one header with score and write to page "You are blocked" - */ - @Override - public void handleBlocking(PXContext context, HttpServletResponseWrapper responseWrapper) throws PXException { - responseWrapper.setHeader("PX-Blocking-Score", String.valueOf(context.getScore())); - try { - responseWrapper.setStatus(403); - responseWrapper.getWriter().print("You are blocked"); - } catch (IOException e) { - e.printStackTrace(); - } - } -} From 1fcd4ea30af72d9d7de3013217870e85d9b1bf42 Mon Sep 17 00:00:00 2001 From: Dan Bezalel Date: Sun, 24 Mar 2024 16:32:49 +0200 Subject: [PATCH 19/20] Added vid validation in context creation --- src/main/java/com/perimeterx/models/PXContext.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/perimeterx/models/PXContext.java b/src/main/java/com/perimeterx/models/PXContext.java index ece56cff..4073cb55 100644 --- a/src/main/java/com/perimeterx/models/PXContext.java +++ b/src/main/java/com/perimeterx/models/PXContext.java @@ -404,8 +404,12 @@ private void setVidAndPxhd(Cookie[] cookies) { if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("_pxvid") || cookie.getName().equals("pxvid")) { - this.vid = cookie.getValue(); - this.vidSource = VidSource.VID_COOKIE; + if (isValidVid(cookie.getValue())) { + this.vid = cookie.getValue(); + this.vidSource = VidSource.VID_COOKIE; + } else { + logger.debug("setVidAndPxhd - invalid VID value was extracted"); + } } if (cookie.getName().equals("_pxhd")) { try { @@ -548,4 +552,10 @@ public boolean isBreachedAccount() { public boolean isContainCredentialsIntelligence() { return this.getLoginData() != null && this.getLoginData().getLoginCredentials() != null; } + + private boolean isValidVid(String vidCookieValue) { + Pattern vidPattern = Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", Pattern.CASE_INSENSITIVE); + Matcher matcher = vidPattern.matcher(vidCookieValue); + return matcher.matches(); + } } From 9754cba558c3b89bb65fc915772f9943f7cef42c Mon Sep 17 00:00:00 2001 From: Dan Bezalel Date: Wed, 27 Mar 2024 11:35:37 +0200 Subject: [PATCH 20/20] release v6.13.0 --- CHANGELOG.md | 6 ++++++ README.md | 2 +- pom.xml | 2 +- px_metadata.json | 2 +- web/pom.xml | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5ace89a..8c719b8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## [v6.13.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.13.0...HEAD) (2024-04-27) +- Added vid Validation for _pxvid extraction +- Added Enforcer Fuzzer as part of the CI process +- Updated log4j artifact version +- Removed `/examples` directory + ## [v6.12.0](https://github.com/PerimeterX/perimeterx-java-sdk/compare/6.12.0...HEAD) (2024-02-25) - Added Dockerfile for web application example. - Bugfix - Sensitive headers are now case-insensitive. diff --git a/README.md b/README.md index 6e65477a..b71c5e81 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # [PerimeterX](http://www.perimeterx.com) Java SDK -> Latest stable version: [v6.12.0](https://search.maven.org/#artifactdetails%7Ccom.perimeterx%7Cperimeterx-sdk%7C6.12.0%7Cjar) +> Latest stable version: [v6.13.0](https://search.maven.org/#artifactdetails%7Ccom.perimeterx%7Cperimeterx-sdk%7C6.13.0%7Cjar) ## Table of Contents diff --git a/pom.xml b/pom.xml index 583bdef2..2e174612 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ PerimeterX JAVA SDK com.perimeterx perimeterx-sdk - 6.12.0 + 6.13.0 jar PerimeterX Java SDK diff --git a/px_metadata.json b/px_metadata.json index 1172ab20..78e2a0f7 100644 --- a/px_metadata.json +++ b/px_metadata.json @@ -1,5 +1,5 @@ { - "version": "6.12.0", + "version": "6.13.0", "supported_features": [ "advanced_blocking_response", "bypass_monitor_header", diff --git a/web/pom.xml b/web/pom.xml index 5861b4d0..46665da7 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -65,7 +65,7 @@ 8 8 - 6.12.0 + 6.13.0