Skip to content

Security: Harden Juror Authorization & Fix Validation Bypass (#370)#443

Open
ayushshukla1807 wants to merge 1 commit intohatnote:masterfrom
ayushshukla1807:gsoc-2026-juror-access-security
Open

Security: Harden Juror Authorization & Fix Validation Bypass (#370)#443
ayushshukla1807 wants to merge 1 commit intohatnote:masterfrom
ayushshukla1807:gsoc-2026-juror-access-security

Conversation

@ayushshukla1807
Copy link
Copy Markdown

@ayushshukla1807 ayushshukla1807 commented Mar 29, 2026

GSoC 2026 Blueprint — Phase 1 Security: Harden Juror Authorization

Status: Active architecture blueprint, cited in my GSoC 2026 proposal (Phase 1, Security Hardening). Fixes Issue #370.

Problem

During the pre-application audit, I identified a class of authorization bypass vulnerabilities in the Montage API. The CoordinatorDAO methods trust that callers have already verified the user's role — but several API endpoints do not enforce this check before invoking DAO methods.

Specific attack vector:

  1. An authenticated juror (valid session cookie) crafts a direct POST /admin/round/{id}/finalize request
  2. The endpoint does not verify the user is a coordinator — it only checks they have a valid session
  3. The finalize_round DAO method executes, closing the round prematurely

This is a privilege escalation vulnerability: any active juror can terminate a round they are supposed to be voting in.

Proposed Fix Architecture

sequenceDiagram
    participant Juror as Juror (malicious)
    participant EP as POST /finalize_round
    participant RoleCheck as @require_coordinator
    participant DAO as CoordinatorDAO

    Juror->>EP: POST /admin/round/42/finalize
    EP->>RoleCheck: check session user role
    Note over RoleCheck: User is juror, not coordinator
    RoleCheck-->>Juror: 403 Forbidden
    Note over DAO: Never reached

    participant Coord as Coordinator (legitimate)
    Coord->>EP: POST /admin/round/42/finalize
    EP->>RoleCheck: check session user role
    Note over RoleCheck: User is coordinator ✓
    RoleCheck->>DAO: finalize_round(round_id)
    DAO-->>Coord: 200 OK
Loading

Implementation: @require_coordinator Decorator

def require_coordinator(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        user = get_current_user()
        campaign_id = kwargs.get('campaign_id') or request.json.get('campaign_id')
        if not is_coordinator(user, campaign_id):
            raise MontageError('permission_denied',
                               'Coordinator role required for this action')
        return f(*args, **kwargs)
    return decorated

Affected Endpoints (Audit Results)

Endpoint Current After Fix
POST /admin/round/finalize Session check only + @require_coordinator
POST /admin/round/advance Session check only + @require_coordinator
POST /admin/campaign/edit Session check only + @require_coordinator
DELETE /admin/juror/remove Session check only + @require_coordinator

@ayushshukla1807
Copy link
Copy Markdown
Author

I am closing this PR to reduce repository noise. The core fixes relevant to my GSoC Proposal are being manually consolidated into PR #454 and PR #415 to make it substantially easier for the maintainers to review my code. The larger concepts discussed here will be implemented incrementally and manually if my proposal is accepted.

@ayushshukla1807
Copy link
Copy Markdown
Author

I have stripped the AI formatting from the description and reopened this PR so I can manually improve its code over the coming days, fulfilling my promise.

@ayushshukla1807
Copy link
Copy Markdown
Author

Closing this conceptual proposal. Consolidating my Open Source footprint to prioritize high-value, locally verified bug fixes for the current review window.

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.

1 participant