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.
Related
A non-technical, security-paranoid employee at work insists that an effective method of securing a website of ours, is to separate the application in to three parts; a front end, an API, and a backend management area for staff.
Both the API and the management system are on domain names that are just a random set of characters.
The application holds sensitive data, however, all of the applications are on the same server.
The problem I face is that debugging or adding features the application while it is in this state makes work extremely difficult, as it is unclear as to what part of the application does what. (There is no documentation and the previous developer has since left the company.)
He insists that future projects follow the same suite, with their own separate APIs and management areas, which I think will be unnecessary for a relatively simple application.
The second problem is that I know that security through obscurity is not necessarily security, and I don't see the point in using a domain that complicated to host part, or all of a website.
So my questions are this:
1) Is using an API like this going to carry any security benefits? Are there alternative ways that we can ensure the application and it's data is secure so that it does not compromise development speed.
2) Is using an obscure domain necessary to keep an application secure? Again, are there alternative methods that would be just as effective that wouldn't look as odd to future developers?
3) The management system is secured with a username and password. Would having the administration system be just as secure being on website.com/admin rather than randomcharacters.com?
Is using an API like this going to carry any security benefits? Are there alternative ways that we can ensure the application and it's data is secure so that it does not compromise development speed.
An API should be secured by an authentication mechanism such as an OAuth access token (AuthN). Who can do what on that API should then be determined by the claims in the access token (AuthZ). Authentication and Authorization should be thought of in these terms.
'I am this principal, I can prove this because I have a token that you have issued me and you can verify that only you could have issued it. I have a number of pieces of information that you can use to make decisions on what I'm allowed to do'
Is using an obscure domain necessary to keep an application secure? Again, are there alternative methods that would be just as effective that wouldn't look as odd to future developers?
No, using obscure domain names doesn't offer any level of security. They are just letters that are transformed into an IP address by a DNS entry - to use either my-website-address.com or hdsfiuycxzuyecgfr.com, you'd have to communicate that to someone and at that point they are equally secure!
The management system is secured with a username and password. Would having the administration system be just as secure being on website.com/admin rather than randomcharacters.com?
The questions to ask are, who are the users of the different parts of the system and who should have access to what? Is the front end application publicly visible on the internet and can it be used by various clients? Does the management system fall into the same category, or is that more of an internal tool? Identify the use cases for the components and consider whether you will secure them either by application logic, such as OAuth tokens, or infrastructure restrictions (e.g. only computers within a particular IP address range / subnet can access the management tool). It's usually a combination of both application and infrastructure security that provides the best level of protection.
Having the front end application and the management tool hosted as different applications may allow you to apply different security boundaries around them, which could be useful.
However, it's a matter of determining who your threat actors are and designing accordingly.
An obscure domain name just needs to leak once somewhere; as soon as any attacker gets wind of the domain name, it ceases to be obscure and does not provide any benefit whatsoever. If you have a public website which makes API calls to the "obscured" backend, then that domain name is already being well publicised.
No, there's virtually no point in using an obscure name for the sake of security. If your API is insecure and allows unauthorised access, that is your security weak point; not the fact that the domain name might be known.
Hybrid apps are obviously a bit new, so it's hard to find good information on this. I know that I need to allow cross origin resource sharing on my server side pages, but this clearly adds a security flaw. On a phonegap/cordova app, I only have client-side control with ajax calls to my server-side page. This means that anyone can access my php pages. This means that anyone can essentially mimic my app by accessing all my data like account info, etc. My question is how can I confirm that only my app is accessing these pages? Please provide specific coding examples.
I answered your question, and many others like it, in this blog post: Client authenticity is not the server's problem.
One of the most basic rules of application security is input validation. The reason this rule is so fundamental is because your server only has control (and visibility) over the software running on itself. Every other device on the Internet is a black box that you can communicate with over networking protocols. You can't see what it's doing, you only see the messages that it sends.
...
The server should remain agnostic to the client.
The software on the client and the software on the server should have a mutual distrust towards each other. Any messages that the server receives should be validated for correctness and handled with care. Data should never be mixed with code if you can help it.
...
The take-away is: Instead of trying to control your users, focus on making their misbehavior inconsequential to the stability and integrity of your server.
This question is asked here every day.
What you want to do is logically impossible. There is no solution. You cannot control the client.
I'm building an online dating website at the moment.
There needs to be an admin backend to the site to approve users/photos etc.
I can add this admin part of the site/login etc to the same domain.
eg: www.domainname.com/admin
Or from my experience with PHP CURL I can put this site on a different domain and CURL the requests through.
Question: is it more secure to put the admin code/site on a completely different domain? or it really doesn't matter if it sits on the same domain? hacking/security is the really point of this.
thx
Technically it might be more secure if you ran it from a different server and hosted it on a subdomain using a different IP/vhost, or use a proxy mod for your webserver (see Apache mod_proxy) to proxy requests from yourdomain.com/admin to admin.otherdomain.com and enforce additional IP or access control using .htaccess or equivalent to access the proxy url.
Of course, if those other domains are web accessible, then they are only as secure as the users and passwords that use them.
For corporate applications, you may want to make the admin interface accessible from a VPN connection, but I don't know if that applies to you.
If there is a vulnerability on your public webserver that allows someone to get shell access, then it may make it slightly more difficult to get administrative access since they don't have the code for the administration portion.
In other words, it can provide additional security depending on the lengths you go to, but is not necessarily a solid solution.
Using something like cURL is a possibility, but you'd have far less troubleshooting to do using a more conventional method like proxy or subdomain on another server.
I have a website where most of the traffic comes from the API (http://untiny.com/api/). I use Google Analytics to collect traffic data, however, the statistics do not include the API traffic because I couldn't include the Google Analytics javascript code into the API pages, and including it will affect the API results. (example: http://untiny.com/api/1.0/extract/?url=tinyurl.com/123).
The solution might be executing the javascript using a javascript engine. I searched stackoverflow and found javascript engines/interpreters for Java and C, but I couldn't find one for PHP except an old one "J4P5" http://j4p5.sourceforge.net/index.php
The question: is using a javascript engine will solve the problem? or is there another why to include the API traffic to Google Analytics?
A simple problem with this in general is that any data you get could be very misleading.
A lot of the time it is probably other servers making calls to your server. When this is true the location of the server in no way represents to location of the people using it, the user agent will be fake, and you can't tell how many different individuals are actually using the service. There's no referrers and if there is they're probably fake... etc. Not many stats in this case are useful at all.
Perhaps make a PHP back end that logs IP and other header information, that's really all you can do to. You'll at least be able to track total calls to the API, and where they're made from (although again, probably from servers but you can tell which servers).
I spent ages researching this and finally found an open source project that seems perfect, though totally under the radar.
http://code.google.com/p/serversidegoogleanalytics/
Will report back on results.
you would likely have to emulate all http calls on the server side with whatever programming language you are using..... This will not give you information on who is using it though, unless untiny is providing client info through some kind of header.
if you want to include it purely for statistical purposes, you could try using curl (if using php) to access the gif file if you detect untiny on the server side
http://code.google.com/apis/analytics/docs/tracking/gaTrackingTroubleshooting.html#gifParameters
You can't easily do this as the Javascript based Google Analytics script will not be run by the end user (unless of course, they are including your API output exactly on their display to the end user: which would negate the need for a fully fledged API [you could just offer an iframable code], pose possible security risks and possibly run foul of browser cross-domain javascript checks).
Your best solution would be either to use server side analytics (such as Apache or IIS's server logs with Analog, Webalizer or Awstats) or - since the most information you would be getting from an API call would be useragent, request and IP address - just log that information in a database when the API is called.
I am creating a web service using php's SoapServer built-in class. I have run some basic tests and it seems to be working fine, but now I need to limit who can use the service.
Assuming that only other scripts on the same server are trying to consume my service, and that they would do this server-side (as opposed to with AJAX or similar means), does my service have any means of identifying the owner of the requester?
I could limit access the service to only requests coming from a specific origin, but this seems either very strict or very unreliable, depending on if I allow access to any script in a directory vs. only specific scripts.
I'm just not clear if I can limit access by the user on the server since the user that the original requesting script will be www.
here are some of your options:
as vivek mentioned, a key in the url could do the trick, i have used this many times, and it works nicely, and also allows you to monitor who's consuming the service (different consumers, different keys)
you could restrict usage of the scripts by IP. this is like the nuke of restrictions, i've seen it used mostly in places where service is granted outside the original server, but where a VPN would be an overkill.
of course, you may require full authentication, but this has too much overhead, both in terms of programming, and in terms of usefulness.
however, i must ask:
if only scripts on the same server are consuming the service, why make it a service at all?
if you have (unrestricted) pages that consume this (restricted) service, what's stopping anyone from scraping those pages - no matter how hard you protect the service?
You can always implement HTTP authentication against a data source of your choice. Apache has various options for doing Digest and Basic auth against a myriad of sources (we use mod_auth_mysql to secure a php webdav solution) but PHP also has good documentation about how to do it at the app level.
http://php.net/manual/en/features.http-auth.php
Why not just make the web service available on the localhost vhost?
Not completely water-tight, admittedly but relatively simple to implement.
Or on a vhost running on a firewalled port?
C.
You could use a registration key as most famous API's do, like weather bug....
so when a request comes in, you could check the the code and see whether the user has registered to use your API.