7

We've recently started working on an API, and I'm running into a philosophy issue. This is only my second API I've worked on, but the standard I've seen for retrieving a single model is always a GET, and the endpoint is something like api/model/1, with 1 being the ID. However, my coworker is REALLY adamant about not passing any data through a URL, and wants to use POST instead and send the ID through the body. His reasoning is that he feels it's a security risk.

At the same time, he wants to follow a philosophy of one POST per file. This means we need a file for UpdateModel, DeleteModel, and EditModel.

What I'm proposing is we follow this structure:

GET    /api/Model       Get all to-do items
GET    /api/Model/{id}  Get an item by ID
POST   /api/Model       Add a new item
PUT    /api/Model/{id}  Update an existing item
DELETE /api/Model/{id}  Delete an item 

But he's proposing something like this:

GET  /api/Model Get all to-do items
POST /api/Model Get an item by ID
POST /api/Model Add a new item
POST /api/Model Update an existing item 
POST /api/Model Delete an item 

Is there anything to my coworkers philosophy that I'm not understanding?

3 Answers3

4

Using POST and putting the actual request details in the body “works”. At least nothing will break. Except HTTP caching. But at that point you're inventing your own RPC mechanism that uses HTTP as a transport protocol, and are not building a REST API that makes use of HTTP. This is a fundamental design choice, but both can be valid. E.g. GraphQL uses precisely this POST /some-endpoint mechanism.

In a RESTful API, the URI/URL should identify the resource. If model items are a distinct resource in the context of your application, a RESTful design would give each such item a separate URL. However, it could also be that the collection of items as a whole is the finest granularity that is reasonable for your application.

Whether putting data into an URL is a security risk depends on your threat model. There are two good reasons to keep sensitive data out of URLs:

  • as a defence against shoulder-surfing
  • to keep sensitive data out of log files

There can also be XSRF considerations, but requiring POST requests and serving appropriate CSP headers is a better response.

For all other purposes, the path or query parts are exactly as safe as the body of a POST request. E.g. if your backend has an Insecure Direct Object Reference vulnerability, this is just as exploitable through a POST body as it is through an URL component – just slightly more cumbersome for an unmotivated attacker.

amon
  • 135,795
2

I agree with other answers here, however I would also want to question the reasoning behind your coworkers opinion.

Using POST body over a path param won't really add any meaningful security as such. If someone can snoop on path param, he can definitely do the same with request body.

Moreover path params don't really have any sensitive data, which is true in your case too.

sasmit
  • 21
1

Both solutions are identical. The only change is your mapping of the html protocol to your server side code.

As such you could easily implement both mappings with the same code and architecture.

The security risk from having the id in the path is not a direct one, its encoded like the rest of the data, but the path is often logged. As such including data in it is not a great idea.

I would also note that presumably the object you are sending in edit and update requests includes its own id as a property. So adding it to the path is uneeded.

Get requests with query params or paths are easy to use in a browser without a client. For this reason I would prefer them for simple queries.

But I would use the query parameter, not the path. This will make your logging eaiser. You wont have to parse the data out to find the method etc.

Ewan
  • 83,178