From 74eb6e2332939af0f4d984f6e814155002e218d5 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Fri, 29 Nov 2024 06:18:39 -0500 Subject: [PATCH] scanpolicies: Add workflow/script to generate updates based on rule tags - generate-scan-policies.js > ZAP standalone script to be used by a nightly docker image to craft the scan policies. - generate_policies.yml > The new workflow. Triggered by cron every Friday morning or manually via workflow_dispatch. Signed-off-by: kingthorin --- .github/scripts/generateScanPolicies.js | 81 +++++++++++++++++++++++++ .github/workflows/generate_policies.yml | 54 +++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 .github/scripts/generateScanPolicies.js create mode 100644 .github/workflows/generate_policies.yml diff --git a/.github/scripts/generateScanPolicies.js b/.github/scripts/generateScanPolicies.js new file mode 100644 index 00000000000..87a1cba0746 --- /dev/null +++ b/.github/scripts/generateScanPolicies.js @@ -0,0 +1,81 @@ +// This is a ZAP standalone script - it will only run in ZAP. +// It generates the scan policies for https://github.com/zaproxy/zap-extensions/tree/main/addOns/scanpolicies etc +// The policies are created after starting a ZAP nightly release with the '-addoninstall ascanrulesAlpha' option. + +const FileWriter = Java.type("java.io.FileWriter"); +const PrintWriter = Java.type("java.io.PrintWriter"); +const PolicyTag = Java.type("org.zaproxy.addon.commonlib.PolicyTag"); +const UTF_8 = Java.type("java.nio.charset.StandardCharsets").UTF_8; +const StringEscapeUtils = Java.type( + "org.apache.commons.text.StringEscapeUtils" +); + +const extAscan = control + .getExtensionLoader() + .getExtension(org.zaproxy.zap.extension.ascan.ExtensionActiveScan.NAME); + +const plugins = extAscan + .getPolicyManager() + .getDefaultScanPolicy() + .getPluginFactory() + .getAllPlugin() + .toArray() + .sort(function (a, b) { + return a.getId() - b.getId(); + }); + +const INDENT = " "; + +PolicyTag.values().forEach((currentTag) => { + const policyFilePath = + "/zap/wrk/zap-extensions/addOns/XXXXX/src/main/zapHomeFiles/policies/".replace( + "XXXXX", + currentTag.getAddonId() + ) + currentTag.getFileName(); + print(policyFilePath); + // Create the policy + const fw = new FileWriter(policyFilePath, UTF_8); + const pw = new PrintWriter(fw); + pw.println(''); + pw.println(""); + pw.println( + INDENT + + "" + + StringEscapeUtils.escapeXml11(currentTag.getPolicyName()) + + "" + ); + pw.println(INDENT + ""); + pw.println(INDENT.repeat(2) + "OFF"); + pw.println(INDENT.repeat(2) + "MEDIUM"); + pw.println(INDENT + ""); + pw.println(INDENT + ""); + + plugins.forEach((plugin) => { + try { + if ( + plugin.getAlertTags() != null && + plugin.getAlertTags().keySet().contains(currentTag.getTag()) + ) { + pw.println(INDENT.repeat(2) + ""); + pw.println( + INDENT.repeat(3) + + "" + + StringEscapeUtils.escapeXml11(plugin.getName()) + + "" + ); + pw.println(INDENT.repeat(3) + "true"); + pw.println(INDENT.repeat(3) + "MEDIUM"); + pw.println(INDENT.repeat(2) + ""); + } + } catch (e) { + print(e); + control.setExitStatus( + 1, + "An exception was encountered while generating the scan policy(ies)." + ); + } + }); + pw.println(INDENT + ""); + pw.println(""); + pw.close(); +}); diff --git a/.github/workflows/generate_policies.yml b/.github/workflows/generate_policies.yml new file mode 100644 index 00000000000..7282721c66a --- /dev/null +++ b/.github/workflows/generate_policies.yml @@ -0,0 +1,54 @@ +name: Generate Scan Policies from Policy Tags +on: + schedule: # The start of every Friday + - cron: '0 0 * * 5' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-policies: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + persist-credentials: false + path: zap-extensions + fetch-depth: 0 + - name: Create Policies + run: | + # Run the ZAP script + docker run -v $(pwd):/zap/wrk/:rw --user root -t ghcr.io/zaproxy/zaproxy:nightly ./zap.sh -addoninstall ascanrulesAlpha -silent -script /zap/wrk/zap-extensions/.github/scripts/generateScanPolicies.js -cmd + - name: Attach Policies + uses: actions/upload-artifact@v4 + with: + name: Policies + path: 'zap-extensions/addOns/scanpolicies/src/main/zapHomeFiles/policies/*.policy' + - name: Update Scan Policies + run: | + export BASE=$(pwd) + # Setup git details + export GITHUB_USER=zapbot + git config --global user.email "12745184+zapbot@users.noreply.github.com" + git config --global user.name $GITHUB_USER + BRANCH=scan-policies-updt + cd zap-extensions + git remote add upstream https://github.com/zaproxy/zap-extensions.git + SRC_BASE="zaproxy/zap-extensions@"$(git log -1 --format=format:%h) + export GITHUB_TOKEN=${{ secrets.ZAPBOT_TOKEN }} + git checkout -b $BRANCH + # Update the index to be sure git is aware of changes + git update-index -q --refresh + git add . + ## If there are changes: comment, commit, PR + if ! git diff-index --quiet HEAD --; then + ./gradlew :addOns:scanpolicies:updateChangelog --change="- Updated based on Rules' Policy Tag assignments." + git remote set-url origin https://$GITHUB_USER:$GITHUB_TOKEN@github.com/$GITHUB_USER/zap-extensions.git + git add . + git commit -m "Update scan policies based on Tags" -m "Updates based on $SRC_BASE" --signoff + git push --set-upstream origin $BRANCH --force + gh pr create -R zaproxy/zap-extensions --fill + fi