How to confirm that the request was made through the website securely

Asked

Viewed 1,065 times

3

Good would like to know if there is any way for me to confirm that the request really came from the site and not from outside, and is also being made by the page with the user action.

I tried to work something out, but it didn’t work out. That was to create a session with single token every time q page is started and be sent through ajax to another page, but the token arrives different. Question: Session does not work as expected in Ajax and PHP request

Then I wonder if there is a way to check if the data sent is actually made by the page and how I can do it/apply it in PHP, Javascript or jQuery

2 answers

3

Hello,

It is not possible to create a system that guarantees 100% that the request was made from a page of your site, because technically no request is made "from your site" while the user is browsing, because all requests are made by the browser (browser)That is, by the client. And everything that comes from the customer can be manipulated.

The only way would be if the request was literally made by the server, i.e., you make a request using ex. Direct PHP URL to a url of your application, but I understand that this escapes the purpose of your inquiry.

Conclusion: It is not possible to have 100% guarantee of origin of a HTTP request from a client that is not controlled by you or by its own application.

Here is a diagram illustrating: inserir a descrição da imagem aqui

2

There are two points to consider, one of them has solution:

  • I want to prevent another website send request to my website:

    A website (malicioso.com) is making requisitions to seusite.com, taking advantage of the sessions initiated by the user on his site.

  • I want to prevent you from sending requests to my site while out of it.

    A software that is not a browser (for example: curl) is making requisitions for the seusite.com, typically in an automatic and non-human manner.


The first case is a site that executes on the client side such a request, for example:

malicioso.com:
 <img src="http://seusite.com/deletar_conta.php">

When you access the page you will call your page. This could be done with AJAX or any other method, provided it runs on the client side, in the browser of the user accessing the malicioso.com.

Solutions:

Easy and applicable in general use, with low impact for the user:

  • Add the header of X-Frame-Options for DENY

    This will prevent another site from making a iframe of your website.

  • Add CSRF-Token (using a CSPRNG) to all forms.

    The malicious site will not have access to CSRF-Token unless there is another vulnerability, such as XSS.

  • Add to flag of SameSite for strict session cookie (not natively supported by PHP, but can do this manually):

    The request made for your website will not have cookies, but this is still an experimental feature and not supported in all browsers.

Moderate, low impact for user:

  • Send a public key (RSA case) or common key (HMAC or AES-GCM case) to the user and use it to make calls via AJAX.

    The key will be in the body of the page or in the localStorage and will be used to sign/encrypt the information, the malicious site will not have access to this information, unless there is another vulnerability.

Difficult and high impact for the user:

  • Do not use cookies as sessions or recite sessions.

    You can use for example the websocket, once started the connection no other with the same identifier can be opened. Another option is to use some key derivation, so when the user logs in both parties can recognize the generated key user. Both cases any new request made by the malicious site will not be able to enjoy an already open session.


The second case is to prevent you from sending requests outside my site, prevent them from being able to automate actions, or using software such as Curl to make requests on my site, for example:

curl -X "POST" -d "CSRF=12345678&CONTA=12345678" -H "Cookie: sessao=ui1j3dasqwe123;" -H "Referer: seusite.com" https://seusite.com/deletar_conta.php

I want to make sure that the user moved the mouse to the button and clicked there, inside my site.

Solutions:

  • There’s no way

"Pseudo-Soluções":

This will not fix the issue, requests can still be made outside your site!

  • Add Captcha to avoid non-human requisitions.

    This will increase the cost so that you can send the request outside the website, a bot you will not be able to make this request easily, but it is still possible.

    Normally the user will have to write in text the message displayed in image, this can be inconvenient to the user, but if he is more sure that the user is actually legit, after all was able to write the correct text.

  • Add a Pow (e.g. hashcash) to avoid automations.

    This is based on bitcoin. The user must calculate a hash and this will cost computational power, increasing the cost for new requests to be made.

  • Não recicle sessões; This means that I must create a new session for each user request even if they haven’t closed the tab/logged in?

  • @Guilherme.oc97 Yes. You can use websocket for this, if the connection is automatically cut the session is closed. Or, you can use the sessionStorage browser, which is "zeroed" every time it opens in a new tab or refreshes the page, for example, which only exists on that page. This is very different from cookies, which have the same value "forever".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.