From 4b3ff02d4906ec3424e08843c91ba01a49035e58 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Dec 2025 11:06:49 +0100 Subject: [PATCH 1/4] chore: Add pip-audit action --- .github/workflows/ci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf4384a1c..510efe64f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,6 +60,8 @@ jobs: uv pip install -e ft_client/ uv pip install -e . + - uses: pypa/gh-action-pip-audit@1220774d901786e6f652ae159f7b6bc8fea6d266 # v1.1.0 + - name: Check for version alignment run: | python build_helpers/freqtrade_client_version_align.py @@ -87,12 +89,12 @@ jobs: rm -rf codecov codecov.SHA256SUM codecov.SHA256SUM.sig - name: Run json schema extract - # This should be kept before the repository check to ensure that the schema is up-to-date + # This must be kept before the repository check to ensure that the schema is up-to-date run: | python build_helpers/extract_config_json_schema.py - name: Run command docs partials extract - # This should be kept before the repository check to ensure that the docs are up-to-date + # This must be kept before the repository check to ensure that the docs are up-to-date if: ${{ (matrix.python-version == '3.13') }} run: | python build_helpers/create_command_partials.py From f55a90d98cbcb6d9b9a4304339848118bac950d9 Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Dec 2025 11:35:25 +0100 Subject: [PATCH 2/4] chore: add pip-audit as dependency and test --- .github/workflows/ci.yml | 1 - requirements-dev.txt | 1 + tests/test_pip_audit.py | 85 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tests/test_pip_audit.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 510efe64f..f596da117 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,6 @@ jobs: uv pip install -e ft_client/ uv pip install -e . - - uses: pypa/gh-action-pip-audit@1220774d901786e6f652ae159f7b6bc8fea6d266 # v1.1.0 - name: Check for version alignment run: | diff --git a/requirements-dev.txt b/requirements-dev.txt index 38a49f661..a59805e46 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -30,3 +30,4 @@ types-filelock==3.2.7 types-requests==2.32.4.20250913 types-tabulate==0.9.0.20241207 types-python-dateutil==2.9.0.20251115 +pip-audit==2.10.0 diff --git a/tests/test_pip_audit.py b/tests/test_pip_audit.py new file mode 100644 index 000000000..fca696193 --- /dev/null +++ b/tests/test_pip_audit.py @@ -0,0 +1,85 @@ +import subprocess +import sys +from pathlib import Path + +import pytest + + +def test_pip_audit_no_vulnerabilities(): + """ + Run pip-audit to check for known security vulnerabilities. + + This test will fail if any vulnerabilities are detected in the installed packages. + + Note: CVE-2025-53000 (nbconvert Windows vulnerability) is ignored as it only affects + Windows platforms and is a known acceptable risk for this project. + """ + # Get the project root directory + project_root = Path(__file__).parent.parent + command = [ + sys.executable, + "-m", + "pip_audit", + # "--format=json", + "--progress-spinner=off", + "--ignore-vuln", + "CVE-2025-53000", + "--skip-editable", + ] + + # Run pip-audit with JSON output for easier parsing + try: + result = subprocess.run( + command, + cwd=project_root, + capture_output=True, + text=True, + timeout=120, # 2 minute timeout + ) + except subprocess.TimeoutExpired: + pytest.fail("pip-audit command timed out after 120 seconds") + except FileNotFoundError: + pytest.fail("pip-audit not installed or not accessible") + + # Check if pip-audit found any vulnerabilities + if result.returncode != 0: + # pip-audit returns non-zero when vulnerabilities are found + error_output = result.stdout + "\n" + result.stderr + + # Check if it's an actual vulnerability vs an error + if "vulnerabilities found" in error_output.lower() or '"dependencies"' in result.stdout: + pytest.fail( + f"pip-audit detected security vulnerabilities!\n\n" + f"Output:\n{result.stdout}\n\n" + f"Please review and update vulnerable packages.\n" + f"Run manually with: {' '.join(command)}" + ) + else: + # Some other error occurred + pytest.fail( + f"pip-audit failed to run properly:\n\nReturn code: {result.returncode}\nOutput: {error_output}\n" + ) + + # Success - no vulnerabilities found + assert result.returncode == 0, "pip-audit should return 0 when no vulnerabilities are found" + + +def test_pip_audit_runs_successfully(): + """ + Verify that pip-audit can run successfully (even if vulnerabilities are found). + + This is a smoke test to ensure pip-audit is properly installed and functional. + """ + try: + result = subprocess.run( + [sys.executable, "-m", "pip_audit", "--version"], + capture_output=True, + text=True, + timeout=10, + ) + assert result.returncode == 0, f"pip-audit --version failed: {result.stderr}" + assert "pip-audit" in result.stdout.lower(), "pip-audit version output unexpected" + except FileNotFoundError: + pytest.fail("pip-audit not installed") + except subprocess.TimeoutExpired: + pytest.fail("pip-audit --version timed out") From 78709a9d76e5787bc0078b0b2ad3d81d19c32f7e Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Dec 2025 11:39:00 +0100 Subject: [PATCH 3/4] test: properly wrap line --- tests/test_pip_audit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_pip_audit.py b/tests/test_pip_audit.py index fca696193..29eaca607 100644 --- a/tests/test_pip_audit.py +++ b/tests/test_pip_audit.py @@ -57,7 +57,8 @@ def test_pip_audit_no_vulnerabilities(): else: # Some other error occurred pytest.fail( - f"pip-audit failed to run properly:\n\nReturn code: {result.returncode}\nOutput: {error_output}\n" + f"pip-audit failed to run properly:\n\nReturn code: {result.returncode}\n" + f"Output: {error_output}\n" ) # Success - no vulnerabilities found From 2013a2eddaeffd495ae2bc2ed30fde2a0143c1ec Mon Sep 17 00:00:00 2001 From: Matthias Date: Wed, 24 Dec 2025 12:04:30 +0100 Subject: [PATCH 4/4] chore: add recognition to the original tests author --- .github/workflows/ci.yml | 1 - tests/test_pip_audit.py | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f596da117..84b9f9afb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,6 @@ jobs: uv pip install -e ft_client/ uv pip install -e . - - name: Check for version alignment run: | python build_helpers/freqtrade_client_version_align.py diff --git a/tests/test_pip_audit.py b/tests/test_pip_audit.py index 29eaca607..ab9017b89 100644 --- a/tests/test_pip_audit.py +++ b/tests/test_pip_audit.py @@ -1,3 +1,9 @@ +""" +Run pip audit to check for known security vulnerabilities in installed packages. +Original Idea and base for this implementation by Michael Kennedy's blog: +https://mkennedy.codes/posts/python-supply-chain-security-made-easy/ +""" + import subprocess import sys from pathlib import Path