diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
new file mode 100644
index 0000000000000..947b771f0fbf8
--- /dev/null
+++ b/.github/workflows/dependency-review.yml
@@ -0,0 +1,23 @@
+name: 'Dependency Review'
+on: [pull_request]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+jobs:
+ dependency-review:
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout Repository'
+ uses: actions/checkout@v4
+
+ - name: 'Dependency Review'
+ uses: actions/dependency-review-action@v4
+ with:
+ fail-on-severity: high
+ fail-on-scopes: runtime, unknown, development
+ comment-summary-in-pr: always
+ show-openssf-scorecard: true
+ retry-on-snapshot-warnings: true
+ warn-only: false
diff --git a/.github/workflows/maven-owasp-check.yml b/.github/workflows/maven-owasp-check.yml
new file mode 100644
index 0000000000000..2f8043121b24a
--- /dev/null
+++ b/.github/workflows/maven-owasp-check.yml
@@ -0,0 +1,138 @@
+name: Maven OWASP Dependency Check
+on:
+ pull_request:
+ workflow_dispatch:
+ inputs:
+ cvss-threshold:
+ description: 'CVSS score threshold for failing (7.0 = high/critical)'
+ required: false
+ default: '7.0'
+ type: string
+
+jobs:
+ dependency-check:
+ runs-on: ubuntu-latest
+ env:
+ CVSS_THRESHOLD: ${{ github.event.inputs.cvss-threshold || '7.0' }}
+ OWASP_VERSION: '12.1.3'
+ steps:
+ - name: Checkout PR branch
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+ path: pr
+
+ - name: Checkout base branch
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.base.sha }}
+ path: base
+
+ - name: Set up Java
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: 17
+ cache: 'maven'
+
+ - name: Get date for cache key
+ id: get-date
+ run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
+
+ - name: Restore OWASP database cache
+ uses: actions/cache/restore@v4
+ id: cache-owasp-restore
+ with:
+ path: ~/.owasp/dependency-check-data
+ key: owasp-cache-${{ runner.os }}-${{ env.OWASP_VERSION }}-${{ steps.get-date.outputs.date }}
+ restore-keys: |
+ owasp-cache-${{ runner.os }}-${{ env.OWASP_VERSION }}-
+ owasp-cache-${{ runner.os }}-
+
+ - name: Run OWASP check on base branch
+ working-directory: base
+ run: |
+ mvn org.owasp:dependency-check-maven:${{ env.OWASP_VERSION }}:aggregate \
+ -DskipTests \
+ -Dformat=JSON \
+ -DprettyPrint=true \
+ -DfailOnError=false \
+ -DossindexAnalyzerEnabled=true \
+ -DnvdApiAnalyzerEnabled=false \
+ -DnodeAnalyzerEnabled=false \
+ -DassemblyAnalyzerEnabled=false \
+ -DcentralAnalyzerEnabled=false \
+ -DnuspecAnalyzerEnabled=false \
+ -DnvdValidForHours=168 \
+ -DdataDirectory=$HOME/.owasp/dependency-check-data
+
+ - name: Save OWASP cache after base scan
+ if: steps.cache-owasp-restore.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v4
+ with:
+ path: ~/.owasp/dependency-check-data
+ key: owasp-cache-${{ runner.os }}-${{ env.OWASP_VERSION }}-${{ steps.get-date.outputs.date }}-partial
+
+ - name: Run OWASP check on PR branch
+ working-directory: pr
+ run: |
+ mvn org.owasp:dependency-check-maven:${{ env.OWASP_VERSION }}:aggregate \
+ -DskipTests \
+ -Dformat=JSON \
+ -DprettyPrint=true \
+ -DfailOnError=false \
+ -DossindexAnalyzerEnabled=true \
+ -DnvdApiAnalyzerEnabled=false \
+ -DnodeAnalyzerEnabled=false \
+ -DassemblyAnalyzerEnabled=false \
+ -DcentralAnalyzerEnabled=false \
+ -DnuspecAnalyzerEnabled=false \
+ -DnvdValidForHours=168 \
+ -DdataDirectory=$HOME/.owasp/dependency-check-data
+
+ - name: Compare and fail on new CVEs above threshold
+ run: |
+ # Extract CVEs above threshold from both branches (CVSS >= $CVSS_THRESHOLD)
+ threshold="${{ env.CVSS_THRESHOLD }}"
+ base_cves=$(cat base/target/dependency-check-report.json 2>/dev/null | jq -r ".dependencies[].vulnerabilities[]? | select((.cvssv2.score // 0) >= $threshold or (.cvssv3.baseScore // 0) >= $threshold) | .name" | grep -E '^CVE-[0-9]{4}-[0-9]+$' | sort -u)
+ pr_cves=$(cat pr/target/dependency-check-report.json 2>/dev/null | jq -r ".dependencies[].vulnerabilities[]? | select((.cvssv2.score // 0) >= $threshold or (.cvssv3.baseScore // 0) >= $threshold) | .name" | grep -E '^CVE-[0-9]{4}-[0-9]+$' | sort -u)
+
+ # Find new CVEs introduced in PR
+ new_cves=$(comm -13 <(echo "$base_cves") <(echo "$pr_cves"))
+
+ if [ -n "$new_cves" ]; then
+ echo "❌ New vulnerabilities introduced in PR:"
+ echo "$new_cves"
+ echo ""
+
+ for cve in $new_cves; do
+ echo "=================================================="
+ echo "CVE: $cve"
+ echo "=================================================="
+
+ # Find which dependencies have this CVE (with safe access to packages)
+ cat pr/target/dependency-check-report.json | jq -r ".dependencies[] | select(.vulnerabilities[]?.name == \"$cve\") | \"Module: \" + (.projectReferences // [\"root\"])[0] + \"\nDependency: \" + .fileName + \"\nPackage: \" + (if .packages and .packages[0] then .packages[0].id else \"N/A\" end) + \"\nDescription: \" + (.vulnerabilities[] | select(.name == \"$cve\") | .description)"
+
+ echo ""
+ done
+
+ exit 1
+ else
+ echo "✅ No new vulnerabilities introduced"
+ fi
+
+ - name: Save OWASP database cache
+ if: always()
+ uses: actions/cache/save@v4
+ with:
+ path: ~/.owasp/dependency-check-data
+ key: owasp-cache-${{ runner.os }}-${{ env.OWASP_VERSION }}-${{ steps.get-date.outputs.date }}
+
+ - name: Upload reports
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: owasp-reports
+ path: |
+ base/target/dependency-check-report.json
+ pr/target/dependency-check-report.json
diff --git a/.github/workflows/trivy-pr-check.yml b/.github/workflows/trivy-pr-check.yml
new file mode 100644
index 0000000000000..7bcc87f0da563
--- /dev/null
+++ b/.github/workflows/trivy-pr-check.yml
@@ -0,0 +1,54 @@
+name: Trivy PR Security Check
+on: [pull_request]
+
+jobs:
+ trivy-scan:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout PR branch
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+ path: pr
+
+ - name: Checkout base branch
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.base.sha }}
+ path: base
+
+ - name: Scan base branch
+ uses: aquasecurity/trivy-action@master
+ with:
+ scan-type: 'fs'
+ scan-ref: 'base'
+ format: 'json'
+ output: 'base-results.json'
+ exit-code: '0' # Don't fail on base branch issues
+
+ - name: Scan PR branch
+ uses: aquasecurity/trivy-action@master
+ with:
+ scan-type: 'fs'
+ scan-ref: 'pr'
+ format: 'json'
+ output: 'pr-results.json'
+ exit-code: '0'
+
+ - name: Compare and fail on new CVEs
+ run: |
+ # Extract CVE IDs from both scans
+ base_cves=$(cat base-results.json | jq -r '.Results[]?.Vulnerabilities[]?.VulnerabilityID' | sort -u)
+ pr_cves=$(cat pr-results.json | jq -r '.Results[]?.Vulnerabilities[]?.VulnerabilityID' | sort -u)
+
+ # Find new CVEs in PR
+ new_cves=$(comm -13 <(echo "$base_cves") <(echo "$pr_cves"))
+
+ if [ ! -z "$new_cves" ]; then
+ echo "New vulnerabilities introduced in PR:"
+ echo "$new_cves"
+ cat pr-results.json | jq '.Results[]?.Vulnerabilities[]? | select(.VulnerabilityID | IN($new_cves))'
+ exit 1
+ else
+ echo "No new vulnerabilities introduced"
+ fi
diff --git a/presto-hudi/pom.xml b/presto-hudi/pom.xml
index 0682e3f4ae51d..cf871c4f9609d 100644
--- a/presto-hudi/pom.xml
+++ b/presto-hudi/pom.xml
@@ -40,6 +40,18 @@
compile
+
+ junit
+ junit
+ 4.11
+ test
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.14.1
+
+
com.google.inject
guice
@@ -149,7 +161,7 @@
org.apache.hudi
hudi-presto-bundle
- 1.0.2
+ 0.14.0