making database available to other servers - php

OK,
I'm not entirely clear how to ask this question, so please feel free to edit it.
Here's the idea.
I have a database that I think may be useful to webmasters.
I would like to offer, as a paid service, the inclusion of some interface with the database.
I want my database to dynamically populate drop-down option menus.
I understand how to do it when the database, requesting html/javascript and the processing php are all on the same server.
I'm not so sure whether this can be done if the requesting html html/javascript are on the webmaster's server, and the processing phps and the database are on my server.
I'm also not sure how to make sure that only authorized users can hook up to my database.
At this point, I am looking for a macro-level solution, not the code implementation.
Thanks!

Instead of directly connecting to remote database server, I suggest you to create a simple web service (such as a PHP page grabbing information from database, based on the request stated in query string you specified ) to generate XML / JSON for your web page.
Your web page, containing your drop down box, can make an AJAX request to fetch the XML & parse for data. With this mechanism, security problem caused by exposing the database can be avoided.

My approach to this would be to write a web service (whether SOAP, XMLRPC or REST) that requires the users to submit an API key with each request. The service would validate the key, talk to the database, and return results to the user in some standard format. The API key would (obviously) be unique for each user/subscription.

You could return the results of the request to the php script in JSONP format (json with padding). That allows the javascript to execute a callback method on the original webpage even though the service is on another domain.
You'd probably need some way of tracking state in your php code to determine if they're authenticated. One way would be to have the author of the 3rd-party webpage send an authentication token during their body onload to your php script. You could then mark the IP address of the client as "authenticated" and then all other requests from that same IP would return a valid result. Requests from a non-authenticated IP could return an error message.
IPs are obviously not unique in our world of NAT (network address translation). If you want it to be more fool-proof, you could generate your own token inside the PHP & send it back from the request to authenticate. The 3rd-party site would store that token in memory (or a cookie) & send it back to you on every request. You'd use that token as the proof of authentication on future requests, rather than the IP. This is basically how most servers do Sessions, PHP probably has something built in for that.

Related

How would I go about preventing hotlinking of a PHP web service script that runs a query on a MySQL database and outputs it in JSON form?

Introduction and background
I have a MySQL database of Lottery Results which my Android application queries to get the results via a PHP web service script which connects to the database, does a query for the top 10 and returns JSON data for the Android client to parse and then display.
I have the server hosted and it uses Cpannel (cannot find the version number).
In terms of the Android app (java program) The full URLs of php script are stored in a String. I fear if the program got decompiled they could get access to this string. I am using pro-guard to obfuscate the code but this does not hide actual values given to Strings or variables.
The actual Problem
How would I prevent others (if they got the actual URL of the PHP script location) to prevent them from leaching the results I provide just by running the script (this would cost me bandwidth usage). I tested it and I could actually get the JSON data output if I input the full URL of the script.
What I have done so far
Im new to this server hosting and administration. So far I disabled indexing on the directory which contains the PHP scripts just in case someone found them that way.
I was looking into setting permissions for the script file but ended up actually blocking legitimate use of it. At the moment they are 644. I cannot remember which ones I tried.
I found various hotlinking tutorials but these seem to be for images and multimedia but not specifically a script which outputs JSON data. Please help me.
What I am looking for
I don't have any code to show but I am looking for advice for those who have been through the same problem and point me into a direction to which I can research, investigate and build a solution from.
Thank your for your time in reading
A quick but not super secure solution would be to generate an unique token for every request:
Given:
Secret Key: examplekey1234
Client:
Calculates Token: sha256(examplekey + requestdata + date + ip ....)
Does request with token as additional request data
Server:
Calculates token the same way as the client.
Compares calculated with submitted token.
If both are equal, accept the request.
Since the secret key is known only to the client and the server, nobody ellse can calculate the token.
The data added to the calculation (requestdate, ip, date) ensures, that the token can't be reused for other requests (different reqest data, other user, at a later time, etc.).
If you have some kind of session id, you could also add it to your token calculation. This makes the token a little bit more secure, since it's only usable for this session.
But: When somebody decompiles your application, he can obtain the secret key. This method mainly protects against sniffing the network traffic to get the url.

Protecting API - JS Frontend and PHP Backend

Iam searching for an good implementation to protect my Backend written in PHP.
Scenario:
Server 1 (www.domain.com)
Servers only JS/HTML to the Client
Server 2 (www.domain2.com)
Is Running an PHP Server wich is responding to Server 1 with JSON Data (rendered by an Javascript Template engine on Sevrer1).
How can i stop others to grab the JSON Response from Server1?
I know i can add somekind of API key but it is stored in JS (everyone can read it), i know i could check if the request is from Server 1 IP, but it is not a big deal to fake such a request.
Making internal calls from Server1 to Server2 is a solution, not exposing Server1 to the internet, and adding it to a private network might help.
Even if someone works around a way out, you could add validations like making sure that the request origin is from the authorized source (in your case Server2).
If the request origin is from another source, simply return without processing.
If you're still paranoid about it, you can always keep adding more mechanisms like hash-based message authentication code
One thing you can do is to create a session cookie on the server 1 and simultaneously store that session value in the database on server 2. Whenever someone makes a request from server 1 you append the request with the cookie value and send it to server 2 while making API calls. The server 2 serves back the JSON only when the incoming session ID matches with the one stored in the database.
This is not foolproof. Someone can hack the cookies, you will need to clear up the session once the users log out.
The other way, as you mentioned, is using a server side scripting language on server 1.
Why not just create some short-life tokens and share them only server-side, then embed in JS code?
Source

