Allowing GET requests only from specified server IP - php

I want to update records in a database through an api.php. I do this by sending GET requests to the API on the server from another particular server.
I tried limiting CORS to only that specific server, but GET requests were still accepted from the browser. I also tried to set a condition to match the server's IP with the one specified in the API and abort if it's false. However, I fear that this is an imprudent move as I am not that experienced in these types of situations.
Can I safely limit the api to allow GET requests only from this specific server address?
System architecture
Webserver: Nginx
App language: php(5.3), javascript, html, css
Database: Mysql

An solution would be to use JSON Web Tokens.
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
You can find the PHP framework to generate/check the tokens at https://github.com/web-token/jwt-framework

Related

Most secure way to communicate with my database?

I'm making a game in Unity which makes use of a remote MySQL database, hosted on a web server. Although it's entirely possible to communicate with a database directly from Unity/C#, I'm also aware of how easy it is to reverse engineer the app in order to find any hard-coded authentication information (such as URLs, passwords, etc)... So, because the server is a web server and not a VPS, that means that all database connections and modifications would need to be done via server-side scripting.
But the client app would still need to make requests to the web server, where some PHP scripts would handle the requests and perform the appropriate actions. So using a url with a php query string still revisits the original hacking issue, and even using HTTP GET/POST requests can easily be packet-sniffed without any decompilation of the game.
So unless I'm missing something, does the most secure way to do this involve a mixture of direct HTTP GET/POST requests, where the data is somehow encrypted/obfuscated? Maybe via HTTPS instead of HTTP? Or is there an even better way to do this?
Expose a RESTful API over HTTPS

Load balancing (Distribution) with PHP and many servers

I am developing an app which has many users and (hopefully) will have many more in the future and therefore I want to get rid of my current one-server-makes-it-all solution to a many server structure. My app has customers in different countries and I want to handle each country with an own server. You can see this in the picture above. The app only knows the URL of the distribution server and I want to achieve, that the distribution server redirects to the right server.
How can I technically do this? I am using PHP / MySQL and my app is talking to my server with simple HTTP requests (GET and maybe later also POST) like
http://distributionServer.com/script.php?appCountry=us&work=getListOfItems
Server Sends back JSON data.
I have some technical questions:
how to make the redirect in PHP with all the parameters? The Servers that will finally handle the user need these params. Can I just make a simple redirect with "header()" ?
When I make redirect with header() does the communication still runs then over the distribution server? Because I don't want that all the "return" traffic is going over the distribution server, this server only needs to say "ok USA-App you talk to server USA". When server USA sends back data it should not go the way: ServerUSA -> Distribution Server -> App. Because these Server do not share a LAN, just somewhere in the net.
I know I could just hardcode the server URLs in the app so that US user always connect directly to USA Server but I need some flexibility to add new servers / change servers / change URLs / add new countries.. and I don't want to always update the app when something changed on the server side.
This is simplest way you can do this : https://support.rackspace.com/how-to/simple-load-balancing-with-apache/

Secure requests between different apps

Assume there are two different apps on appengine- one powered by Go and another by PHP
They each need to be able to make specific requests to eachother, purely over the backend network (i.e. these are the only services that need to make these specific requests- other remote requests should be blocked).
What is the best-practices way of doing this? Off the top of my head, here are 3 possible solutions and why I am a bit worried about them
1) Do not keep them as separate apps, but rather modules
The problem with this is that using modules introduces some other annoyances- such as difficulties with Channel Presence reporting. Also, conceptually, these 2 requests are really the only places they touch and it will be clearer to see what's going on in terms of database usage etc. if they are separated. But the presence issue is more of a show-stopper
2) Append the request with some hardcoded long secret key and only allow response if via SSL
It seems a bit strange to rely on this, since the key would never change... theoretically the only way it could be known is if an administrator on the account or someone with the source revealed it... but I don't know, just seems strange
3) Only allow via certain IP ranges (maybe combined with #2)
This just seems iffy, can the IP ranges be definitively known?
4) Pub/Sub
So it seems AppEngine allows a pub/sub mechanism- but that doesn't really fit my use case since I want to get the response right away - not via a postback once the subscriber processes it
All of them
-- As a side point, assuming it is some sort of https request, is this done using the Socket API for each language?
HTTPS is of course an excellent idea in general (not just for communication between two GAE apps).
But, for the specific use case, I would recommend relying on the X-Appengine-Inbound-Appid request header: App Engine's infrastructure ensures that this cannot be set on requests not coming from GAE apps, and, for requests that do come from GAE apps (via a url-fetch that doesn't follow redirects), the header is set to the app-id.
This is documented for Go at https://cloud.google.com/appengine/docs/go/urlfetch/ , for PHP at https://cloud.google.com/appengine/docs/php/urlfetch/ (and it's just the same for Java and Python, by the way).
purely over the backend network
Only allow via certain IP ranges
These requirement are difficult to impossible to fulfill with app engine infrastructure because you're not in control of the physical network routes. From the app engine FAQ:
App Engine does not currently provide a way to map static IP addresses to an application. In order to optimize the network path between an end user and an App Engine application, end users on different ISPs or geographic locations might use different IP addresses to access the same App Engine application.
Therefore always assume your communication happens over the open network and never assume anything about IPs.
Append the request with some hardcoded long secret key
The hard coded long secret does not provide any added security, only obscurity.
only allow response if via SSL
This is a better idea; encrypt all of your internal traffic with a strong algorithm. For example, ECDHE-RSA or ECDHE-ECDSA if available.

