Fix three RCE vectors in the build system #4812
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Automatus Debian 12 | |
| on: | |
| pull_request: | |
| branches: [master, 'stabilization*'] | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: >- | |
| ${{ github.workflow }}-${{ | |
| github.event.number || github.run_id }} | |
| cancel-in-progress: true | |
| env: | |
| DATASTREAM: ssg-debian12-ds.xml | |
| jobs: | |
| build-content: | |
| name: Build Content | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Install Deps | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y \ | |
| cmake ninja-build python3-yaml \ | |
| python3-jinja2 git python3-deepdiff \ | |
| python3-requests jq python3-pip \ | |
| libxml2-utils xsltproc ansible-lint wget \ | |
| libdbus-1-dev libdbus-glib-1-dev \ | |
| libcurl4-openssl-dev libgcrypt20-dev \ | |
| libselinux1-dev libxslt1-dev \ | |
| libgconf2-dev libacl1-dev libblkid-dev \ | |
| libcap-dev libxml2-dev libldap2-dev \ | |
| libpcre3-dev python3 swig \ | |
| libxml-parser-perl libxml-xpath-perl \ | |
| libperl-dev libbz2-dev librpm-dev g++ \ | |
| libyaml-dev libxmlsec1-dev \ | |
| libxmlsec1-openssl | |
| - name: Install deps python | |
| run: pip3 install gitpython xmldiff lxml lxml-stubs requests | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Checkout (CTF) | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v4 | |
| with: | |
| repository: ComplianceAsCode/content-test-filtering | |
| path: ctf | |
| # https://github.com/actions/checkout/issues/766 | |
| - name: Set git safe directory | |
| run: >- | |
| git config --global --add safe.directory | |
| "$GITHUB_WORKSPACE" | |
| - name: Find forking point | |
| env: | |
| BASE_BRANCH: ${{ github.base_ref }} | |
| run: | | |
| FORK_POINT=$(git merge-base \ | |
| origin/$BASE_BRANCH \ | |
| ${{ github.event.pull_request.head.sha }}) | |
| echo "FORK_POINT=$FORK_POINT" >> $GITHUB_OUTPUT | |
| id: fork_point | |
| - name: Detect content changes in the PR | |
| run: | | |
| python3 ./ctf/content_test_filtering.py pr \ | |
| --base ${{ steps.fork_point.outputs.FORK_POINT }} \ | |
| --remote_repo \ | |
| ${{ github.server_url }}/${{ github.repository }} \ | |
| --verbose --rule --output json \ | |
| ${{ github.event.pull_request.number }} \ | |
| > output.json | |
| - name: Test if there are no content changes | |
| run: >- | |
| echo "CTF_OUTPUT_SIZE=$(stat --printf="%s" | |
| output.json)" >> $GITHUB_OUTPUT | |
| id: ctf | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 | |
| if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| with: | |
| name: output.json | |
| path: output.json | |
| - name: Print changes to content detected if any | |
| if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: cat output.json | |
| - name: Get product attribute | |
| if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| id: product | |
| # yamllint disable-line rule:line-length | |
| uses: notiz-dev/github-action-json-property@a5a9c668b16513c737c3e1f8956772c99c73f6e8 # v0.2.0 | |
| with: | |
| path: 'output.json' | |
| prop_path: 'product' | |
| - name: Download OpenSCAP | |
| run: | | |
| wget \ | |
| https://github.com/OpenSCAP/openscap/releases/download/1.3.10/openscap-1.3.10.tar.gz | |
| - name: Extract OpenSCAP | |
| run: tar xf openscap-1.3.10.tar.gz | |
| - name: Build OpenSCAP | |
| run: | | |
| cd openscap-1.3.10 | |
| cmake -Bbuild -DCMAKE_INSTALL_PREFIX=/usr . | |
| sudo cmake --build build --target install | |
| - name: Build product | |
| if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: ./build_product debian12 | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 | |
| if: ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| with: | |
| name: ${{ env.DATASTREAM }} | |
| path: build/${{ env.DATASTREAM }} | |
| validate-ubuntu: | |
| name: Run Tests | |
| needs: build-content | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Install Deps | |
| run: | | |
| sudo apt update && sudo apt install -y \ | |
| cmake ninja-build libxml2-utils xsltproc \ | |
| python3-jinja2 python3-yaml ansible-lint \ | |
| podman wget \ | |
| libdbus-1-dev libdbus-glib-1-dev \ | |
| libcurl4-openssl-dev libgcrypt20-dev \ | |
| libselinux1-dev libxslt1-dev \ | |
| libgconf2-dev libacl1-dev libblkid-dev \ | |
| libcap-dev libxml2-dev libldap2-dev \ | |
| libpcre3-dev python3 swig \ | |
| libxml-parser-perl libxml-xpath-perl \ | |
| libperl-dev libbz2-dev librpm-dev g++ \ | |
| libyaml-dev libxmlsec1-dev \ | |
| libxmlsec1-openssl | |
| - name: Checkout | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v4 | |
| - name: Get cached CTF output | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 | |
| id: get_ctf_output | |
| with: | |
| name: output.json | |
| # continue even if the file is unavailable; | |
| # that means there are no changes detected | |
| # by CTF in the previous job | |
| continue-on-error: true | |
| - name: Download OpenSCAP | |
| run: | | |
| wget \ | |
| https://github.com/OpenSCAP/openscap/releases/download/1.3.10/openscap-1.3.10.tar.gz | |
| - name: Extract OpenSCAP | |
| run: tar xf openscap-1.3.10.tar.gz | |
| - name: Build OpenSCAP | |
| run: | | |
| cd openscap-1.3.10 | |
| cmake -Bbuild -DCMAKE_INSTALL_PREFIX=/usr . | |
| sudo cmake --build build --target install | |
| - name: Test if there are no content changes | |
| if: >- | |
| ${{ steps.get_ctf_output.outcome == 'success' }} | |
| run: >- | |
| echo "CTF_OUTPUT_SIZE=$(stat --printf="%s" | |
| output.json)" >> $GITHUB_OUTPUT | |
| id: ctf | |
| - name: Print changes to content detected if any | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: cat output.json | |
| - name: Generate id_rsa key | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: ssh-keygen -N '' -t rsa -f ~/.ssh/id_rsa | |
| - name: Build test suite container | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: | | |
| podman build \ | |
| --build-arg \ | |
| "CLIENT_PUBLIC_KEY=$(cat ~/.ssh/id_rsa.pub)" \ | |
| -t ssg_test_suite \ | |
| -f test_suite-debian12 | |
| working-directory: ./Dockerfiles | |
| - name: Get oscap-ssh | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: | | |
| wget https://raw.githubusercontent.com/OpenSCAP/openscap/maint-1.3/utils/oscap-ssh | |
| sudo chmod 755 oscap-ssh | |
| sudo mv -v oscap-ssh /usr/local/bin | |
| sudo chown root:root /usr/local/bin/oscap-ssh | |
| rm -f oscap-ssh | |
| - name: Get rule ids to be tested | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| id: rules | |
| # yamllint disable-line rule:line-length | |
| uses: notiz-dev/github-action-json-property@a5a9c668b16513c737c3e1f8956772c99c73f6e8 # v0.2.0 | |
| with: | |
| path: 'output.json' | |
| prop_path: 'rules' | |
| - name: Get product attribute | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| id: product | |
| # yamllint disable-line rule:line-length | |
| uses: notiz-dev/github-action-json-property@a5a9c668b16513c737c3e1f8956772c99c73f6e8 # v0.2.0 | |
| with: | |
| path: 'output.json' | |
| prop_path: 'product' | |
| - name: Get bash attribute | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| id: bash | |
| # yamllint disable-line rule:line-length | |
| uses: notiz-dev/github-action-json-property@a5a9c668b16513c737c3e1f8956772c99c73f6e8 # v0.2.0 | |
| with: | |
| path: 'output.json' | |
| prop_path: 'bash' | |
| - name: Get ansible attribute | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| id: ansible | |
| # yamllint disable-line rule:line-length | |
| uses: notiz-dev/github-action-json-property@a5a9c668b16513c737c3e1f8956772c99c73f6e8 # v0.2.0 | |
| with: | |
| path: 'output.json' | |
| prop_path: 'ansible' | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 | |
| if: >- | |
| ${{ steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| with: | |
| name: ${{ env.DATASTREAM }} | |
| - name: Run tests in a container - Bash | |
| if: >- | |
| ${{steps.bash.outputs.prop == 'True' | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: | | |
| tests/test_rule_in_container.sh \ | |
| --no-make-applicable-in-containers \ | |
| --dontclean \ | |
| --logdir logs_bash \ | |
| --remediate-using bash \ | |
| --name ssg_test_suite \ | |
| --datastream $DATASTREAM \ | |
| ${{join(fromJSON(steps.rules.outputs.prop))}} | |
| env: | |
| ADDITIONAL_TEST_OPTIONS: >- | |
| --duplicate-templates | |
| --remove-fips-certified | |
| - name: Check for ERROR in logs | |
| if: >- | |
| ${{steps.bash.outputs.prop == 'True' | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: grep -q "^ERROR" logs_bash/test_suite.log | |
| id: check_results_bash | |
| # when grep returns 1 means it didn't find the | |
| # ^ERROR string in the test_suite.log file and | |
| # this means tests finished successfully without | |
| # errors. So the job needs to keep going. | |
| # By using continue-on-error: true the | |
| # "conclusion" parameter is set to true so it's | |
| # not possible to use it to determine whether | |
| # the task has failed or succeed. The "outcome" | |
| # parameter has to be used instead. | |
| # See the step below | |
| continue-on-error: true | |
| - name: Upload logs in case of failure | |
| if: >- | |
| ${{steps.bash.outputs.prop == 'True' | |
| && steps.check_results_bash.outcome == 'success' | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 | |
| with: | |
| name: logs_bash | |
| path: logs_bash/ | |
| - name: Run tests in a container - Ansible | |
| if: >- | |
| ${{ steps.ansible.outputs.prop == 'True' | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: | | |
| tests/test_rule_in_container.sh \ | |
| --no-make-applicable-in-containers \ | |
| --dontclean \ | |
| --logdir logs_ansible \ | |
| --remediate-using ansible \ | |
| --name ssg_test_suite \ | |
| --datastream $DATASTREAM \ | |
| ${{join(fromJSON(steps.rules.outputs.prop))}} | |
| env: | |
| ADDITIONAL_TEST_OPTIONS: >- | |
| --duplicate-templates | |
| --remove-fips-certified | |
| --product debian12 | |
| - name: Check for ERROR in logs | |
| if: >- | |
| ${{steps.ansible.outputs.prop == 'True' | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: grep -q "^ERROR" logs_ansible/test_suite.log | |
| id: check_results_ansible | |
| continue-on-error: true | |
| - name: Upload logs in case of failure | |
| if: >- | |
| ${{ steps.ansible.outputs.prop == 'True' | |
| && steps.check_results_ansible.outcome == 'success' | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 | |
| with: | |
| name: logs_ansible | |
| path: logs_ansible/ | |
| - name: Fail if ERROR in test logs | |
| if: >- | |
| ${{ (steps.check_results_bash.outcome == 'success' | |
| || steps.check_results_ansible.outcome == 'success') | |
| && steps.ctf.outputs.CTF_OUTPUT_SIZE != '0' }} | |
| run: | | |
| [[ -f logs_bash/test_suite.log ]] \ | |
| && echo "---Bash Remediation Logs---" \ | |
| && cat logs_bash/test_suite.log \ | |
| | grep -v "DEBUG - " | |
| [[ -f logs_ansible/test_suite.log ]] \ | |
| && echo "---Ansible Remediation Logs---" \ | |
| && cat logs_ansible/test_suite.log \ | |
| | grep -v "DEBUG - " | |
| exit 1 |