Securing JSONP?

I have a script that uses JSONP to make cross domain ajax calls. This works great but my question is, is there a way to prevent other sites from accessing and getting data from these URL's? I basically would like to make a list of sites that are allowed and only return data if they are in the list. I am using PHP and figure I might be able to use "HTTP_REFERER" but have read that some browsers will not send this info.... ??? Any ideas?
Thanks!
There really is no effective solution. If your JSON is accessible through the browser, then it is equally accessible to other sites. To the web server a request originating from a browser or another server are virtually indistinguishable aside from the headers. Like ILMV commented, referrers (and other headers) can be falsified. They are after all, self-reported.
Security is never perfect. A sufficiently determined person can overcome any security measures in place, but the goal of security is to create a high enough deterrent that laypeople and or most people would be dissuaded from putting the time and resources necessary to compromise the security.
With that thought in mind, you can create a barrier of entry high enough that other sites would probably not bother making requests with the barriers of entry put into place. You can generate single use tokens that are required to grab the json data. Once a token is used to grab the json data, the token is then subsequently invalidated. In order to retrieve a token, the web page must be requested with a token embedded within the page in javascript that is then put into the ajax call for the json data. Combine this with time-expiring tokens, and sufficient obfuscation in the javascript and you've created a high enough barrier.
Just remember, this isn't impossible to circumvent. Another website could extract the token out of the javascript, and or intercept the ajax call and hijack the data at multiple points.
Do you have access to the servers/sites that you would like to give access to the JSONP?
What you could do, although not ideal is to add a record to a db of the IP on the page load that is allowed to view the JSONP, then on the jsonp load, check if that record exists. Perhaps have an expiry on the record if appropriate.
e.g.
http://mysite.com/some_page/ - user loads page, add their IP to the database of allowed users
http://anothersite.com/anotherpage - as above, add to database
load JSONP, check the IP exists in the database.
After one hour delete the record from the db, so another page load would be required for example
Although this could quite easily be worked around if the scraper (or other sites) managed to work out what method you are using to allow users to view the JSONP, they'd only have to hit the page first.
How about using a cookie that holds a token used with every jsonp request?
Depending on the setup you can also use a variable if you don't want to use cookies.
Working with importScript form the Web Worker is quite the same as jsonp.
Make a double check like theAlexPoon said. Main-script to web worker, web worker to sever and back with security query. If the web worker answer to the main script without to be asked or with the wrong token, its better to forward your website to the nirvana. If the server is asked with the wrong token don't answer. Cookies will not be send with an importScript request, because document is not available at web worker level. Always send security relevant cookies with a post request.
But there are still a lot of risks. The man in the middle knows how.
I'm certain you can do this with htaccess -
Ensure your headers are sending "HTTP_REFERER" - I don't know any browser that wont send it if you tell it to. (if you're still worried, fall back gracefully)
Then use htaccess to allow/deny access from the right referer.
# deny all except those indicated here
order deny,allow
deny from all
allow from .*domain\.com.*

database security with php page that spits out XML

I just created a PHP page that spits outs some data from my database in an XML format. This data is fetched from a flex application I made.
I had spent a long time formatting my tables and database information and do not want anyone to be able to simply type www.mysite.com/page_that_spits_out_XML.php and steal my data. However, at the same time I need to be able to access this page from my flex application.
Is there a way I can prevent other people from doing this? Thank you!
Are you using Flex's HTTPService object?
A few general ideas...
Create a Session or Cookie authentication scheme on your web service
Add some type of API key that Flex passes to your XML web service, which would provide a basic safeguard (though it can easily be detected and doesn't provide much in terms of security as it's visible in the postdata).
Use something like HTTP basic authentication: http://geekzguru.wordpress.com/2008/07/04/howto-add-basic-authentication-header-to-httpservice/
You need to set up an authentication. The Flex application sends HTTP POST data (typically a username and a password) to the server where your PHP application checks whether the account exists and if it does, it sets up a session. Whenever accessing a file (such as the page_that_outputs_xml.php), the PHP file will check whether the account in the session has a permission to view this data.
That would be as bulletproof as today's most login systems.
The only thing that is really going to slow down a datathief is encryption, make sure that your flex app is obfuscated and that the key and the encryption function stored within is neither guessable nor easily extractable.
This is the best you can do, but it's not a type of solution I would generally recommend. If someone REALLY want that data they are going to get it.
Get your flex app to send a secret key (hash or something) and then get your PHP to check if who is accessing it has a correct key. Might want to use a POST request to hide what you are sending. This isn't super secure but that's my two cents!

