fix: critical security hardening (Phase A permissions audit)
- Remove role field from UserCreate schema, hardcode 'engineer' at registration
- Escape all user content in HTML export with html.escape() (XSS fix)
- Add field_validator to reject default SECRET_KEY when DEBUG=False
- Add CHECK constraint on users.role ('engineer'|'viewer') + migration 011
- Fix test_admin fixture to properly grant is_super_admin via ORM
- Fix circular FK (users↔invite_codes) in test DB setup with DROP SCHEMA CASCADE
- Add 5 new security tests (role validation + XSS prevention)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
14
CLAUDE.md
14
CLAUDE.md
@@ -105,6 +105,12 @@ When adding new frontend pages or components, use "ResolutionFlow" for any user-
|
||||
- Frontend hook: `frontend/src/hooks/usePermissions.ts`
|
||||
- Viewers CAN: browse trees, start sessions, rate steps
|
||||
- Viewers CANNOT: create/edit trees, steps, tags, categories
|
||||
- **Security Hardening (Phase A):**
|
||||
- Registration role field removed from `UserCreate` — hardcoded to `engineer`
|
||||
- HTML export XSS fix — all user content escaped via `html.escape()`
|
||||
- Secret key validator — rejects default key when `DEBUG=False`
|
||||
- Role CHECK constraint on `users` table (migration 011)
|
||||
- `test_admin` fixture fixed to properly grant `is_super_admin=True`
|
||||
- **Session Scratchpad (Floating Overlay):**
|
||||
- Fixed-position overlay panel (420px wide, 55vh tall) on right edge
|
||||
- Floating button when collapsed, slide-in panel when expanded
|
||||
@@ -329,7 +335,7 @@ docker exec -it patherly_postgres psql -U postgres -c "CREATE DATABASE patherly_
|
||||
pip install -r requirements-dev.txt
|
||||
|
||||
# Run tests
|
||||
pytest
|
||||
pytest --override-ini="addopts="
|
||||
```
|
||||
|
||||
### Frontend Operations
|
||||
@@ -513,6 +519,10 @@ When using `allow_origin_regex` for wildcard patterns, also include `allow_origi
|
||||
- Frontend: use `usePermissions()` hook for all role/permission checks
|
||||
- `TreeListItem` includes `team_id` for frontend permission checks (`author_id` and `team_id` are nullable)
|
||||
|
||||
### SQLAlchemy Test Fixtures: Circular FK Handling
|
||||
|
||||
The `users ↔ invite_codes` tables have circular foreign keys. `Base.metadata.drop_all()` fails with `CircularDependencyError`. The test fixture uses `DROP SCHEMA public CASCADE` instead (split into two `sa.text()` calls — asyncpg rejects multi-statement strings).
|
||||
|
||||
### Alembic Migrations: Test Data State Before Writing WHERE Clauses
|
||||
|
||||
Migration 010 had `WHERE role = 'admin'` but the only user already had `role = 'engineer'` (changed by earlier work), so the UPDATE matched zero rows. Always verify actual data values before writing conditional migrations, or use broader conditions.
|
||||
@@ -753,7 +763,7 @@ Position overlay at `right-2` (not `right-0`) so it sits inside the page scrollb
|
||||
|
||||
- Commit message format: `type: description`
|
||||
- Types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`
|
||||
- Always include `Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>`
|
||||
- Always include `Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>`
|
||||
- Always create a feature branch BEFORE committing new work (not retroactively after committing to main)
|
||||
- PR workflow: `git checkout -b feat/feature-name` → commit → `git push -u origin feat/feature-name` → `gh pr create`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user