How do I protect my JSON application?

Asked

Viewed 996 times

6

I created a unique subdomain to provide data from my tables in JSON, it facilitates requests for both the mobile version and the desktop version of my site, but I would like to protect such data or at least make it difficult to access it, what I could do?

I’ve thought about generating an access token to validate the request on the server, but this would invalidate the page cache (something I want to keep), not to use Sesssions because they are in different domains, it would be possible to at least block direct access through the URL?

I’m also testing the method below, but I’m not sure it’s safe

$origem = $_SERVER['HTTP_ORIGIN'];

if ($origem == "http://www.dominio.com" || $origem == "http://m.dominio.com")
{  
    header("Access-Control-Allow-Origin: $origem");
}

I do not believe that this way is safe because the data is still accessible through the direct url of the api, even if the individual may not be able to make requests he can still open the page and copy the generated data.

  • Did some testing using the header Access-Control-Allow-Origin. ?

  • I added an example of what I’m using to such @Maurivan

  • You’re right, the URL will be accessible. $_SERVER['REMOTE_HOST'] ou $_SERVER['REMOTE_ADDR'] since only 2 hosts will have access.

2 answers

2

Summary: There’s no way, not that I’m pessimistic, but in fact there’s no way.


CSRF protection:

If you’re worried about someone reading the content, there are two "distinct":

  1. Get your /json.json on the client side, via Javascript/Ajax.
  2. Get your /json.json on the "server"/"client" side, via Curl/Wget/Webviewer (and "custom browsers").

The first situation is easier and in fact "there is something to do" to prevent:

  1. Add the header of Access-Control-Allow-Origin, strict to your website.
    • (Optional) Add the Access-Control-Allow-Headers, limit headers (eg. X-CRSF-TOKEN) that can be sent.
    • (Optional) Add the Access-Control-Allow-Methods, limit the accepted methods (ex. GET) so only this method will be accepted.

So you can use:

header('Access-Control-Allow-Origin: http://www.dominio.com http://m.dominio.com');
header('Access-Control-Allow-Methods: GET');

I recommend seeing this answer.

  1. Add a CSRF Token.
    • CSRF Token must be valid only for a single session.
    • (Recommended) The CSRF Token must be valid for a single IP.
    • (Optional) The CSRF Token should expose after a single use.
    • (Optional) The CSRF Token must be unique for each URL or each tracking.

You can read this answer, think of decompressing and not recommend the use of generateRandomString() for being a LCG.

Measures that are inefficient but can help:

  1. Check the Referrer/Origin, are easily forged.

The second situation is impossible to be fixed, literally there is no way to prevent this, everything listed above is not enough to prevent the use of Curl/Wget.

  1. Create a Rate-Limit, a limit on how many times the page can be accessed per second per IP (or Ipv6 range) is relatively efficient as it will require the use of multiple proxies if you want to obtain content constantly, but remember the CGNAT in Ipv4.

  2. Block access via TOR and public proxies.

Much less efficient measures, but they can help:

  1. Create a "challenge" in Javascript, such as jjencode, Cloudflare uses this.

There may be other security problems, which is not the CSRF, for example the Mitm, XSS, Of (including the json_decode, standard, is vulnerable by hash-dos) and among other problems like Side-Channel Attacks, but these are other things that have no relation to the question...

0

You can try basic access authentication.

Serve JSON only over HTTPS. Hence you use the header Authorization to pass credentials, coded with Base64. Here is an example of what the header would look like, taken directly from the wiki:

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

On the server you extract the header credentials and authenticate the request. This way only authenticated users will have access to JSON.

In time, because this comment always comes up: I know that Base64 does not provide any security. Security is in the HTTPS protocol. Base64 serves to follow the default for this type of authentication.

Browser other questions tagged

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