How do I restrict JSON access?

I have a web application that pulls data from my newly created JSON API.
My static HTML pages dynamically calls the JSON API via JavaScript from the static HTML page.
How do I restrict access to my JSON API so that only I (my website) can call from it?
In case it helps, my API is something like: http://example.com/json/?var1=x&var2=y&var3=z... which generates the appropriate JSON based on the query.
I'm using PHP to generate my JSON results ... can restricting access to the JSON API be as simple as checking the $_SERVER['HTTP_REFERER'] to ensure that the API is only being called from my domain and not a remote user?
I think you might be misunderstanding the part where the JSON request is initiated from the user's browser rather than from your own server. The static HTML page is delivered to the user's browser, then it turns around and executes the Javascript code on the page. This code opens a new connection back to your server to obtain the JSON data. From your PHP script's point of view, the JSON request comes from somewhere in the outside world.
Given the above mechanism, there isn't much you can do to prevent anybody from calling the JSON API outside the context of your HTML page.
The usual method for restricting access to your domain is prepend the content with something that runs infinitely.
For example:
while(1);{"json": "here"} // google uses this method
for (;;);{"json": "here"} // facebook uses this method
So when you fetch this via XMLHttpRequest or any other method that is restricted solely to your domain, you know that you need to parse out the infinite loop. But if it is fetched via script node:
<script src="http://some.server/secret_api?..."></script>
It will fail because the script will never get beyond the first statement.
In my opinion, you can't restrict the access, only make it harder. It's a bit like access-restriction by obscurity. Referrers can be easily forged, and even with the short-lived key a script can get the responses by constantly refreshing the key.
So, what can we do?
Identify the weakness here:
http://www.example.com/json/getUserInfo.php?id=443
The attacker now can easily request all user info from 1 to 1.000.000 in a loop. The weak point of auto_increment IDs is their linearity and that they're easy to guess.
Solution: use non-numeric unique identifiers for your data.
http://www.example.com/json/getUserInfo.php?userid=XijjP4ow
You can't loop over those. True, you can still parse the HTML pages for keys for all kinds of keys, but this type of attack is different (and more easily avoidable) problem.
Downside: of course you can't use this method to restrict queries that aren't key-dependent, e.g. search.
Any solution here is going to be imperfect if your static pages that use the API need to be on the public Internet. Since you need to be able to have the client's browser send the request and have it be honored, it's possibly for just about anyone to see exactly how you are forming that URL.
You can have the app behind your API check the http referrer, but that is easy to fake if somebody wants to.
If it's not a requirement for the pages to be static, you could try something where you have a short-lived "key" generated by the API and included in the HTML response of the first page which gets passed along as a parameter back to the API. This would add overhead to your API though as you would have to have the server on that end maintain a list of "keys" that are valid, how long they are valid for, etc.
So, you can take some steps which won't cost a lot but aren't hard to get around if someone really wants to, or you can spend more time to make it a tiny bit harder, but there is no perfect way to do this if your API has to be publically-accessible.
The short answer is: anyone who can access the pages of your website will also be able to access your API.
You can attempt to make using your API more difficult by encrypting it in various ways, but since you'll have to include JavaScript code for decrypting the output of your API, you're just going to be setting yourself up for an arms race with anyone who decides they want to use your API through other means. Even if you use short-lived keys, a determined "attacker" could always just scrape your HTML (along with the current key) just before using the API.
If all you want to do is prevent other websites from using your API on their web pages then you could use Referrer headers but keep in mind that not all browsers send Referrers (and some proxies strip them too!). This means you'd want to allow all requests missing a referrer, and this would only give you partial protection. Also, Referrers can be easily forged, so if some other website really wants to use your API they can always just spoof a browser and access your API from their servers.
Are you, or can you use a cookie based authentication? My experience is based on ASP.NET forms authentication, but the same approach should be viable with PHP with a little code.
The basic idea is, when the user authenticates through the web app, a cookie that has an encrypted value is returned to the client browser. The json api would then use that cookie to validate the identity of the caller.
This approach obviously requires the use of cookies, so that may or may not be a problem for you.
Sorry, maybe I'm wrong but... can it be made using HTTPS?
You can (?) have your API accessible via https://example.com/json/?var1=x&var2=y, thus only authenticated consumer can get your data...
Sorry, there's no DRM on the web :-)
You can not treat HTML as a trusted client. It's a plain text script interpreted on other people's computers as they see fit. Whatever you allow your "own" JavaScript code do you allow anyone. You can't even define how long it's "yours" with Greasemonkey and Firebug in the wild.
You must duplicate all access control and business logic restrictions in the server as if none of it were present in your JavaScript client.
Include the service in your SSO, restrict the URLs each user has access to, design the service keeping wget as the client in mind, not your well behaved JavaScript code.

Categories