From df18d331c29968132ba38613e88e2cdb3eaf72ae Mon Sep 17 00:00:00 2001 From: Arthur Meyre Date: Mon, 20 Dec 2021 11:56:21 +0100 Subject: [PATCH] chore: add pip-audit and schedule step for weekly closes #1076 --- .github/workflows/continuous-integration.yaml | 48 +++- Makefile | 4 + poetry.lock | 223 +++++++++++++++++- pyproject.toml | 1 + script/actions_utils/parse_pip_audit_vulns.py | 66 ++++++ 5 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 script/actions_utils/parse_pip_audit_vulns.py diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index c5e928c4d..dc75b655d 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -219,8 +219,6 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 - with: - fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@f38219332975fe8f9c04cca981d674bf22aea1d3 with: @@ -401,6 +399,52 @@ jobs: ec2-instance-id: ${{ needs.start-runner.outputs.ec2-instance-id }} mode: stop + weekly-pip-audit: + if: ${{ github.event_name == 'schedule' }} + runs-on: ubuntu-20.04 + steps: + - name: Checkout Code + uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 + - name: Set up Python 3.8 + uses: actions/setup-python@f38219332975fe8f9c04cca981d674bf22aea1d3 + with: + python-version: '3.8' + - name: Set up env + run: | + python -m pip install --upgrade pip + python -m pip install poetry + sudo apt update && sudo apt install graphviz* -y + make setup_env + - name: Run pip-audit + shell: bash + run: | + VULN_OUT="$(mktemp --suffix=.json)" + REPORT_OUT="$(mktemp --suffix=.txt)" + echo "REPORT_OUT=${REPORT_OUT}" >> "$GITHUB_ENV" + poetry run pip-audit -f json > "${VULN_OUT}" + cat "${VULN_OUT}" + poetry run python ./script/actions_utils/parse_pip_audit_vulns.py \ + --vulns-json "${VULN_OUT}" \ + --vulns-report "${REPORT_OUT}" + # We load the report in a new step if we exited with an error code above to let the workflow fail + - name: Load report in env + if: ${{ always() }} + run: | + cat "${REPORT_OUT}" + REPORT="$(cat "${REPORT_OUT}")" + echo "REPORT=${REPORT}" >> "$GITHUB_ENV" + - name: Slack Notification + if: ${{ always() && !success() }} + continue-on-error: true + uses: rtCamp/action-slack-notify@12e36fc18b0689399306c2e0b3e0f2978b7f1ee7 + env: + SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }} + SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png + SLACK_COLOR: ${{ job.status }} + SLACK_MESSAGE: "${{ env.REPORT || 'Error during pip-audit' }} (${{ env.ACTION_RUN_URL }})" + SLACK_USERNAME: ${{ secrets.BOT_USERNAME }} + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} + publish-docs: needs: [build] concurrency: diff --git a/Makefile b/Makefile index 004022d57..069763415 100644 --- a/Makefile +++ b/Makefile @@ -348,3 +348,7 @@ check_licenses: .PHONY: help # Generate list of targets with descriptions help: @grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1\t\2/' | expand -t30 | sort + +.PHONY: pip_audit # Run pip-audit and check if there are known vulnerabilities in our dependencies +pip_audit: + poetry run pip-audit diff --git a/poetry.lock b/poetry.lock index 99d2bcf03..405ce327f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -153,6 +153,22 @@ packaging = "*" six = ">=1.9.0" webencodings = "*" +[[package]] +name = "cachecontrol" +version = "0.12.10" +description = "httplib2 caching for requests" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +msgpack = ">=0.5.2" +requests = "*" + +[package.extras] +filecache = ["lockfile (>=0.9)"] +redis = ["redis (>=2.10.5)"] + [[package]] name = "certifi" version = "2021.10.8" @@ -254,6 +270,20 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "cyclonedx-python-lib" +version = "0.12.3" +description = "A library for producing CycloneDX SBOM (Software Bill of Materials) files." +category = "dev" +optional = false +python-versions = ">=3.6,<4.0" + +[package.dependencies] +packageurl-python = ">=0.9" +toml = ">=0.10.0,<0.11.0" +types-setuptools = ">=57.0.0" +types-toml = ">=0.10.0,<0.11.0" + [[package]] name = "debugpy" version = "1.5.1" @@ -388,6 +418,24 @@ python-versions = ">=3.7" gitdb = ">=4.0.1,<5" typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} +[[package]] +name = "html5lib" +version = "1.1" +description = "HTML parser based on the WHATWG HTML specification" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +six = ">=1.9" +webencodings = "*" + +[package.extras] +all = ["genshi", "chardet (>=2.2)", "lxml"] +chardet = ["chardet (>=2.2)"] +genshi = ["genshi"] +lxml = ["lxml"] + [[package]] name = "idna" version = "3.3" @@ -731,6 +779,14 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "lockfile" +version = "0.12.2" +description = "Platform-independent file locking module" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "loguru" version = "0.5.3" @@ -835,6 +891,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "msgpack" +version = "1.0.3" +description = "MessagePack (de)serializer." +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "mypy" version = "0.910" @@ -1042,6 +1106,17 @@ category = "main" optional = false python-versions = ">=3.7,<3.11" +[[package]] +name = "packageurl-python" +version = "0.9.6" +description = "A purl aka. Package URL parser and builder" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +test = ["pytest", "isort"] + [[package]] name = "packaging" version = "21.3" @@ -1129,6 +1204,35 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "pip-api" +version = "0.0.26" +description = "An unofficial, importable pip API" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pip-audit" +version = "1.1.1" +description = "A tool for scanning Python environments for known vulnerabilities" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +CacheControl = ">=0.12.10" +cyclonedx-python-lib = ">=0.11.1" +html5lib = ">=1.1" +lockfile = ">=0.12.2" +packaging = ">=21.0.0" +pip-api = ">=0.0.26" +progress = ">=1.6" +resolvelib = ">=0.8.0" + +[package.extras] +dev = ["bump", "flake8", "black", "isort", "pytest", "pytest-cov", "pretend", "coverage", "interrogate", "mypy", "types-requests", "types-html5lib", "types-dataclasses", "pdoc3"] + [[package]] name = "pip-licenses" version = "3.5.3" @@ -1178,6 +1282,14 @@ python-versions = ">=3.6" dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "progress" +version = "1.6" +description = "Easy to use progress bars" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "prometheus-client" version = "0.12.0" @@ -1628,6 +1740,20 @@ python-versions = "*" [package.dependencies] requests = ">=2.0.1,<3.0.0" +[[package]] +name = "resolvelib" +version = "0.8.1" +description = "Resolve abstract dependencies into concrete ones" +category = "dev" +optional = false +python-versions = "*" + +[package.extras] +examples = ["html5lib", "packaging", "pygraphviz", "requests"] +lint = ["black", "flake8", "mypy", "isort", "types-requests"] +release = ["build", "towncrier", "twine"] +test = ["commentjson", "packaging", "pytest"] + [[package]] name = "rfc3986" version = "1.5.0" @@ -2006,6 +2132,22 @@ requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0" rfc3986 = ">=1.4.0" tqdm = ">=4.14" +[[package]] +name = "types-setuptools" +version = "57.4.4" +description = "Typing stubs for setuptools" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "types-toml" +version = "0.10.1" +description = "Typing stubs for toml" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "typing-extensions" version = "4.0.1" @@ -2092,7 +2234,7 @@ full = ["pygraphviz"] [metadata] lock-version = "1.1" python-versions = ">=3.8,<3.11" -content-hash = "f0b36d7e0d58df807aa484d3ffbd8d72dcf40fce0e0f4ff25593e2e9374e2c78" +content-hash = "767afd54d83cdd78c3ddf10a8972660d839b7baa6d69fee693acfda671be67ed" [metadata.files] alabaster = [ @@ -2162,6 +2304,10 @@ bleach = [ {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"}, {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"}, ] +cachecontrol = [ + {file = "CacheControl-0.12.10-py2.py3-none-any.whl", hash = "sha256:b0d43d8f71948ef5ebdee5fe236b86c6ffc7799370453dccb0e894c20dfa487c"}, + {file = "CacheControl-0.12.10.tar.gz", hash = "sha256:d8aca75b82eec92d84b5d6eb8c8f66ea16f09d2adb09dbca27fe2d5fc8d3732d"}, +] certifi = [ {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, @@ -2309,6 +2455,10 @@ cycler = [ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, ] +cyclonedx-python-lib = [ + {file = "cyclonedx-python-lib-0.12.3.tar.gz", hash = "sha256:ea2d5393a3de4a347e9c99c6c59efe4e3f64da2fb48e80f3e350fee289fa8a73"}, + {file = "cyclonedx_python_lib-0.12.3-py3-none-any.whl", hash = "sha256:ba7297148c0f3a72ed3395495080be86a344539084f9d4df9c0f3b466e4f6e54"}, +] debugpy = [ {file = "debugpy-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:70b422c63a833630c33e3f9cdbd9b6971f8c5afd452697e464339a21bbe862ba"}, {file = "debugpy-1.5.1-cp310-cp310-win32.whl", hash = "sha256:3a457ad9c0059a21a6c7d563c1f18e924f5cf90278c722bd50ede6f56b77c7fe"}, @@ -2375,6 +2525,10 @@ gitpython = [ {file = "GitPython-3.1.24-py3-none-any.whl", hash = "sha256:dc0a7f2f697657acc8d7f89033e8b1ea94dd90356b2983bca89dc8d2ab3cc647"}, {file = "GitPython-3.1.24.tar.gz", hash = "sha256:df83fdf5e684fef7c6ee2c02fc68a5ceb7e7e759d08b694088d0cacb4eba59e5"}, ] +html5lib = [ + {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, + {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, +] idna = [ {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, @@ -2554,6 +2708,10 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, ] +lockfile = [ + {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, + {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, +] loguru = [ {file = "loguru-0.5.3-py3-none-any.whl", hash = "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c"}, {file = "loguru-0.5.3.tar.gz", hash = "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319"}, @@ -2686,6 +2844,42 @@ mistune = [ {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, ] +msgpack = [ + {file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079"}, + {file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3"}, + {file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73"}, + {file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147"}, + {file = "msgpack-1.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39"}, + {file = "msgpack-1.0.3-cp310-cp310-win32.whl", hash = "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85"}, + {file = "msgpack-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7"}, + {file = "msgpack-1.0.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d"}, + {file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b"}, + {file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec"}, + {file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770"}, + {file = "msgpack-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9"}, + {file = "msgpack-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a"}, + {file = "msgpack-1.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a"}, + {file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc"}, + {file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a"}, + {file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920"}, + {file = "msgpack-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50"}, + {file = "msgpack-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba"}, + {file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea"}, + {file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a"}, + {file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef"}, + {file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611"}, + {file = "msgpack-1.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1"}, + {file = "msgpack-1.0.3-cp38-cp38-win32.whl", hash = "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4"}, + {file = "msgpack-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a"}, + {file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3"}, + {file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52"}, + {file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2"}, + {file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996"}, + {file = "msgpack-1.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2"}, + {file = "msgpack-1.0.3-cp39-cp39-win32.whl", hash = "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88"}, + {file = "msgpack-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d"}, + {file = "msgpack-1.0.3.tar.gz", hash = "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e"}, +] mypy = [ {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"}, {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"}, @@ -2783,6 +2977,10 @@ numpy = [ {file = "numpy-1.21.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a3deb31bc84f2b42584b8c4001c85d1934dbfb4030827110bc36bfd11509b7bf"}, {file = "numpy-1.21.4.zip", hash = "sha256:e6c76a87633aa3fa16614b61ccedfae45b91df2767cf097aa9c933932a7ed1e0"}, ] +packageurl-python = [ + {file = "packageurl-python-0.9.6.tar.gz", hash = "sha256:c01fbaf62ad2eb791e97158d1f30349e830bee2dd3e9503a87f6c3ffae8d1cf0"}, + {file = "packageurl_python-0.9.6-py3-none-any.whl", hash = "sha256:676dcb8278721df952e2444bfcd8d7bf3518894498050f0c6a5faddbe0860cd0"}, +] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, @@ -2876,6 +3074,14 @@ pillow = [ {file = "Pillow-8.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc"}, {file = "Pillow-8.4.0.tar.gz", hash = "sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed"}, ] +pip-api = [ + {file = "pip-api-0.0.26.tar.gz", hash = "sha256:d1266be311f1cd1ddd0d501e99275c7f6ff1fd0ec6db46d521f56e747d9286e5"}, + {file = "pip_api-0.0.26-py3-none-any.whl", hash = "sha256:b24e94e5d5d3f161a2db49653798e6a4c1f0ed6b379e511b45a8fa57c185d711"}, +] +pip-audit = [ + {file = "pip-audit-1.1.1.tar.gz", hash = "sha256:61d772968b6ef644f43ecceace89665d28d7ea521a9390e59188c4189d580856"}, + {file = "pip_audit-1.1.1-py3-none-any.whl", hash = "sha256:86aff3427a544757d1d30e8a0ee83eb040c85a94e7b8b6541ed4058493090b44"}, +] pip-licenses = [ {file = "pip-licenses-3.5.3.tar.gz", hash = "sha256:f44860e00957b791c6c6005a3328f2d5eaeee96ddb8e7d87d4b0aa25b02252e4"}, {file = "pip_licenses-3.5.3-py3-none-any.whl", hash = "sha256:59c148d6a03784bf945d232c0dc0e9de4272a3675acaa0361ad7712398ca86ba"}, @@ -2892,6 +3098,9 @@ pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] +progress = [ + {file = "progress-1.6.tar.gz", hash = "sha256:c9c86e98b5c03fa1fe11e3b67c1feda4788b8d0fe7336c2ff7d5644ccfba34cd"}, +] prometheus-client = [ {file = "prometheus_client-0.12.0-py2.py3-none-any.whl", hash = "sha256:317453ebabff0a1b02df7f708efbab21e3489e7072b61cb6957230dd004a0af0"}, {file = "prometheus_client-0.12.0.tar.gz", hash = "sha256:1b12ba48cee33b9b0b9de64a1047cbd3c5f2d0ab6ebcead7ddda613a750ec3c5"}, @@ -3194,6 +3403,10 @@ requests-toolbelt = [ {file = "requests-toolbelt-0.9.1.tar.gz", hash = "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"}, {file = "requests_toolbelt-0.9.1-py2.py3-none-any.whl", hash = "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f"}, ] +resolvelib = [ + {file = "resolvelib-0.8.1-py2.py3-none-any.whl", hash = "sha256:d9b7907f055c3b3a2cfc56c914ffd940122915826ff5fb5b1de0c99778f4de98"}, + {file = "resolvelib-0.8.1.tar.gz", hash = "sha256:c6ea56732e9fb6fca1b2acc2ccc68a0b6b8c566d8f3e78e0443310ede61dbd37"}, +] rfc3986 = [ {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, @@ -3422,6 +3635,14 @@ twine = [ {file = "twine-3.7.1-py3-none-any.whl", hash = "sha256:8c120845fc05270f9ee3e9d7ebbed29ea840e41f48cd059e04733f7e1d401345"}, {file = "twine-3.7.1.tar.gz", hash = "sha256:28460a3db6b4532bde6a5db6755cf2dce6c5020bada8a641bb2c5c7a9b1f35b8"}, ] +types-setuptools = [ + {file = "types-setuptools-57.4.4.tar.gz", hash = "sha256:a3cbcbf3f02142bb5d3b5c5f5918f453b8752362b96d58aba2a5cfa43ba6d209"}, + {file = "types_setuptools-57.4.4-py3-none-any.whl", hash = "sha256:9fe4180548e5cbb44cc0d343a47e4dc1d6769c31e16447994788c28df169011f"}, +] +types-toml = [ + {file = "types-toml-0.10.1.tar.gz", hash = "sha256:5c1f8f8d57692397c8f902bf6b4d913a0952235db7db17d2908cc110e70610cb"}, + {file = "types_toml-0.10.1-py3-none-any.whl", hash = "sha256:8cdfd2b7c89bed703158b042dd5cf04255dae77096db66f4a12ca0a93ccb07a5"}, +] typing-extensions = [ {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, diff --git a/pyproject.toml b/pyproject.toml index 6fb02a810..4ef3986a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,6 +50,7 @@ pip-licenses = "^3.5.3" sphinx-zama-theme = "2.0.8" scikit-learn = "1.0.1" pandas = "1.3.4" +pip-audit = "^1.1.1" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/script/actions_utils/parse_pip_audit_vulns.py b/script/actions_utils/parse_pip_audit_vulns.py new file mode 100644 index 000000000..2f14b0d65 --- /dev/null +++ b/script/actions_utils/parse_pip_audit_vulns.py @@ -0,0 +1,66 @@ +"""Script to parse output of pip-audit""" + +import argparse +import json +import sys +from pathlib import Path +from typing import List + + +def format_vulnerability(pkg_name, pkg_version, vuln_info: dict) -> List[str]: + """Format a vulnerability info.""" + + vuln_strs = [ + f"{pkg_name}({pkg_version}) - ID: {vuln['id']} " + f"fixed in {', '.join(vuln['fix_versions'])}" + for vuln in vuln_info + ] + return vuln_strs + + +# Cannot have a backslash in f-string, so create a constant for newline +NEW_LINE = "\n" + + +def main(args): + """Entry point""" + + vulns_json_path = Path(args.vulns_json).resolve() + json_content = [] + with open(vulns_json_path, "r", encoding="utf-8") as f: + json_content.extend(f.readlines()) + + report_path = Path(args.vulns_report).resolve() + with open(report_path, "w", encoding="utf-8") as report: + if json_content: + report.write("Found the following vulnerabilities:\n") + assert len(json_content) == 1 + json_data = json.loads(json_content[0]) + # print(json.dumps(json_data, indent=4)) + for entry in json_data: + vuln_entries = entry.get("vulns", []) + if vuln_entries: + formatted_vulns = format_vulnerability( + entry["name"], entry["version"], vuln_entries + ) + report.write(f"- {f'{NEW_LINE}- '.join(formatted_vulns)}\n") + sys.exit(1) + else: + report.write("No vulnerabilities found.\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser("pip-audit output parser", allow_abbrev=False) + + parser.add_argument( + "--vulns-json", type=str, required=True, help="The path to the pip-audit json output" + ) + parser.add_argument( + "--vulns-report", + type=str, + required=True, + help="Path to the file to which to write the vulneratbility report", + ) + + cli_args = parser.parse_args() + main(cli_args)