How to protect my JSON application?

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 them , what could I do?

I thought of generating an access token to validate the request on the server, but this would invalidate the cache of the page (something I want to keep), not to use sessions because they are in different domains, it would be possible to at least block the direct access to 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 api url, even though the individual may not be able to make requests, he can still open the page and copy the generated data.     

asked by anonymous 19.04.2017 / 14:03

2 answers

2

Summary: There's no way, not that I'm pessimistic, but there's really no way.

CSRF protection:

If you are worried about someone reading the content, there are two "different" situations:

  • Get your /json.json on the client side, via Javascript / Ajax.
  • Get your /json.json on the "server" / "client" side via cURL / Wget / Webviewer (and "custom browsers").
  • The first situation is easier and indeed "there is something to be done" to prevent:

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

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

    I recommend viewing this answer.

  • Add a CSRF Token .
    • The CSRF Token should only be valid for a single session.
    • (Recommended) CSRF Token should be valid for a single IP.
    • (Optional) CSRF Token should expire after a single use.
    • (Optional) CSRF Token should be unique for each URL or for each follow up.
  • You can read this answer , to agree to disagree and do not recommend using generateRandomString() because it is a LCG .

    Not efficient but can help:

    The second situation is impossible to fix, literally, there is no way to prevent this, all listed above is not enough to prevent the use of cURL / Wget.

  • Creating a Referrer , a limit on how many times the page can be accessed per second per IP (or IPv6 band) is relatively efficient as it will require the use of multiple proxies if you want to get content constantly, but remember CGNAT in IPv4 .

  • Block access via TOR and public proxies.

  • Much less efficient but can help:

  • Create a "challenge" in Javascript, such as Origin , CloudFlare uses this .
  • There may be other security issues, other than CSRF, such as MiTM , #,

    19.04.2017 / 16:02
    0

    You can try Basic Access Authentication .

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

    Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
    

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

    In time, this comment always comes up: I know that Base64 does not give any security. Security is in the HTTPS protocol. Base64 is intended to follow the pattern of this type of authentication.

        
    19.04.2017 / 16:26