How should multiple server-side apps "communicate" with each other

Lets say there are two server-side applications on two separate servers.
Server #1, IP address 1.2.3.4, contains a PHP web application with MySQL database.
Server #2, IP address 5.6.7.8, contains a NodeJS app with MongoDB database.
How can the PHP app "commands" the NodeJS app (or vice versa) to do something, like :
"please save this data on your database", or
"I want to retrieve data from your database, where some_id = 123"
These internal communication should be secure, it means that no one except both servers can execute them.
I think that this is possible with simple HTTP POST / GET requests.
For example, the NodeJS app sends a POST request with parameters to http://1.2.3.4/do_something.php
Or maybe the PHP app sends GET request to http://5.6.7.8/retrieveSomething
But I think it is not secure because the URL is exposed to public. (correct me if I'm wrong)
I don't even know the google search keyword for this problem.
Is it web services? SOA? RPC?
Your example is perfectly fine. In terms of securing it, a simple way would be to have the "client/sender" send some sort of agreed upon API key along with the request. The "server/receiver" would then check this API key. If it is valid, then the appropriate command would be executed. If it's not, the server will simply return a 404 Not Found.

How to use https and how things differ

How would you use https ?, would sending information via GET and POST be any different while using https ?
Any information and examples on how https is used in php for something simple like a secure login would be useful,
Thank you!
It will be no different for your php scripts, the encryption and decryption is done transparently on another layer.
Both GET and POST get encrypted, but GET will leave a trace in the web server log files.
HTTPS is handled at the SSL/TLS Layer, not at the Application Layer (HTTP). Your server will handle it as aularon was saying.
SSL and/or HTTPS is used to provide some level of confidentiality for data in transit between the web users and the web server. It can also be used to provide a level of confidence that the site the users are communicating with is in fact the one they intend to be.
In order to use SSL, you'll need to configure these capabilities on the server itself, which would include either purchasing (an authority-signed) or creating (a self-signed) certificate. If you create your own self-signed certificate, the level of confidence that the site is the intended one is significantly reduced for your users.
PHP
Once your webserver is able to serve SSL-protected pages, PHP will continue to operate as usual. Things to look out for are port numbers (normal HTTP is usually on port 80, while HTTPS traffic is usually on port 443), if your code relies on them.
GET & POST Data
Pierre 303 is correct, GET data may end up in the logs, and POST data will not, but this is no different than a non-SSL web server. SSL is meant to protect data in transit, it does nothing to protect you and your customers from web servers and their administrators that you may not trust.
Secure Login
There is also a performance hit (normally) when using SSL, so, some sites will configure their pages to only use https when the user is sending sensitive information, for example, their password or credit card details, etc. Other traffic would continue to use the normal, http server.
If this is the sort of thing you'd like to do, you'll want to ensure that your login form in HTML uses a ACTION that points to the https server's pages. Once the server accepts this form submission, it can send a redirect to send the user back to the page they requested using just http again.
Just ensure you're sending the correct headings when allowing files to be downloaded over ssl... IE can be a bit quirky. http://support.microsoft.com/kb/323308 for details of how to resolve

Categories