Skip to content

fix: require auth token for PDF download endpoint (#1428) - #1487

Open
monanksojitra wants to merge 1 commit into
idurar:devfrom
monanksojitra:issues/fix-unauthenticated-pdf-download
Open

fix: require auth token for PDF download endpoint (#1428)#1487
monanksojitra wants to merge 1 commit into
idurar:devfrom
monanksojitra:issues/fix-unauthenticated-pdf-download

Conversation

@monanksojitra

Copy link
Copy Markdown

The /download route was mounted without the isValidAuthToken middleware, allowing anyone to download any invoice, quote or payment PDF by guessing or enumerating record ids (#1428).

  • mount adminAuth.isValidAuthToken on the /download route
  • add request.download() which fetches the PDF via axios with the Authorization header and saves it as a blob, since window.open cannot send auth headers
  • switch all four download call sites to request.download()

Description

The /download route was mounted without the isValidAuthToken middleware, allowing anyone to download any invoice, quote or payment PDF without logging in, just by guessing or enumerating record ids.

Changes:

  • Backend: mount adminAuth.isValidAuthToken on the /download route in backend/src/app.js — the same middleware already protecting the /api routes (one line).
  • Frontend: window.open() cannot send an Authorization header, so the backend fix alone would break the download buttons. Added request.download() in frontend/src/request/request.js, which fetches the PDF via axios with the auth token (responseType: 'blob') and saves it, following the existing includeToken() / errorHandler pattern. Switched all four download call sites (ERP panel DataTable and ReadItem, Payment ReadItem, Dashboard RecentTable) to use it.

Note: complementary to #1484 / #1476 / #1473, which fix the password-update IDOR from the same issue but do not touch the download route.

Related Issues

Fixes the unauthenticated PDF download part of #1428.

Steps to Test

  1. Run the backend and log in to get a token.
  2. Without any token, request:
    GET http://localhost:8888/download/invoice/invoice-<id>.pdf
    401 Unauthorized (before this fix: returned the PDF).
  3. Repeat with a valid Authorization: Bearer <token> header
    200, valid PDF with correct Content-Type: application/pdf and attachment filename.
  4. In the UI, click Download PDF on an invoice/quote/payment list or detail page → the PDF downloads as before.

Screenshots (if applicable)

N/A — no visual changes; download buttons behave the same for logged-in users.

Checklist

  • I have tested these changes
  • I have updated the relevant documentation
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the codebase
  • My changes generate no new warnings or errors
  • The title of my pull request is clear and descriptive

Two boxes stay unchecked honestly: no documentation exists for this route (nothing to update), and the code needed no comments — it follows existing patterns. Checking boxes that don't apply looks worse than leaving them.

The /download route was mounted without the isValidAuthToken middleware,
allowing anyone to download any invoice, quote or payment PDF by guessing
or enumerating record ids (idurar#1428).

- mount adminAuth.isValidAuthToken on the /download route
- add request.download() which fetches the PDF via axios with the
  Authorization header and saves it as a blob, since window.open cannot
  send auth headers
- switch all four download call sites to request.download()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants