Skip to content

Fix three RCE vectors in the build system #4812

Fix three RCE vectors in the build system

Fix three RCE vectors in the build system #4812

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