Monero Integration, CSRF: enforce coverage test + CI gate; Monero docs/hardening updates
Summary
- Completes CSRF protection audit.
- Adds a focused CSRF coverage test and integrates it into CI as a gate.
- Updates docs (Testing, Security, README) with CSRF policy and Monero hardening guidance.
- No runtime breaking changes or DB migrations.
Changes
-
Makefile
- Added
test-csrftarget to run only tests/test_csrf_coverage.py withPYTEST_DISABLE_PLUGIN_AUTOLOAD=1for stable output.
- Added
-
CI
-
.gitlab-ci.yml: New
csrf-auditjob to runmake test-csrfon each commit/MR.
-
.gitlab-ci.yml: New
-
Tests
-
tests/test_csrf_coverage.py:
- Ensures all POST views declare
require_csrf=True. - Ensures all local POST forms include
{% include "snippets/csrf.j2" %}. - Skips external POSTs:
- absolute URLs (
http/https) - signed upload forms (
action="{{ signed_post["url"] }}")
- absolute URLs (
- Ensures all POST views declare
-
tests/test_csrf_coverage.py:
-
Templates
- make_post_sell/templates/update-card.j2
-
make_post_sell/templates/snippets/stripe.j2
- Standardized CSRF includes to double quotes so the test recognizes them.
-
Documentation
-
docs/testing.md: Added “CSRF Coverage Test Only” section (
make test-csrf). - docs/security.md: Finalized CSRF coverage status, template policy (skip CSRF for external POSTs), and CI verification. Expanded Monero hardening guidance.
- README.rst: Added CSRF coverage test snippet in “Running Tests”.
-
docs/testing.md: Added “CSRF Coverage Test Only” section (
CSRF Audit Details
- All state-changing POST routes use
require_csrf=True. - All local POST forms include
{% include "snippets/csrf.j2" %}. - External POSTs (e.g., signed S3/Spaces uploads) are excluded from CSRF and test coverage.
Examples (selected):
-
Views:
-
make_post_sell/views/authentication.py:
- Split GET/POST for
join-or-log-in,verification-challenge, addedrequire_csrf=Trueon POST.
- Split GET/POST for
-
make_post_sell/views/coupon.py:
- Split coupon_new into GET/POST, added
require_csrf=Trueon POST.
- Split coupon_new into GET/POST, added
- Verified comment.py, cart.py POST routes have
require_csrf=True.
-
make_post_sell/views/authentication.py:
-
Templates (selected):
-
cart.j2, coupon_new.j2, join-or-log-in.j2, markup_editor.j2, user_settings.j2, user_addresses.j2, shop_settings.j2, shop_users.j2, shop_new.j2, shop_location_form.j2, product_new.j2, product_edit.j2,
comments/*, verification-challenge.j2. - Signed external upload forms (e.g., in product_edit.j2, shop_settings.j2) are intentionally excluded from CSRF and test coverage.
-
cart.j2, coupon_new.j2, join-or-log-in.j2, markup_editor.j2, user_settings.j2, user_addresses.j2, shop_settings.j2, shop_users.j2, shop_new.j2, shop_location_form.j2, product_new.j2, product_edit.j2,
Monero: Documentation & Hardening Notes
-
- Monero hardening checklist:
- RPC bound to localhost, strong auth, no public exposure.
- Disable mock mode in production; keep mock JSON non-public.
- Price oracle: HTTPS, enforce timeouts/retries and sanity bounds.
- Minimal PII in logs; avoid leaking addresses/PII.
- Watcher idempotence and confirmation thresholds.
- Notes on watcher behavior and inventory finalization parity with Stripe.
- Monero hardening checklist:
-
- Monero test targets remain (
make test-monero), with CSRF test added.
- Monero test targets remain (
Testing
-
Local CSRF coverage test:
-
make test-csrf→ 2 passed (CSRF views + template coverage).
-
-
Full test suite:
-
make test(set Stripe test keys per README if needed).
-
CI
- Adds
csrf-auditjob to theteststage that runsmake test-csrfto prevent regressions. - Pip-audit job retained as before.
Backwards Compatibility
- No runtime behavior changes except added CSRF enforcement on POST (expected security hardening).
- No config changes or DB migrations.
Risks & Mitigations
- Risk: Missing CSRF in a new POST endpoint or template could regress.
- Mitigation: CI gate (
csrf-audit) fails if coverage is incomplete.
- Mitigation: CI gate (
- Risk: False positive for external POSTs.
- Mitigation: Test explicitly skips actions to absolute URLs and
signed_post["url"].
- Mitigation: Test explicitly skips actions to absolute URLs and
Follow-ups (Optional)
- Add a CI badge or README note for CSRF coverage gate.
- Extend tests to assert specific critical routes/forms if desired.
- Consider adding price oracle timeouts/retries and bounds in
views/crypto.py.
How To Verify
- Locally:
-
make test-csrfshould pass.
-
- In CI:
- Ensure
csrf-auditjob passes in the MR pipeline.
- Ensure