security: add continuous fuzzing for URL and path boundaries
#105 opened on Jul 12, 2026
Repository metrics
- Stars
- (2 stars)
- PR merge metrics
- (PR metrics pending)
Description
Why
The API now has explicit URL and filesystem containment boundaries, but those parsers should be exercised with generated edge cases rather than only hand-picked examples. OpenSSF Scorecard also reports that the project has no recognized continuous-fuzzing integration.
This is an advanced help-wanted task, not a good-first-issue shortcut. One focused, reviewable integration is more useful than several tiny PRs.
Suggested first target
Start with pure or locally isolated boundaries in apps/api/app/main.py:
_local_anki_connect_url_safe_path_segment_resolve_contained_path
A useful target should explore malformed URLs, Unicode/path separators, traversal segments, encoded userinfo, unexpected ports, symlink escapes, and long inputs. It must never make an external network request or read outside a temporary fixture tree.
Done when
- Add one maintained Python fuzzing engine and a Scorecard-recognized continuous integration such as ClusterFuzzLite, with every GitHub Action pinned to a full commit SHA.
- Seed a small corpus with valid loopback URLs, invalid external URLs, safe identifiers, traversal attempts, and symlink-containment cases.
- Treat unhandled exceptions, an accepted non-loopback Anki URL, or a resolved path outside its root as failures.
- Run a short deterministic smoke budget on pull requests and a longer scheduled fuzz job without exposing secrets or uploading private inputs.
- Document the exact local reproduction command and corpus location.
- Keep existing
pytest, CodeQL, dependency audit, and public-tree checks green. - Link this issue in the PR and include the fuzz engine/version plus the seed used for any reproduced crash.
Coordination
Comment /claim before implementation so the maintainer can reserve the issue for one contributor. A proposal that uses a different recognized integration is welcome when it explains the tradeoff and keeps the initial target this small.
References: