Skip to content

fix: add session ownership check before deleteCase and copyCase (#48)#50

Merged
SeaCelo merged 2 commits intoEAPD-DRB:sec-case-guardfrom
tejassinghbhati:feature/48-session-ownership-check-delete-copy
Feb 27, 2026
Merged

fix: add session ownership check before deleteCase and copyCase (#48)#50
SeaCelo merged 2 commits intoEAPD-DRB:sec-case-guardfrom
tejassinghbhati:feature/48-session-ownership-check-delete-copy

Conversation

@tejassinghbhati
Copy link
Copy Markdown
Contributor

Summary

/deleteCase and /copyCase previously performed destructive filesystem operations (shutil.rmtree, shutil.copytree) using a case name taken directly from user-supplied JSON, with no verification that the requesting client owned that case. The session was only checked after deletion to decide which status code to return — not before to guard the operation.

This PR adds an ownership guard to both routes before any filesystem action is taken.


Changes

API/Routes/Case/CaseRoute.py

Both /deleteCase and /copyCase now:

  • Check that an active session exists — return 403 if none
  • Verify that the requested casename matches session['osycase'] — return 403 if not
# Added at the top of both routes, before any filesystem call
active_case = session.get('osycase')
if not active_case:
    return jsonify({'message': 'No active session.', 'status_code': 'error'}), 403

if case != active_case:
    return jsonify({'message': 'Unauthorised: case does not match active session.', 'status_code': 'error'}), 403

Additionally, deleteCase is simplified — the redundant if/else checking session after deletion is replaced with a single session['osycase'] = None, since ownership is now guaranteed by the guard above.


Verification

Manually verified the guard logic:

BLOCKED: Ownership mismatch -> 403 Unauthorised   ← mismatched casename rejected
ALLOWED: model_A matches session -> delete proceeds ← authorised request passes

Authorised requests behave identically to before — no regression in normal usage.

Screenshot 2026-02-25 125839

Related

Closes #48

@SeaCelo
Copy link
Copy Markdown
Collaborator

SeaCelo commented Feb 26, 2026

Thanks for this PR, @tejassinghbhati.

I want to integrate #50 and #55 together on a branch sec-case-guard so we keep both:

Please retarget this PR to sec-case-guard. I’d like this PR to merge first, but it needs to edits to avoid a conflict.

Behavior to keep from this PR:

  • copyCase and deleteCase require active session case match.
  • mismatch or no active session returns 403 with clear JSON message.

@tejassinghbhati tejassinghbhati changed the base branch from main to sec-case-guard February 27, 2026 04:12
@tejassinghbhati tejassinghbhati force-pushed the feature/48-session-ownership-check-delete-copy branch from 9e6071f to 9be3d8a Compare February 27, 2026 04:14
@tejassinghbhati
Copy link
Copy Markdown
Contributor Author

Hi @SeaCelo, done — I've retargeted this PR to sec-case-guard and rebased cleanly on top of it. No conflicts.

On the 403 behaviour you flagged: both routes return distinct JSON messages — "No active session." when there's no osycase in session, and "Unauthorised: case does not match active session." on a mismatch — so the frontend can distinguish between the two cases. Let me know if you'd prefer a different message format or a single unified 403 body.

Ready for review whenever you are — happy to adjust anything before #55 lands on top.

@tejassinghbhati
Copy link
Copy Markdown
Contributor Author

tejassinghbhati commented Feb 27, 2026

Also raised #75 — /setSession can bypass the ownership guards we added here.

SeaCelo added a commit that referenced this pull request Feb 27, 2026
Merging into `sec-case-guard` as the first of three PRs in the security integration sequence:

1. **#76** (this PR) — validate `/setSession` so session can only hold existing case names
2. **#50** — ownership guards on `/deleteCase` and `/copyCase` (depends on trusted session from #76)
3. **#55** — graceful handling of missing case directories (resilience layer)

### Minor cleanup needed post-merge

The `from pathlib import Path` import inside `setSession()` is redundant — `Path` is already imported at line 2 of `app.py`. I'll remove it in a follow-up commit on `sec-case-guard`.
@SeaCelo SeaCelo merged commit 82ee0da into EAPD-DRB:sec-case-guard Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] /deleteCase and /copyCase perform destructive filesystem operations without validating session ownership

2 participants