Skip to content

Unauthenticated writes on PUT /post/:id/views and PUT /publish/:id (orm/express) #8560

Description

@zyx77550

In orm/express/src/index.ts, both write endpoints take :id straight from the URL and mutate the Post row with no authentication or ownership check:

app.put('/post/:id/views', async (req, res) => {
  const { id } = req.params
  const post = await prisma.post.update({
    where: { id: Number(id) },
    data: { viewCount: { increment: 1 } },
  })
  // ...
})

app.put('/publish/:id', async (req, res) => {
  const { id } = req.params
  // ...
  const post = await prisma.post.update({
    where: { id: Number(id) },
    data: { published: !postData?.published },
  })
})

Anyone who can reach the API can inflate the view count or toggle published on any post by guessing an integer id — there's no caller-identity check anywhere on either path.

I get that this is an intentionally minimal teaching example and auth is out of scope for the "getting started" story — not filing this as a "this repo is broken," more as a heads-up: this example is widely copied into real projects, and this specific gap (writes gated by nothing but a URL param) is one people tend to carry over verbatim. A one-line comment near these two handlers (// no auth check here — add one before shipping this to production) or a short note in the README might be enough to save someone a bad day.

Happy to send a small PR adding that comment / a minimal isOwner stub if useful — let me know which you'd prefer.

(Found while running an automated behavior-proof tool — SPARDA — against a corpus of public Express repos; happy to share the full report if useful.)

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