I am currently investigating a mobile app API.

There is a feature which fills in a form in the app automatically. The user supplies a string which contains all the compressed form data. And then the app displays the filled in form for the user to enter some additional mandatory data, and submit.

It does all of that with two requests:

  • A POST request to POST /compressedformdata.php, which submits the data in the request message body. The server responds with status 200 OK.
  • A GET request to GET /filledoutform.php, which responds with the HTML page content (representation), with the pre-filled form in the response message body.

Apart from that, there is only the session information (cookie), and literally nothing else in both requests, to identify the resource.

The client and the user expect the GET request to return the exact data/representation that was created with the first request.

But I found that I can just repeat the first POST request with different data, and found that the GET /filledoutform.php endpoint will return whatever was posted in this same session, with the POST request.

How insecure is it, to not specify the exact representation to be requested in this scenario?

It would be critical, when the second request returns the wrong html form. Since this whole functionality relies on it.

In a web API, this design would be catastrophic. Since the POST request could be inadvertently repeated with outdated data, when the user refreshes an old tab he'd left open with this page, for example. Or due to the risk of CSRF.

I am trying to figure out whether or not this design is safe in a mobile app API.

Normally, you would (for example) return a "201 Created" HTTP status code as response to the first POST request. And redirect to the new resource, e.g. using the Location header field. Or otherwise reference the new resource.

Is it bad that the API doesn't specify the resource, but instead just accepts anything that was previously created with POST /compressedformdata.php?

  • For any further discussion, please do it in chat. – Rory Alsop Jun 18 at 12:57

This is much ado about nothing. Idempotency as you are defining it is a matter of HTTP semantics, not a security concern. You should be concerned if

  1. the GET request is not safe (e.g., GET results in changes on the server), or
  2. a lack of idempotency allows false information to be displayed.

As you described it, however, it sounds like the data on the server is only being changed in the POST request.

The second part seems to be avoided by the design. There is no expectation by the programmers that "GET filledoutform.php" will return a specific form (that is to say, it does not return form 9999). If it were always supposed to return form 9999, then the fact that the data changes would be bad. But that's not something this application expects.

| improve this answer | |
  • Thank you for your answer. I just like to point out that this is a mobile API, as described in the first sentence of my original question, not a web application. – Martin Fürholz Jun 16 at 6:19
  • @MartinFürholz Ah, I missed that. However, I think that this reasoning still stands because HTTP is HTTP whether it's used in a web app or mobile app. – Fire Quacker Jun 16 at 13:10
  • The thing is that the client absolutely expects that specific representation in the response. Therefore it would be much safer to return it directly with the response to the first POST request. – Martin Fürholz Jun 17 at 16:32

Using of ID in the request can have advantages and disadvantages.

Advantage: It is easier to understand what logic the URL triggers.

Disadvantage: It is more error prone and thus may be less secure.

If a request contains both user ID (in the URL) and session ID (in a cookie), then user is actually identifiable via 2 ways. The backend can determine user based on the session ID, because session should be associated with some user. Also backend can determine the user based on the ID in the URL. What should backend do, if these are two different users?

Actually, backend should first check if the user ID in the URL means the same as user associated with session ID. If they are different, backend should reject such request. If such check is forgotten, this will be a security problem: After logging in a user can put to URL a user ID of some other user and thus read data of another user.

If backend checks user ID in the URL and user associated with the session, then we have redundancy. Redundancy is not good, because it may be not clear, what should be used in particular case: One developer will use user ID from URL, the other will use the user associated with session ID.

That's why avoiding user ID in URL can be an advantage and can be more secure in cases when user requests his/her own data.

We should distinguish this from cases when particular users (e.g. administrators) do need to access the data of other users. In such cases session ID is associated with administrator and the ID of the target user is really needed as a part of URL. In such cases there can be 2 similar services - one that provides user own data for the current user and one service for admins. This may look as overhead, but actually it may be more secure. It is up to the architect who decides about particular system.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.