Skip to content

Markdown preview endpoint accepts unbounded unauthenticated input #1005

Open

Description

@HEKPYTO

Summary

POST /api/render compiles Markdown that the caller sends, using the site's own MDX pipeline (src/lib/renderMarkdown.ts -> next-mdx-remote). It accepts any string, with no login and no size limit.

The compile is CPU bound and runs inside the request, so the size of the request decides how long the server spends on it, and the answer is much larger than the document that was sent.

The route sits in the application router, so every deployment of this commit serves it, and anyone can reach it without a session. One request with a large document is enough to keep the server busy for a long time and to make the other pages wait.

What we measured

All numbers come from a local deployment of the current main commit. The hosted site was not contacted.

  • A 256 KB document of inline maths: 200 after 48 s, and 196 MB of compiled output.
  • While that request was running, a request to / came back 500 after 61 s.
  • Bigger documents take longer, and the answer grows with the document.

How to reproduce

node -e 'const m="$x^2+y=z$ ";process.stdout.write(JSON.stringify({content:m.repeat(25600)}))' > payload.json

time curl -s -o /dev/null -w '%{http_code} %{size_download} bytes\n' \
  -X POST http://127.0.0.1:3000/api/render \
  -H 'content-type: application/json' --data-binary @payload.json

curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' http://127.0.0.1:3000/

Where it lives

  • src/app/api/render/route.ts - the endpoint
  • src/app/render/page.tsx - the only page that calls it
  • src/lib/renderMarkdown.ts - the shared compile helper, also used for task statements, solutions and assessment instructions

Suggested fix

Nothing in the site uses the preview: no page, test, script or workflow links to /render, and the endpoint has no other caller. A pull request that deletes both files is open (#1004); it leaves the statements, the solutions and the assessment instructions untouched, because those go through src/lib/renderMarkdown.ts.

Until that is merged, deleting the two files is the whole fix. If the preview is wanted back, it can be restored from e983e1c and used as a local tool, outside the deployed app.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions