Skip to content

Proposal creation should not allow caller-controlled ids #2041

@Ceyvion

Description

@Ceyvion

Bug

POST /api/proposals lets a caller override the server-generated proposal id. apps/api/src/services/proposalService.js creates the proposal object with id first, then spreads the caller payload afterward:

const proposal = { id: `prp_${Date.now()}`, ...payload };

Because the payload is applied after the generated id, a request body can replace the server-owned proposal id.

Reproduction payload:

{
  "id": "prp_attacker",
  "jobId": "job_1",
  "freelancerId": "usr_1",
  "coverLetter": "Hello"
}

Observed behavior from current origin/main:

HTTP 201
{ "success": true, "data": { "id": "prp_attacker", "jobId": "job_1", "freelancerId": "usr_1", "coverLetter": "Hello" } }

Impact

  • Public proposal creation can choose a server-owned identifier.
  • Callers can create confusing or colliding proposal ids.
  • Downstream workflow that trusts proposal ids can be associated with client-controlled identifiers.

Expected behavior

The server should always own the generated proposal id. Caller-supplied id values should not override the generated prp_... value, while normal proposal payload fields should still be preserved.

Proposed fix

  • Apply caller payload fields before server-owned fields in proposal creation.
  • Add endpoint regression coverage proving caller-supplied id is ignored.
  • Keep the change scoped to proposal creation behavior.

This issue is limited only to the creator of this issue. This means that only the issue author can attempt to solve this issue. If you would like to work on it, please create another issue with the same contents and refer to issue #743 for more information.

Parent bounty: #743.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions