From 0a39f559d9baa22eb21d11c3ec69b2c31242ff34 Mon Sep 17 00:00:00 2001 From: Ivan Pinatti Date: Thu, 5 Mar 2026 16:38:05 -0500 Subject: [PATCH 1/5] Add security scanning CI (CodeQL, pip-audit, Dependabot) Adds three free security layers for the public repo: - CodeQL SAST for Python logic bugs and unsafe API usage - pip-audit dependency scan against OSV database for CVEs - Dependabot for automated dependency and Actions version updates Closes: https://github.com/AlfredoSequeida/hints/issues/91 --- .github/dependabot.yml | 10 ++++++++ .github/workflows/security.yml | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/security.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..645c171 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..09ab53e --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,44 @@ +name: Security Scanning + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 6 * * 1' # Weekly on Mondays + workflow_dispatch: + +jobs: + codeql: + name: CodeQL Analysis + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - uses: actions/checkout@v4 + - uses: github/codeql-action/init@v3 + with: + languages: python + - uses: github/codeql-action/analyze@v3 + + pip-audit: + name: Dependency Vulnerability Scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Install system dependencies + run: | + sudo apt-get update -qq + sudo apt-get install -y libgirepository1.0-dev libcairo2-dev pkg-config \ + python3-dev libdbus-1-dev gir1.2-gtk-4.0 + - name: Install project + run: pip install -e . + - uses: pypa/gh-action-pip-audit@v1.1.0 + with: + local: true From ea388c3cc7837a4b0997382f73736888068b2609 Mon Sep 17 00:00:00 2001 From: Ivan Pinatti Date: Thu, 5 Mar 2026 16:41:06 -0500 Subject: [PATCH 2/5] Use CodeQL Action v4 (v3 deprecated Dec 2026) --- .github/workflows/security.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 09ab53e..c9e8bb0 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -19,10 +19,10 @@ jobs: security-events: write steps: - uses: actions/checkout@v4 - - uses: github/codeql-action/init@v3 + - uses: github/codeql-action/init@v4 with: languages: python - - uses: github/codeql-action/analyze@v3 + - uses: github/codeql-action/analyze@v4 pip-audit: name: Dependency Vulnerability Scan From 2a2474048fdc78c4f6389edf3699f980db81da85 Mon Sep 17 00:00:00 2001 From: Ivan Pinatti Date: Thu, 5 Mar 2026 16:47:34 -0500 Subject: [PATCH 3/5] Add bandit pre-commit hook for local security scanning Adds bandit (SAST) as a pre-commit hook for catching security issues in Python code locally before push. Runs only on staged files by default. Existing findings in the codebase (shell=True, pickle.loads, /tmp socket path) are pre-existing and for the maintainer to review separately. pip-audit is intentionally CI-only: installing this project requires system libs (libgirepository, Cairo) unavailable in pre-commit's isolated environment. --- .pre-commit-config.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7839263 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: + - repo: https://github.com/PyCQA/bandit + rev: 1.9.4 + hooks: + - id: bandit + name: bandit (security linter) + args: ["-r", "-ll"] + # -r recursive, -ll report medium+ severity + # pip-audit is intentionally omitted: installing this project + # requires system libs (libgirepository, Cairo) unavailable in + # pre-commit's isolated environment. It runs in CI instead. From d61edab7482785e296f5f98a96eb464abca5b233 Mon Sep 17 00:00:00 2001 From: Ivan Pinatti Date: Thu, 5 Mar 2026 17:05:29 -0500 Subject: [PATCH 4/5] Add pip-audit pre-commit hook and requirements.txt Adds local dependency vulnerability scanning via pip-audit alongside the existing bandit SAST hook. requirements.txt mirrors setup.py install_requires and is used by pip-audit with --no-deps to avoid dependency resolution. PyGObject is excluded from requirements.txt: it requires gobject-introspection system headers to build metadata, which are not universally available locally. It is fully covered by pip-audit in CI where system libs are installed. Transitive dependency CVEs are also covered by CI. --- .pre-commit-config.yaml | 19 ++++++++++++++++--- requirements.txt | 12 ++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 requirements.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7839263..e9b8091 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,19 @@ repos: name: bandit (security linter) args: ["-r", "-ll"] # -r recursive, -ll report medium+ severity - # pip-audit is intentionally omitted: installing this project - # requires system libs (libgirepository, Cairo) unavailable in - # pre-commit's isolated environment. It runs in CI instead. + + - repo: local + hooks: + - id: pip-audit + name: pip-audit (dependency scan) + language: system + entry: pip-audit + args: ["-r", "requirements.txt", "--no-deps"] + pass_filenames: false + # language: system uses the system Python, giving pip access to system + # libs (libgirepository, Cairo) needed to build PyGObject metadata. + # --no-deps checks only direct dependencies from requirements.txt + # (which mirrors install_requires in setup.py), not transitive deps. + # Transitive dependency CVEs are caught by pip-audit in CI where the + # full project is installed in a clean runner with system libs present. + # Requires pip-audit in the active environment: pip install pip-audit diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9700f3a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,12 @@ +# Runtime dependencies — mirrors install_requires in setup.py. +# Kept in sync manually; used by pip-audit for local dependency scanning. +# +# PyGObject is intentionally excluded: it requires gobject-introspection system +# headers to build metadata, which are not universally available. It is covered +# by pip-audit in CI where system libs are installed explicitly. +pillow +pyscreenshot +opencv-python +evdev +dbus-python +rich From 16d573342f53c097d5f294440bfcadf77af34712 Mon Sep 17 00:00:00 2001 From: Ivan Pinatti Date: Thu, 5 Mar 2026 17:14:32 -0500 Subject: [PATCH 5/5] Expand Contributing section with pre-commit setup instructions --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index eb59335..0cd9330 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,42 @@ pip install -e . At this point, hints should be installed locally in the virtual environment, you can run `hints` in your shell to launch it. Any edits you make to the source code will automatically update the installation. For future development work, you can simply re-enable the virtual environment (step 2). +## Pre-commit validation + +hints uses [pre-commit](https://pre-commit.com) to run security checks locally before each commit: + +- **bandit** — static analysis (SAST) for Python security issues, runs on staged files. +- **pip-audit** — dependency vulnerability scan against the [OSV database](https://osv.dev), runs against `requirements.txt`. + +### Setup + +4. Install pre-commit: + +``` +pip install pre-commit +``` + +5. Install pip-audit: + +``` +pip install pip-audit +``` + +6. Install the git hooks: + +``` +pre-commit install +``` + +The hooks will now run automatically on every `git commit`. You can also run them manually at any time: + +``` +pre-commit run --all-files +``` + +> [!NOTE] +> `PyGObject` is excluded from `requirements.txt` used by pip-audit because it requires `gobject-introspection` system headers to build package metadata, which are not universally available. It is covered by pip-audit in CI. + ## Development tips - If you are making updates that impact hints, you will most likely need to test displaying hints and might find yourself executing hints but not being quick enough to switch to a window to see hints. To get around this, you can execute `hints` with a short pause in your shell: `sleep 0.5; hints`. This way you can have time to switch to a window and see any errors / logs in your shell.