diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000000..a10be7a00e --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,21 @@ +name: "CodeQL config for ModSecurity" + +queries: + - uses: security-extended + +paths-ignore: + # Tests + - "tests/**" + - "test/**" + - "**/*test*" + + # Third-party / submodules + - "others/**" + - "bindings/**" + - "examples/**" + - "doc/**" + + # Build & generated files + - "build/**" + - "**/*.png" + - "**/*.md" diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000000..16d9dd8134 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,15 @@ +version: 2 +updates: + - package-ecosystem: "gitsubmodule" + directory: "/" + schedule: + interval: "daily" + commit-message: + prefix: "Submodule Update" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + commit-message: + prefix: "GitHub Actions Updates" \ No newline at end of file diff --git a/.github/security-scan-excludes.txt b/.github/security-scan-excludes.txt new file mode 100644 index 0000000000..5a06e1c0bc --- /dev/null +++ b/.github/security-scan-excludes.txt @@ -0,0 +1,29 @@ +# Build & Output +build +build/* +out +out/* +dist +dist/* + +# Dependencies / Vendored +vendor +vendor/* +third_party +third_party/* +deps +deps/* +external +external/* +others/* + +# VCS / CI +.git +.github + +# Docs & misc +docs +examples +tests +test +benchmarks diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d6895b825d..95a2255ab0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,10 +10,9 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-22.04] + os: [ubuntu-24.04] platform: - - {label: "x64", arch: "amd64", configure: ""} - - {label: "x32", arch: "i386", configure: "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32"} + - {label: "x64", arch: "amd64", configure: ""} # nur noch x64 compiler: - {label: "gcc", cc: "gcc", cxx: "g++"} - {label: "clang", cc: "clang", cxx: "clang++"} @@ -27,11 +26,8 @@ jobs: - {label: "wo ssdeep", opt: "--without-ssdeep" } - {label: "with lmdb", opt: "--with-lmdb" } - {label: "with pcre", opt: "--with-pcre" } - exclude: - - platform: {label: "x32"} - configure: {label: "wo geoip"} - - platform: {label: "x32"} - configure: {label: "wo ssdeep"} + # keine excludes mehr nötig – es gibt kein x32 + steps: - name: Setup Dependencies (common) run: | @@ -40,36 +36,48 @@ jobs: sudo apt-get install -y libyajl-dev:${{ matrix.platform.arch }} \ libcurl4-openssl-dev:${{ matrix.platform.arch }} \ liblmdb-dev:${{ matrix.platform.arch }} \ - liblua5.2-dev:${{ matrix.platform.arch }} \ + liblua5.3-dev:${{ matrix.platform.arch }} \ libmaxminddb-dev:${{ matrix.platform.arch }} \ libpcre2-dev:${{ matrix.platform.arch }} \ pcre2-utils:${{ matrix.platform.arch }} \ - bison flex - - name: Setup Dependencies (x32) - if: ${{ matrix.platform.label == 'x32' }} - run: | - sudo apt-get install g++-multilib - sudo apt-get install -y libxml2-dev:${{ matrix.platform.arch }} \ - libpcre3-dev:${{ matrix.platform.arch }} + libpcre3-dev:${{ matrix.platform.arch }} \ + bison flex cmake \ + libmbedtls-dev:${{ matrix.platform.arch }} + # x32-Setup fällt komplett weg + - name: Setup Dependencies (x64) if: ${{ matrix.platform.label == 'x64' }} run: | sudo apt-get install -y libgeoip-dev:${{ matrix.platform.arch }} \ - libfuzzy-dev:${{ matrix.platform.arch }} - - uses: actions/checkout@v4 + libfuzzy-dev:${{ matrix.platform.arch }} + + - uses: actions/checkout@v6 with: submodules: true fetch-depth: 0 - - name: build.sh - run: ./build.sh + + - name: Init git submodules + run: | + git submodule sync --recursive + git submodule update --init --recursive --force + + - name: Build-Script ausführbar machen + run: chmod +x build_on_linux.sh + + - name: build_on_linux.sh + run: ./build_on_linux.sh + - name: configure env: CC: ${{ matrix.compiler.cc }} CXX: ${{ matrix.compiler.cxx }} - run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes + run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes --disable-dependency-tracking + - uses: ammaraskar/gcc-problem-matcher@master + - name: make run: make -j `nproc` + - name: check run: make check @@ -78,22 +86,27 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-14] + os: [macos-14, macos-15, macos-26] configure: - - {label: "with parser generation", opt: "--enable-parser-generation" } - - {label: "wo curl", opt: "--without-curl" } - - {label: "wo lua", opt: "--without-lua" } - - {label: "wo maxmind", opt: "--without-maxmind" } - - {label: "wo libxml", opt: "--without-libxml" } + - {label: "with parser generation", opt: "--enable-parser-generation --without-geoip" } + - {label: "wo curl", opt: "--without-curl --without-geoip" } + - {label: "wo lua", opt: "--without-lua --without-geoip" } + - {label: "wo maxmind", opt: "--without-maxmind --without-geoip" } + - {label: "wo libxml", opt: "--without-libxml --without-geoip" } - {label: "wo geoip", opt: "--without-geoip" } - - {label: "wo ssdeep", opt: "--without-ssdeep" } - - {label: "with lmdb", opt: "--with-lmdb" } - - {label: "with pcre", opt: "--with-pcre" } + - {label: "wo ssdeep", opt: "--without-ssdeep --without-geoip" } + - {label: "with lmdb", opt: "--with-lmdb --without-geoip" } + - {label: "with pcre", opt: "--with-pcre --without-geoip" } + steps: - - name: Setup Dependencies - # curl, pcre2 not installed because they're already - # included in the image + - name: Setup Homebrew + run: | + echo "PATH=/opt/homebrew/bin:$PATH" >> $GITHUB_ENV + echo "PKG_CONFIG_PATH=/opt/homebrew/lib/pkgconfig:/opt/homebrew/opt/openssl/lib/pkgconfig:/opt/homebrew/opt/pcre/lib/pkgconfig:/opt/homebrew/opt/pcre2/lib/pkgconfig:/opt/homebrew/opt/libxml2/lib/pkgconfig:/opt/homebrew/opt/curl/lib/pkgconfig:/opt/homebrew/opt/icu4c/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig" >> $GITHUB_ENV + + - name: Install Dependencies run: | + brew update brew install autoconf \ automake \ libtool \ @@ -105,103 +118,105 @@ jobs: ssdeep \ pcre \ bison \ - flex - - uses: actions/checkout@v4 + flex \ + mbedtls + + - uses: actions/checkout@v6 with: submodules: true fetch-depth: 0 - - name: Build GeoIP + + - name: Init git submodules run: | - git clone --depth 1 --no-checkout https://github.com/maxmind/geoip-api-c.git - cd geoip-api-c - git fetch --tags - # Check out the last release, v1.6.12 - git checkout 4b526e7331ca1d692b74a0509ddcc725622ed31a - autoreconf --install - ./configure --disable-dependency-tracking --disable-silent-rules --prefix=/opt/homebrew - make install - - name: build.sh - run: ./build.sh + git submodule sync --recursive + git submodule update --init --recursive --force + + - name: Build-Script ausführbar machen + run: chmod +x build_on_macos.sh + - name: build_on_macos.sh + run: ./build_on_macos.sh + - name: configure - run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes + env: + CPPFLAGS: -I/opt/homebrew/opt/mbedtls/include + LDFLAGS: -L/opt/homebrew/opt/mbedtls/lib + run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes --disable-dependency-tracking + - uses: ammaraskar/gcc-problem-matcher@master + - name: make run: make -j `sysctl -n hw.logicalcpu` + - name: check run: make check - build-windows: - name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }}) - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-2022] - platform: - - {label: "x64", arch: "x86_64"} - configuration: [Release] - configure: - - {label: "full", opt: "" } - - {label: "wo curl", opt: "-DWITH_CURL=OFF" } - - {label: "wo lua", opt: "-DWITH_LUA=OFF" } - - {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" } - - {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" } - - {label: "with lmdb", opt: "-DWITH_LMDB=ON" } - steps: - - uses: actions/checkout@v4 - with: - submodules: true - fetch-depth: 0 - - name: Install Conan - run: | - pip3 install conan --upgrade - conan profile detect - - uses: ammaraskar/msvc-problem-matcher@master - - name: Build ${{ matrix.configuration }} ${{ matrix.platform.arch }} ${{ matrix.configure.label }} - shell: cmd - run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN "${{ matrix.configure.opt }}" - - name: Set up test environment - working-directory: build\win32\build\${{ matrix.configuration }} - env: - BASE_DIR: ..\..\..\.. - shell: cmd - run: | - copy unit_tests.exe %BASE_DIR%\test - copy regression_tests.exe %BASE_DIR%\test - copy libModSecurity.dll %BASE_DIR%\test - copy %BASE_DIR%\unicode.mapping %BASE_DIR%\test - md \tmp - md \bin - copy "C:\Program Files\Git\usr\bin\echo.exe" \bin - copy "C:\Program Files\Git\usr\bin\echo.exe" \bin\echo - - name: Disable tests that don't work on Windows - working-directory: test\test-cases\regression - shell: cmd - run: | - jq "map(if .title == \"Test match variable (1/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json - jq "map(if .title == \"Test match variable (2/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json - jq "map(if .title == \"Test match variable (3/n)\" then .enabled = 0 else . end)" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json - jq "map(if .title == \"Variable offset - FILES_NAMES\" then .enabled = 0 else . end)" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json - - name: Run tests - working-directory: build\win32\build - run: | - ctest -C ${{ matrix.configuration }} --output-on-failure - cppcheck: - runs-on: [macos-14] + # build-windows: + # name: Windows (${{ matrix.configure.label }}) + # runs-on: windows-latest + # strategy: + # matrix: + # configure: + # - {label: "default", opt: "" } + # - {label: "wo curl", opt: "-DWITH_CURL=OFF" } + # - {label: "wo lua", opt: "-DWITH_LUA=OFF" } + # - {label: "wo maxmind", opt: "-DWITH_MAXMIND=OFF" } + # - {label: "wo libxml", opt: "-DWITH_LIBXML2=OFF" } + # - {label: "with lmdb", opt: "-DWITH_LMDB=ON" } + # steps: + # - uses: actions/checkout@v6 + # with: + # submodules: true + # fetch-depth: 0 + # - name: Init git submodules + # run: | + # git submodule sync --recursive + # git submodule update --init --recursive --force + # - name: Install Conan + # run: | + # pip3 install conan + # - name: Configure Conan + # run: | + # conan profile detect + # - name: Configure CMake + # run: | + # cmake -S . -B build ${{ matrix.configure.opt }} + # - name: Build + # run: | + # cmake --build build --config Release + + cppcheck-macos: + name: cppcheck (macOS) + runs-on: macos-14 + steps: - name: Setup Dependencies run: | - brew install autoconf \ - automake \ - libtool \ - cppcheck - - uses: actions/checkout@v4 + brew update + brew install autoconf automake libtool cppcheck mbedtls + + - name: Checkout (with submodules) + uses: actions/checkout@v6 with: - submodules: true + submodules: recursive fetch-depth: 0 - - name: configure + + - name: Ensure submodules are up to date run: | - ./build.sh - ./configure + git submodule sync --recursive + git submodule update --init --recursive --force + + - name: Build-Script ausführbar machen + run: chmod +x build_on_macos.sh + + - name: build_on_macos.sh + run: ./build_on_macos.sh + + - name: configure + env: + CPPFLAGS: -I/opt/homebrew/opt/mbedtls/include + LDFLAGS: -L/opt/homebrew/opt/mbedtls/lib + run: ./configure --disable-dependency-tracking + - name: cppcheck run: make check-static diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..7023b792eb --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,60 @@ +name: CodeQL_on_linux + + +on: + workflow_dispatch: + push: + branches: ["master", "main"] + pull_request: + branches: ["master", "main"] + schedule: + - cron: "19 3 * * 1" + + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + name: CodeQL (C/C++) + runs-on: ubuntu-24.04 + + steps: + - name: Checkout (with submodules) + uses: actions/checkout@v6 + with: + submodules: recursive + fetch-depth: 0 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: c-cpp + build-mode: manual + config-file: ./.github/codeql/codeql-config.yml + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential pkg-config \ + autoconf automake libtool \ + flex bison \ + libyajl-dev \ + libxml2-dev \ + libpcre2-dev \ + libcurl4-openssl-dev \ + zlib1g-dev \ + libmbedtls-dev \ + ca-certificates + + - name: Build (required for CodeQL C/C++) + run: | + ./build_on_linux.sh + ./configure --disable-dependency-tracking + make -j"$(nproc)" + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml new file mode 100644 index 0000000000..1fa8642ba1 --- /dev/null +++ b/.github/workflows/cppcheck.yml @@ -0,0 +1,139 @@ +name: Quality Assurance - cppcheck + +on: + workflow_dispatch: + inputs: + full: + description: "Run FULL cppcheck (make check-static). If false: only changed files." + required: true + default: "false" + push: + branches: ["master", "main"] + pull_request: + branches: ["master", "main"] + schedule: + #- cron: "15 2 * * 1" # montags 02:15 UTC (anpassen wenn du willst) + - cron: "15 2 * * 1" # montags + +jobs: + cppcheck-linux: + name: cppcheck (Linux) + runs-on: ubuntu-24.04 + timeout-minutes: 120 + + steps: + - name: Setup Dependencies + run: | + sudo apt-get update -y -qq + sudo apt-get install -y \ + cppcheck \ + autoconf \ + automake \ + libtool + + - name: Checkout (with submodules) + uses: actions/checkout@v6 + with: + submodules: recursive + fetch-depth: 0 + + - name: Ensure submodules are up to date + run: | + git submodule sync --recursive + git submodule update --init --recursive --force + + - name: Build-Script ausführbar machen + run: chmod +x build_on_linux.sh + + - name: build_on_linux.sh + run: ./build_on_linux.sh + + - name: configure + run: ./configure --disable-dependency-tracking + + # FULL scan: scheduled ODER workflow_dispatch(full=true) + - name: cppcheck (full) + if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.full == 'true') + run: make check-static JOBS=$(nproc) + + # FAST scan: Push/PR oder workflow_dispatch(full=false) + - name: cppcheck (changed files) + if: github.event_name != 'schedule' && !(github.event_name == 'workflow_dispatch' && inputs.full == 'true') + run: | + BASE_REF="${{ github.base_ref }}" + if [ -z "$BASE_REF" ]; then + BASE_REF="master" + fi + + git fetch origin "$BASE_REF" --depth=1 || true + CHANGED="$(git diff --name-only "origin/$BASE_REF"...HEAD -- \ + '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' | tr '\n' ' ')" + + if [ -z "$CHANGED" ]; then + echo "No changed C/C++ files detected." + exit 0 + fi + + cppcheck --enable=warning,style,performance,portability \ + --inline-suppr --error-exitcode=1 \ + $CHANGED + + cppcheck-macos: + name: cppcheck (macOS) + runs-on: macos-14 + + steps: + - name: Setup Dependencies + run: | + brew update + brew install autoconf automake libtool cppcheck mbedtls + + - name: Checkout (with submodules) + uses: actions/checkout@v6 + with: + submodules: recursive + fetch-depth: 0 + + - name: Ensure submodules are up to date + run: | + git submodule sync --recursive + git submodule update --init --recursive --force + + - name: Build-Script ausführbar machen + run: chmod +x build_on_macos.sh + + - name: build_on_macos.sh + run: ./build_on_macos.sh + + - name: configure + env: + CPPFLAGS: -I/opt/homebrew/opt/mbedtls/include + LDFLAGS: -L/opt/homebrew/opt/mbedtls/lib + run: ./configure --disable-dependency-tracking + + # FULL scan: scheduled ODER workflow_dispatch(full=true) + - name: cppcheck (full) + if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.full == 'true') + run: make check-static JOBS=$(sysctl -n hw.ncpu) + + # FAST scan: Push/PR oder workflow_dispatch(full=false) + - name: cppcheck (changed files) + if: github.event_name != 'schedule' && !(github.event_name == 'workflow_dispatch' && inputs.full == 'true') + run: | + BASE_REF="${{ github.base_ref }}" + if [ -z "$BASE_REF" ]; then + BASE_REF="master" + fi + + git fetch origin "$BASE_REF" --depth=1 || true + CHANGED="$(git diff --name-only "origin/$BASE_REF"...HEAD -- \ + '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' | tr '\n' ' ')" + + if [ -z "$CHANGED" ]; then + echo "No changed C/C++ files detected." + exit 0 + fi + + cppcheck --enable=warning,style,performance,portability \ + --inline-suppr --error-exitcode=1 \ + $CHANGED diff --git a/.github/workflows/dependabot-auto-approve.yaml b/.github/workflows/dependabot-auto-approve.yaml new file mode 100644 index 0000000000..2b467fa367 --- /dev/null +++ b/.github/workflows/dependabot-auto-approve.yaml @@ -0,0 +1,27 @@ +name: Dependabot Auto-Approve +on: pull_request + +permissions: + pull-requests: write + contents: write + +jobs: + auto-approve: + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' }} + steps: + - name: Fetch Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Approve Pull Request + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Enable Auto-Merge + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/flawfinder.yml b/.github/workflows/flawfinder.yml new file mode 100644 index 0000000000..f0ac0c2105 --- /dev/null +++ b/.github/workflows/flawfinder.yml @@ -0,0 +1,125 @@ +name: Flawfinder (C/C++) + +on: + workflow_dispatch: + pull_request: + push: + branches: [ "main", "master" ] + schedule: + - cron: "20 2 * * 1" # Weekly + +permissions: + contents: read + security-events: write + +jobs: + flawfinder: + runs-on: ubuntu-latest + + steps: + - name: Checkout (inkl. Submodules) + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Install Flawfinder + run: | + sudo apt-get update + sudo apt-get install -y flawfinder + + - name: Build source file list (robust excludes) + shell: bash + run: | + set -euo pipefail + + EXCLUDE_FILE=".github/security-scan-excludes.txt" + EXCLUDE_TMP="/tmp/excludes.txt" + + # 1) Excludes vorbereiten (falls Datei fehlt/leer ist -> leere exclude list) + if [[ -f "$EXCLUDE_FILE" ]]; then + # Kommentare/Leerzeilen entfernen, "./" davor setzen + grep -vE '^\s*#|^\s*$' "$EXCLUDE_FILE" | sed 's|^|./|' > "$EXCLUDE_TMP" || true + else + : > "$EXCLUDE_TMP" + fi + + # 2) Relevante Quellfiles finden + find . \ + -type f \ + \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.cxx' -o -name '*.h' -o -name '*.hh' -o -name '*.hpp' -o -name '*.hxx' \) \ + > /tmp/all-src.txt + + # 3) Excludes anwenden (wenn exclude list leer -> einfach alles nehmen) + if [[ -s "$EXCLUDE_TMP" ]]; then + grep -v -F -f "$EXCLUDE_TMP" /tmp/all-src.txt > /tmp/flawfinder-files.txt || true + else + cp /tmp/all-src.txt /tmp/flawfinder-files.txt + fi + + # 4) Falls nix übrig bleibt, nicht failen – nur warnen + if [[ ! -s /tmp/flawfinder-files.txt ]]; then + echo "No source files to scan after excludes." + else + echo "Files to scan: $(wc -l < /tmp/flawfinder-files.txt)" + fi + + - name: Build Flawfinder file list (headers only) + shell: bash + run: | + set -euo pipefail + git ls-files 'headers/**' \ + | grep -E '\.(h|hh|hpp|hxx)$' \ + > /tmp/flawfinder-headers-files.txt || true + + echo "Header files to scan: $(wc -l < /tmp/flawfinder-headers-files.txt || echo 0)" + + + - name: Run Flawfinder (SARIF, headers strict) + shell: bash + run: | + set -euo pipefail + + if [[ ! -s /tmp/flawfinder-headers-files.txt ]]; then + echo "Skipping flawfinder headers: no files." + echo '{"$schema":"https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"flawfinder","informationUri":"https://dwheeler.com/flawfinder/"}},"results":[]}]}' > flawfinder-headers.sarif + exit 0 + fi + + echo "Flawfinder version:" + flawfinder --version + + set +e + xargs -a /tmp/flawfinder-headers-files.txt \ + flawfinder --sarif --minlevel=1 \ + > flawfinder-headers.sarif \ + 2> flawfinder-headers.stderr + rc=$? + set -e + + echo "flawfinder exit code: $rc" + if [[ -s flawfinder-headers.stderr ]]; then + echo "---- flawfinder stderr ----" + cat flawfinder-headers.stderr + echo "---------------------------" + fi + + echo "SARIF size: $(wc -c < flawfinder-headers.sarif) bytes" + + # Validate SARIF JSON + if ! python3 -c 'import json; json.load(open("flawfinder-headers.sarif","r",encoding="utf-8"))' 2>/dev/null; then + echo "Writing minimal SARIF because flawfinder output was not valid SARIF JSON." + echo '{"$schema":"https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"flawfinder","informationUri":"https://dwheeler.com/flawfinder/"}},"results":[]}]}' > flawfinder-headers.sarif + fi + + # 16 = findings found → OK + if [[ $rc -ne 0 && $rc -ne 16 ]]; then + exit $rc + fi + + + - name: Upload SARIF + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: flawfinder-headers.sarif + category: flawfinder-headers-strict diff --git a/.github/workflows/osv-scanner-pr.yml b/.github/workflows/osv-scanner-pr.yml new file mode 100644 index 0000000000..971bf65ee6 --- /dev/null +++ b/.github/workflows/osv-scanner-pr.yml @@ -0,0 +1,19 @@ +name: OSV Scanner (PR) + +on: + pull_request: + merge_group: + workflow_dispatch: + +permissions: + contents: read + security-events: write + actions: read + +jobs: + scan-pr: + uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@375a0e8ebdc98e99b02ac4338a724f5750f21213 + with: + scan-args: | + --allow-no-lockfiles + --recursive \ No newline at end of file diff --git a/.github/workflows/osv-scanner-scheduled.yml b/.github/workflows/osv-scanner-scheduled.yml new file mode 100644 index 0000000000..d862cd31d4 --- /dev/null +++ b/.github/workflows/osv-scanner-scheduled.yml @@ -0,0 +1,21 @@ +name: OSV Scanner (Scheduled) + +on: + workflow_dispatch: + schedule: + - cron: "30 3 * * 1" + push: + branches: [ "main", "master" ] + +permissions: + contents: read + security-events: write + actions: read + +jobs: + scan: + uses: google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@375a0e8ebdc98e99b02ac4338a724f5750f21213 + with: + scan-args: | + --allow-no-lockfiles + --recursive diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000000..54052c1e11 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,43 @@ +name: OSSF Scorecard + +on: + workflow_dispatch: + branch_protection_rule: + push: + branches: [ "main", "master" ] + schedule: + - cron: "10 1 * * 0" + +permissions: + contents: read + +jobs: + analysis: + runs-on: ubuntu-latest + permissions: + security-events: write + id-token: write + contents: read + issues: read + pull-requests: read + checks: read + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + submodules: recursive + persist-credentials: false + + - name: Run Scorecard + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 + with: + results_file: scorecard.sarif + results_format: sarif + publish_results: false + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: scorecard.sarif + category: scorecard diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 0000000000..9e744bed31 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,73 @@ +name: Semgrep (C/C++ SAST) + +on: + workflow_dispatch: + pull_request: + push: + branches: [ "main", "master" ] + +permissions: + contents: read + security-events: write + +jobs: + semgrep: + runs-on: ubuntu-latest + + steps: + - name: Checkout (inkl. Submodules) + uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Install Semgrep + run: | + python3 -m pip install --upgrade pip + pip install semgrep + + - name: Fetch Semgrep Community rules + run: | + git clone --depth 1 https://github.com/semgrep/semgrep-rules .semgrep-rules + + - name: Run Semgrep (SARIF, robust excludes + configs) + shell: bash + run: | + set -euo pipefail + + # 1) Excludes aus Datei robust einlesen (Kommentare/Leerzeilen ignorieren) + EXCLUDE_FILE=".github/security-scan-excludes.txt" + EXCLUDES="" + if [[ -f "$EXCLUDE_FILE" ]]; then + while IFS= read -r line; do + [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue + EXCLUDES+=" --exclude $line" + done < "$EXCLUDE_FILE" + fi + echo "Semgrep excludes:$EXCLUDES" + + # 2) Configs nur hinzufügen, wenn sie existieren (Repo-Struktur kann sich ändern) + CONFIGS=() + [[ -d ".semgrep-rules/c" ]] && CONFIGS+=("--config" ".semgrep-rules/c") + [[ -d ".semgrep-rules/cpp" ]] && CONFIGS+=("--config" ".semgrep-rules/cpp") + # Optional: generische Security-Audit Rules (sprache-unabhängig/teilweise generisch) + [[ -d ".semgrep-rules/security/audit" ]] && CONFIGS+=("--config" ".semgrep-rules/security/audit") + + if [[ ${#CONFIGS[@]} -eq 0 ]]; then + echo "No suitable Semgrep community rule directories found; skipping." + echo '{"version":"2.1.0","runs":[]}' > semgrep.sarif + exit 0 + fi + + # 3) Scan + semgrep scan \ + "${CONFIGS[@]}" \ + $EXCLUDES \ + --sarif -o semgrep.sarif \ + . + + - name: Upload SARIF + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: semgrep.sarif + category: semgrep diff --git a/Makefile.am b/Makefile.am index 7ac184b504..56ebdb0000 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,8 +55,13 @@ parser: +# Anzahl der cppcheck-Jobs, von außen überschreibbar: JOBS=8 make check-static +JOBS ?= 1 + cppcheck: - @cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \ + @echo "Running cppcheck with $(JOBS) jobs..." + @cppcheck -j $(JOBS) \ + -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \ -D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \ --suppressions-list=./test/cppcheck_suppressions.txt \ --inline-suppr \ @@ -70,7 +75,6 @@ cppcheck: --std=c++17 \ --force --verbose . - check-static: cppcheck check-style: check-coding-style diff --git a/bindings/python b/bindings/python index bc625d5bb0..47a6925df1 160000 --- a/bindings/python +++ b/bindings/python @@ -1 +1 @@ -Subproject commit bc625d5bb0bac6a64bcce8dc9902208612399348 +Subproject commit 47a6925df187f96e4593afab18dc92d5f22bd4d5 diff --git a/build_on_linux.sh b/build_on_linux.sh new file mode 100644 index 0000000000..1b8576bee5 --- /dev/null +++ b/build_on_linux.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +set -e # bei Fehler abbrechen + +## +## Parallel-Jobs bestimmen (nur Linux) +## Überschreibbar mit: JOBS=4 ./bootstrap.sh +## +if [ -z "$JOBS" ]; then + JOBS=$(nproc) +fi +echo "==> Using $JOBS parallel build jobs" + +rm -rf autom4te.cache +rm -f aclocal.m4 + +## +## 1. headers.mk erzeugen +## +cd src +rm -f headers.mk +echo "noinst_HEADERS = \\" > headers.mk +ls -1 \ + actions/*.h \ + actions/ctl/*.h \ + actions/data/*.h \ + actions/disruptive/*.h \ + actions/transformations/*.h \ + debug_log/*.h \ + audit_log/writer/*.h \ + collection/backend/*.h \ + operators/*.h \ + parser/*.h \ + request_body_processor/*.h \ + utils/*.h \ + variables/*.h \ + engine/*.h \ + *.h | tr "\012" " " >> headers.mk +cd .. + +## +## 2. Vendored Mbed TLS bauen – MIT PROGRAMMEN UND TESTS +## +##if [ -d "others/mbedtls" ]; then +## echo "==> Building vendored Mbed TLS (mit Programmen und Tests)..." +## ( +## cd others/mbedtls +## +## mkdir -p build +## +## cmake -S . -B build \ +## -DENABLE_PROGRAMS=ON \ +## -DENABLE_TESTING=ON +## +## # Parallel bauen +## cmake --build build --config Release --parallel "$JOBS" +## +## echo "==> Running Mbed TLS tests..." +## cd build +## ctest --output-on-failure -j"$JOBS" +## ) +##else +## echo "WARNUNG: others/mbedtls nicht gefunden – Mbed TLS wird NICHT gebaut/getestet!" +##fi + +## +## 3. Autotools für ModSecurity initialisieren (nur Linux) +## +libtoolize --force --copy +autoreconf --install +autoheader +automake --add-missing --foreign --copy --force-missing +autoconf --force +rm -rf autom4te.cache diff --git a/build.sh b/build_on_macos.sh old mode 100755 new mode 100644 similarity index 96% rename from build.sh rename to build_on_macos.sh index 7f47f03c04..24ab1d90a9 --- a/build.sh +++ b/build_on_macos.sh @@ -30,6 +30,4 @@ autoreconf --install autoheader automake --add-missing --foreign --copy --force-missing autoconf --force -rm -rf autom4te.cache - - +rm -rf autom4te.cache \ No newline at end of file diff --git a/configure.ac b/configure.ac index 7a78bb6c76..48b5e0bd7e 100644 --- a/configure.ac +++ b/configure.ac @@ -77,8 +77,43 @@ fi AC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd "others/libinjection" && git describe && cd ../..)) AC_SUBST([LIBINJECTION_VERSION]) -# Check for Mbed TLS -if ! test -f "${srcdir}/others/mbedtls/library/base64.c"; then +# ============================================================ +# Check for PSA crypto lib (Mbed TLS / TF-PSA-Crypto) +# ============================================================ + +AC_MSG_CHECKING([for PSA crypto library (Mbed TLS / TF-PSA-Crypto)]) + +MBEDTLS_CRYPTO_LIB="" + +# 1. Mbed TLS 4 / TF-PSA-Crypto: libtfpsacrypto +AC_CHECK_LIB([tfpsacrypto], [psa_crypto_init], + [MBEDTLS_CRYPTO_LIB="-ltfpsacrypto" + AC_MSG_RESULT([using system libtfpsacrypto (-ltfpsacrypto)])], + [ + # 2. Legacy-Name: libmbedcrypto (Mbed TLS <= 3 oder Distros, die das so bereitstellen) + AC_CHECK_LIB([mbedcrypto], [psa_crypto_init], + [MBEDTLS_CRYPTO_LIB="-lmbedcrypto" + AC_MSG_RESULT([using system libmbedcrypto (-lmbedcrypto)])], + [ + # 3. Fallback: vendored libmbedcrypto.a aus others/mbedtls + AC_MSG_RESULT([no system PSA crypto lib found, trying vendored mbedtls]) + + AC_CHECK_FILE([others/mbedtls/build/library/libmbedcrypto.a], + [MBEDTLS_CRYPTO_LIB='$(top_builddir)/others/mbedtls/build/library/libmbedcrypto.a' + AC_MSG_RESULT([using vendored libmbedcrypto.a])], + [AC_MSG_ERROR([Could not find PSA crypto library: + - install Mbed TLS / TF-PSA-Crypto (providing libtfpsacrypto or libmbedcrypto), + or + - build others/mbedtls before running configure])]) + ]) + ]) + +AC_SUBST([MBEDTLS_CRYPTO_LIB]) + + + +# Check for Mbed TLS +if ! test -f "${srcdir}/others/mbedtls/tf-psa-crypto/drivers/builtin/src/base64.c"; then AC_MSG_ERROR([\ diff --git a/examples/multiprocess_c/Makefile.am b/examples/multiprocess_c/Makefile.am index 726d1d9057..59aa448545 100644 --- a/examples/multiprocess_c/Makefile.am +++ b/examples/multiprocess_c/Makefile.am @@ -1,4 +1,4 @@ - +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ noinst_PROGRAMS = multi @@ -9,7 +9,8 @@ multi_LDADD = \ $(SSDEEP_LDADD) \ $(LUA_LDADD) \ $(MAXMIND_LDADD) \ - $(GLOBAL_LDADD) + $(GLOBAL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) multi_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/examples/multithread/Makefile.am b/examples/multithread/Makefile.am index 0871efa1e1..1465749193 100644 --- a/examples/multithread/Makefile.am +++ b/examples/multithread/Makefile.am @@ -5,6 +5,8 @@ noinst_PROGRAMS = multithread multithread_SOURCES = \ multithread.cc +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ + multithread_LDADD = \ $(CURL_LDADD) \ $(GEOIP_LDADD) \ @@ -16,7 +18,8 @@ multithread_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) multithread_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/examples/reading_logs_via_rule_message/Makefile.am b/examples/reading_logs_via_rule_message/Makefile.am index 5a6ba74b2a..7e1723e920 100644 --- a/examples/reading_logs_via_rule_message/Makefile.am +++ b/examples/reading_logs_via_rule_message/Makefile.am @@ -1,4 +1,4 @@ - +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ noinst_PROGRAMS = simple_request @@ -16,7 +16,8 @@ simple_request_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) simple_request_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/examples/reading_logs_with_offset/Makefile.am b/examples/reading_logs_with_offset/Makefile.am index a98ed48d0e..ba021a5203 100644 --- a/examples/reading_logs_with_offset/Makefile.am +++ b/examples/reading_logs_with_offset/Makefile.am @@ -1,4 +1,4 @@ - +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ noinst_PROGRAMS = read @@ -16,7 +16,8 @@ read_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) read_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/examples/simple_example_using_c/Makefile.am b/examples/simple_example_using_c/Makefile.am index b03ab96d48..a1ddb38692 100644 --- a/examples/simple_example_using_c/Makefile.am +++ b/examples/simple_example_using_c/Makefile.am @@ -1,4 +1,4 @@ - +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ noinst_PROGRAMS = test @@ -8,7 +8,8 @@ test_SOURCES = \ test_LDADD = \ $(GLOBAL_LDADD) \ $(LUA_LDADD) \ - $(SSDEEP_LDADD) + $(SSDEEP_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) test_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/examples/using_bodies_in_chunks/Makefile.am b/examples/using_bodies_in_chunks/Makefile.am index 9eb438f368..bb5376ebbf 100644 --- a/examples/using_bodies_in_chunks/Makefile.am +++ b/examples/using_bodies_in_chunks/Makefile.am @@ -1,4 +1,4 @@ - +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ noinst_PROGRAMS = simple_request @@ -16,7 +16,8 @@ simple_request_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) simple_request_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/headers/modsecurity/transaction.h b/headers/modsecurity/transaction.h index 3e70caa38e..d9d670d9c2 100644 --- a/headers/modsecurity/transaction.h +++ b/headers/modsecurity/transaction.h @@ -205,9 +205,12 @@ class TransactionAnchoredVariables { m_variableFilesTmpNames(t, "FILES_TMPNAMES"), m_variableMultipartPartHeaders(t, "MULTIPART_PART_HEADERS"), m_variableOffset(0), - m_variableArgsNames("ARGS_NAMES", &m_variableArgs), - m_variableArgsGetNames("ARGS_GET_NAMES", &m_variableArgsGet), - m_variableArgsPostNames("ARGS_POST_NAMES", &m_variableArgsPost) + m_pVariableArgsNames(std::make_unique("ARGS_NAMES", &m_variableArgs)), + m_variableArgsNames(*m_pVariableArgsNames), + m_pVariableArgsGetNames(std::make_unique("ARGS_GET_NAMES", &m_variableArgsGet)), + m_variableArgsGetNames(*m_pVariableArgsGetNames), + m_pVariableArgsPostNames(std::make_unique("ARGS_POST_NAMES", &m_variableArgsPost)), + m_variableArgsPostNames(*m_pVariableArgsPostNames) { } AnchoredSetVariable m_variableRequestHeadersNames; @@ -291,9 +294,12 @@ class TransactionAnchoredVariables { int m_variableOffset; - AnchoredSetVariableTranslationProxy m_variableArgsNames; - AnchoredSetVariableTranslationProxy m_variableArgsGetNames; - AnchoredSetVariableTranslationProxy m_variableArgsPostNames; + std::unique_ptr m_pVariableArgsNames; + AnchoredSetVariableTranslationProxy &m_variableArgsNames; + std::unique_ptr m_pVariableArgsGetNames; + AnchoredSetVariableTranslationProxy &m_variableArgsGetNames; + std::unique_ptr m_pVariableArgsPostNames; + AnchoredSetVariableTranslationProxy &m_variableArgsPostNames; }; class TransactionSecMarkerManagement { diff --git a/others/Makefile.am b/others/Makefile.am index b102a0330c..b8be3af6eb 100644 --- a/others/Makefile.am +++ b/others/Makefile.am @@ -15,19 +15,21 @@ noinst_HEADERS = \ libinjection/src/libinjection_sqli.h \ libinjection/src/libinjection_sqli_data.h \ libinjection/src/libinjection_xss.h \ - mbedtls/include/mbedtls/base64.h \ - mbedtls/include/mbedtls/check_config.h \ + mbedtls/tf-psa-crypto/include/mbedtls/base64.h \ + mbedtls/tf-psa-crypto/drivers/builtin/src/check_crypto_config.h \ mbedtls/include/mbedtls/mbedtls_config.h \ - mbedtls/include/mbedtls/md5.h \ - mbedtls/include/mbedtls/platform.h \ - mbedtls/include/mbedtls/sha1.h + mbedtls/tf-psa-crypto/drivers/builtin/include/mbedtls/private/md5.h \ + mbedtls/tf-psa-crypto/include/mbedtls/platform.h \ + mbedtls/tf-psa-crypto/drivers/builtin/include/mbedtls/private/sha1.h libmbedtls_la_SOURCES = \ - mbedtls/library/base64.c \ - mbedtls/library/md5.c \ - mbedtls/library/sha1.c \ - mbedtls/library/platform_util.c + mbedtls/tf-psa-crypto/drivers/builtin/src/base64.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/md5.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/sha1.c \ + mbedtls/tf-psa-crypto/drivers/builtin/src/platform_util.c -libmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\" -I$(top_srcdir)/others/mbedtls/include +libmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\" -I$(top_srcdir)/others/mbedtls/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/include -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/drivers/builtin/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/core libmbedtls_la_CPPFLAGS = libmbedtls_la_LIBADD = diff --git a/others/libinjection b/others/libinjection index b9fcaaf9e5..b2d46ec124 160000 --- a/others/libinjection +++ b/others/libinjection @@ -1 +1 @@ -Subproject commit b9fcaaf9e50e9492807b23ffcc6af46ee1f203b9 +Subproject commit b2d46ec124d947d2f82560074e4a348cb15148fc diff --git a/others/mbedtls b/others/mbedtls index 2ca6c285a0..abb0b22954 160000 --- a/others/mbedtls +++ b/others/mbedtls @@ -1 +1 @@ -Subproject commit 2ca6c285a0dd3f33982dd57299012dacab1ff206 +Subproject commit abb0b22954922cc0a28fda4ccf541273c882e171 diff --git a/src/Makefile.am b/src/Makefile.am index 14c26697b5..f77b9f3dc5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,8 @@ libmodsecurity_ladir = $(prefix)/include libmodsecurity_includesub_collectiondir = $(pkgincludedir)/collection/ libmodsecurity_includesub_actionsdir = $(pkgincludedir)/actions/ +MBEDTLS_CRYPTO_LIB = ../others/mbedtls/build/library/libmbedcrypto.a + # pregenerated parser + parser sources EXTRA_DIST = \ @@ -296,6 +298,9 @@ libmodsecurity_la_CPPFLAGS = \ -g \ -I$(top_srcdir)/others \ -I$(top_srcdir)/others/mbedtls/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/drivers/builtin/include \ + -I$(top_srcdir)/others/mbedtls/tf-psa-crypto/core \ -fPIC \ -O3 \ -I$(top_srcdir)/headers \ @@ -343,4 +348,3 @@ libmodsecurity_la_LIBADD = \ $(MAXMIND_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) - diff --git a/src/transaction.cc b/src/transaction.cc index 6c8ae9744c..a977464dbb 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -170,6 +170,12 @@ Transaction::~Transaction() { m_rulesMessages.clear(); + m_ruleRemoveById.clear(); + m_ruleRemoveByIdRange.clear(); + m_ruleRemoveByTag.clear(); + m_ruleRemoveTargetById.clear(); + m_ruleRemoveTargetByTag.clear(); + intervention::free(&m_it); intervention::clean(&m_it); diff --git a/src/utils/base64.cc b/src/utils/base64.cc index e27cace943..6fc1ec360b 100644 --- a/src/utils/base64.cc +++ b/src/utils/base64.cc @@ -10,7 +10,7 @@ * If any of the files related to licensing are missing or if you have any * other questions related to licensing please contact Trustwave Holdings, Inc. * directly using the email address security@modsecurity.org. - * + *#include "mbedtls/base64.h" */ #include "src/utils/base64.h" @@ -23,6 +23,7 @@ #include "mbedtls/base64.h" + template inline std::string base64Helper(const char *data, const unsigned int len, Operation op) { // cppcheck-suppress syntaxError ; false positive size_t out_len = 0; diff --git a/src/utils/md5.h b/src/utils/md5.h index 68f5d748e4..d77bde4fbf 100644 --- a/src/utils/md5.h +++ b/src/utils/md5.h @@ -1,32 +1,57 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. + * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. * + * Licensed under the Apache License, Version 2.0 */ #ifndef SRC_UTILS_MD5_H_ #define SRC_UTILS_MD5_H_ -#include "src/utils/sha1.h" -#include "mbedtls/md5.h" +#include "src/utils/sha1.h" // bringt DigestImpl und psa/crypto.h rein #include namespace modsecurity::Utils { - -class Md5 : public DigestImpl<&mbedtls_md5, 16> { +// Wrapper mit gleicher Signatur wie mbedtls_md5, +// intern aber PSA-API. +inline int modsec_psa_md5(const unsigned char *input, + size_t ilen, + unsigned char output[16]) +{ + // sha1.h macht bereits ein lazy psa_crypto_init() in modsec_psa_sha1, + // aber falls MD5 vor SHA1 benutzt wird, sorgen wir hier auch nochmal vor. + static bool psa_initialized = false; + + if (!psa_initialized) { + psa_status_t init_status = psa_crypto_init(); + if (init_status != PSA_SUCCESS) { + return -1; + } + psa_initialized = true; + } + + size_t out_len = 0; + psa_status_t status = psa_hash_compute( + PSA_ALG_MD5, + input, + ilen, + output, + 16, + &out_len + ); + + if (status != PSA_SUCCESS || out_len != 16) { + return -1; + } + + return 0; +} + +// Statt &mbedtls_md5 benutzen wir jetzt &modsec_psa_md5. +class Md5 : public DigestImpl<&modsec_psa_md5, 16> { }; - } // namespace modsecurity::Utils -#endif // SRC_UTILS_MD5_H_ \ No newline at end of file +#endif // SRC_UTILS_MD5_H_ diff --git a/src/utils/sha1.h b/src/utils/sha1.h index a40d7fa1c8..74cbad408f 100644 --- a/src/utils/sha1.h +++ b/src/utils/sha1.h @@ -1,29 +1,23 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/) - * - * You may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * If any of the files related to licensing are missing or if you have any - * other questions related to licensing please contact Trustwave Holdings, Inc. - * directly using the email address security@modsecurity.org. + * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. * + * Licensed under the Apache License, Version 2.0 */ #ifndef SRC_UTILS_SHA1_H_ #define SRC_UTILS_SHA1_H_ #include +#include #include #include "src/utils/string.h" -#include "mbedtls/sha1.h" -namespace modsecurity::Utils { +// NEU: PSA statt mbedtls/sha1.h +#include +namespace modsecurity::Utils { using DigestOp = int (*)(const unsigned char *, size_t, unsigned char []); @@ -31,44 +25,76 @@ using DigestOp = int (*)(const unsigned char *, size_t, unsigned char []); template class DigestImpl { public: - static std::string digest(const std::string& input) { - return digestHelper(input, [](const auto digest) { + return digestHelper(input, [](const auto digest) { return std::string(digest); }); } static void digestReplace(std::string& value) { - digestHelper(value, [&value](const auto digest) mutable { + digestHelper(value, [&value](const auto digest) mutable { value = digest; }); } static std::string hexdigest(const std::string &input) { - return digestHelper(input, [](const auto digest) { + return digestHelper(input, [](const auto digest) { return utils::string::string_to_hex(digest); }); } -private: - + private: template static auto digestHelper(const std::string &input, - ConvertOp convertOp) -> auto { + ConvertOp convertOp) -> auto { char digest[DigestSize]; - const auto ret = (*digestOp)(reinterpret_cast(input.c_str()), - input.size(), reinterpret_cast(digest)); + const auto ret = (*digestOp)( + reinterpret_cast(input.c_str()), + input.size(), + reinterpret_cast(digest) + ); assert(ret == 0); return convertOp(std::string_view(digest, DigestSize)); } }; +// NEU: Wrapper, der die PSA-API in die alte Signatur presst. +inline int modsec_psa_sha1(const unsigned char *input, + size_t ilen, + unsigned char output[20]) +{ + static bool psa_initialized = false; + + if (!psa_initialized) { + psa_status_t init_status = psa_crypto_init(); + if (init_status != PSA_SUCCESS) { + return -1; + } + psa_initialized = true; + } -class Sha1 : public DigestImpl<&mbedtls_sha1, 20> { -}; + size_t out_len = 0; + psa_status_t status = psa_hash_compute( + PSA_ALG_SHA_1, + input, + ilen, + output, + 20, + &out_len + ); + + if (status != PSA_SUCCESS || out_len != 20) { + return -1; + } + + return 0; +} +// Statt &mbedtls_sha1 nehmen wir jetzt unseren PSA-Wrapper +class Sha1 : public DigestImpl<&modsec_psa_sha1, 20> { +}; } // namespace modsecurity::Utils diff --git a/test/Makefile.am b/test/Makefile.am index 2e7e05d614..f670c754f6 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -41,6 +41,7 @@ noinst_HEADERS = \ unit/*.h \ regression/*.h +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ unit_tests_LDADD = \ $(CURL_LDADD) \ @@ -53,7 +54,8 @@ unit_tests_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) unit_tests_LDFLAGS = \ @@ -108,7 +110,8 @@ regression_tests_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) regression_tests_LDFLAGS = \ @@ -162,7 +165,8 @@ rules_optimization_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) rules_optimization_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/test/benchmark/Makefile.am b/test/benchmark/Makefile.am index 2ac9d92111..c89e42234e 100644 --- a/test/benchmark/Makefile.am +++ b/test/benchmark/Makefile.am @@ -1,4 +1,4 @@ - +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ noinst_PROGRAMS = benchmark @@ -16,7 +16,8 @@ benchmark_LDADD = \ $(SSDEEP_LDADD) \ $(LUA_LDADD) \ $(LIBXML2_LDADD) \ - $(GLOBAL_LDADD) + $(GLOBAL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) benchmark_LDFLAGS = \ -L$(top_builddir)/src/.libs/ \ diff --git a/test/test-cases/secrules-language-tests b/test/test-cases/secrules-language-tests index a3d4405e5a..c6e8802366 160000 --- a/test/test-cases/secrules-language-tests +++ b/test/test-cases/secrules-language-tests @@ -1 +1 @@ -Subproject commit a3d4405e5a2c90488c387e589c5534974575e35b +Subproject commit c6e8802366ec3182b8c2612e23d14e19e3545b47 diff --git a/tools/rules-check/Makefile.am b/tools/rules-check/Makefile.am index 8080411716..95da5773d2 100644 --- a/tools/rules-check/Makefile.am +++ b/tools/rules-check/Makefile.am @@ -5,6 +5,8 @@ bin_PROGRAMS = modsec-rules-check modsec_rules_check_SOURCES = \ rules-check.cc +MBEDTLS_CRYPTO_LIB = @MBEDTLS_CRYPTO_LIB@ + modsec_rules_check_LDADD = \ $(top_builddir)/src/.libs/libmodsecurity.la \ $(CURL_LDADD) \ @@ -17,7 +19,8 @@ modsec_rules_check_LDADD = \ $(PCRE_LDADD) \ $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ - $(YAJL_LDADD) + $(YAJL_LDADD) \ + $(MBEDTLS_CRYPTO_LIB) modsec_rules_check_LDFLAGS = \ $(GEOIP_LDFLAGS) \