Finding EC2 instance ID for someone else's instance - amazon-web-services

I use a public AMI from a third party which runs an nginx web server, and it uses the EC2 instance ID for the default admin password. I'm trying to think of any vulnerabilities with this, if I do not change the default password. Since the HTTPS server is public, is there any way someone could discover the EC2 instance ID?
I know this can be seen by anyone in my company who has ec2:DescribeInstances permission, but I'm not really concerned about that. I just want to make sure no one outside can find it.

Off the top of my head and without considering any crazy specific scenarios, I do not believe it is possible for one to retrieve this information without exploiting some sort of 0-day vulnerability we presently don't know about.
Now let's stop living in a perfect world and begin to threat model about what could potentially happen.
Depending on the functionality you have going on and some other variables, I don't think it is crazy to think the instance ID could be leaked in some manner. Let's say you exposed a web application and you had some functionality which took user input and did not validate this input, then I could see the instance ID potentially being capable of being leaked.
For all intensive purposes, let's say our host is hosting a web application which analyzes users' LinkedIn profiles and offers them career advice. In addition, let's assume that the web application poorly accepts input and does not validate that a spoofed URL has been provided instead of a LinkedIn URL, and it will provide the response details after it has made a request to the URL provided by the attacker.
Considering all these, if I was an attacker trying to get the instance ID of your host, I would navigate to the part of the web application which accepts my input and I would provide the following input, and considering the scenarios I posed above, an attacker could potentially get the desired information:
http://169.254.169.254/latest/meta-data/instance-id
How I came up with that payload was I looked at:
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html#instance-metadata-ex-1
I believe that if all these prerequisites were met, then this would potentially leak the instance ID.
But until all these scenarios exist, it is not likely. I have seen some web applications which allow you to add an integration to your website poorly validate input given by the user. As such, one can exploit a server side request vulnerability to attack the host.
I hope this is a good explanation of how it could potentially happen, but again, I don't think it is likely.

Related

Remembering users of websockets

Good Afternoon,
I am hoping someone might be able to help me with a concept. I have a websocket server which pushes JSON messages out to users, I have coded in a number of admin functions for pushing broadcasts out to users, as well as disconnecting users if needed.
One of the things I would like to be able to do though is to come up with a 'near' foolproof way of 'banning' users from connecting to the server if required. This is where I am a bit lost, if I go the cookie route then it is possible that the cookies get cleared and it no longer works, I can't use the session ID either as once they disconnect they get a new session ID, and the IP address is also problematic as many would be on mobile dynamic connection.
Id appreciate any tips on how to best achieve a way of remembering the users so if I ban them, when they go to reconnect I can prevent them.
The server I am running is the supersocketserver whilst the client is HTML5.
Given your current constraints, there is no "foolproof" way to ban a person from accessing your web site.
For privacy reasons, there is no permanent way to identify a given browser. There are cookies, there are IP addresses, there are even some evil "perma-cookies" that attempt to store little pieces of identifying information in lots of places (such as flash cookies and other plug-in data) to try to make it difficult (but not impossible) for users to clear them. As you're already aware, IP addresses are not permanent and are not always tied to just one user either.
And, of course a user can certainly just use a different browser or computer or mobile device.
So, the usual way to control access is to require a user to create an account in your system before they can use your service. Then, if you want to ban a user, you ban that account. Since you will want to prevent the user from just creating a new account, you can collect other identifying information upon account registration. The more info you require and can verify, the harder it is for users to create more and more accounts. This gets to be quite a bit of work if you really want to make it difficult for users to create more accounts because you need to require pieces of identifying information that you can both verify and are hard for a rogue user to duplicate (credit cards, email addresses, home addresses, etc...). How far you go here and how much effort you put in is up to you on how much you want to keep a banned user out.

How to (programmatically or by other means) encrypt or protect customer data

I am working on a web project and I want to (as far as possible) handle user data in a way that reduces damage to the users privacy in case of someone compromising our servers/databases.
Of course we only have user dat'a that is needed for the website to do it's job but because of the nature of the project we have quite a bit of information on our users (part of the functionality is to apply yourself to jobs and sending your cv with it)
We thought about encrypting/decrypting sensitive data with a private/public keypair of which the private key is encrypted with the users password but found some security and implementation problems with that :P
the question is how do you implement user privacy and a protection against data theft on centralised web sever with browser compatible protocols while for functionality it is required that users can exchange sensible data?
To give some additional insight: this project is not yet in production stage so there is still time to make things right.
we are already doing some basic stuff like
serving https
enforcing https for sites that may handle sensitive data
hashing salted passwords
some hardening of our server and services on it
encrypted harddrives to prevent someone from reading all client information after stealing our servers / harddrives
but that's about it, there is besides the password hashes no mechanism that would stop/at least make it harder for someone who managed to get into (part of) the server to gain all data on all our users. Nor do we see a way to encrypt user data to disable our self from reading them as we need the data (we wouldn't have collected it otherwise) for some part of the website / the functionality we want it to provide. Even if we for example managed somehow (maybe with some javascript) that all data would get to us encrypted (by the client's browser) and we serve the client his privatekey encrypted with some passphrase (like for example his login password) we could not for examle scan user uploaded files for viruses and the like. On the other hand would a client side encryption at least with the browser/webserver concept leave some issues with security at least as we imagine it (you are welcome to prove me wrong) and seems quite like reinventing the wheel, and maybe as this project is not primarily about privacy, but rather privacy is a prefarable property we might not want to reinvent the wheel for it. I strongly believe I am not the first webdeveloper thinking about this, am I? So what have other projects done? What have you done to try to protect your users data?
if relevant we are using django and postrgreSQL for most things and javascript for some UI
The common way to deal with this issue is to split (partition) your data.
Keep minimal data on the Internet-facing web server and pass any sensitive data as quickly as possible to another server that is kept inside a second firewall. Often, data is pulled from the web server by the internal secure server to further increase security. This is how banks and finance houses handle sensitive data from the internet (or at least they should). There is even a set of standards (PCI) that cover the secure handling of credit card transactions that explain all of this in mind-numbing detail.
To further secure the internal server, you can put it on a separate network and secure physical access to it. You can also focus other security tools on it such as Data Loss Protection and Intrusion Protection.
In addition, if you have any data that you don't need to see in the clear, use a client-side encryption library to encrypt it locally. There are still risks of course since the users workstation might be compromised by malware but it still removes risks during data transmission and from server storage risks. It also puts responsibility onto the user rather than just on to your central servers.
You already seem to be a long way ahead of most web developers in ensuring that your customers are kept safe and secure. One other small change it would be worth considering would be to turn on enforced HTTPS for all transactions with your site. That way, there is very little chance of unexpected data leakage such as data being unexpectedly cached.
UPDATE:
Client side encryption can help a lot since it puts the encryption responsibility on the user. Check out LastPass for example. Without doing the encryption client-side, you could never trust the service. Similarly with backup services where you set your key locally so that the backups can never be unlocked by someone on the server - they never have the key.
Partitioning is one of the primary methods for enterprises to secure services that have Internet facing components. As I said, typically, the secure server PULLs data from the less secure one so the less secure server can never have any access to anything more secure even if fully compromised. Indeed there will be a firewall that prevents any traffic from the DMZ (where the less secure service is located) getting to the secure network. Only connections from the secure side are allowed through and they will be tightly controlled by security processes. In a typical bank or other high security setting, you may well find several layers like this, each of which having separate security controls, all partitioned from each other enforcing separation of data and security.
Hope that adds some clarity. Continue to ask if not!
UPDATE 2:
Even for simple, low cost setups, I would still recommend partitioning. For a low cost version, consider having two virtual servers with the dedicated firewall replaced by careful control of the software firewall on the more secure server. Follow the same principals outlined above for everything else.

role-based methods for one web service?

I am trying to set up a (for now) really simple web service. By simple, I mean it only has a small amount of actual work to do on the code-side. It only really has one method/function: the client sends a user login, and the service responds with an otherwise very secure detail about the user (for the purposes of this question, let's say the user's birthday).
I have a lot of questions, but for now I'm wondering:
I am considering having two versions of this method. In version one, the client can only make a generic request with no variable information. The service will respond with birthday of whoever is authenticated in the client's session. In version two, the client is allowed to query any user name (so really, anything they want) and get back either the birthday or "Nothing found", etc.
The application of offering both would be so that most developers would get the birthdate of the current user so that it can be applied to that session. To extend my example: A user logs in, the developer wants to be able to have "Happy Birthday" if it is applicable. The owners of the service/data don't want the developer's client to have any access, real or conceptual, to anything about the user, even their log in, they just want to accommodate the developer's goal, as it is really nice. The developer doesn't want to be responsible for potentially having access to anything, he just wants to be nice.
Version two is available for some user-support groups. They actually need to look up birthdates of users who call in so that they can confirm that the user's are old enough to, let's say, rent a car. They may even have to look up multiple user's to see who is most eligible out of the group to get the best deal.
So I guess the big question, finally, is whether or not these two methods can exist in the same service?
The protocol, at this point, is more likely to be SOAP-based, then RESTful, so simply having URLs that both resolve to the same service but simply offer different methods is probably not an option.
What I need, ideally, is a way to reveal operations in the WSDL based on role. Obviously the documentation given to either group would reflect only the operation appropriate for the role, but ideally the developer/client would a) not see any operations they shouldn't and b) receive the same type of response for trying to use a forbidden response as they would a non-existent one and c) most ideally, receive the former-mentioned error because for their role the operation really DOESN'T exist, not because the service took extra precaution in case the client did try (which it will, FYI, but I don't want that to be the first and only level of obfuscation).
Am I dreaming the impossible dream?
Quick Addendum
I should have been more specific about this, I realize. When I say "role-based" I am referring to service-accounts, not user-accounts. So in my hypothetical situation above, the user-service app that would all for querying any user ID would be using one service-account with the privs to do so, not checking the role of the agent logged in to the session (which would be done to get to the app, obviously, but not to the service).
Why not have two methods:
GetMyBirthday();
GetBirthday(string userName);
Any user can call the first method; only privileged users can call the second method. You use role-based authorization and reject calls to the second method from unauthorized users.
I don't see why you'd want to hide methods in the WSDL based on roles. In many cases you'll be accessing the WSDL only to build a proxy in a development environment, and won't need it at runtime.

Best approach(es) or technolog(y/ies) for this specific problem?

I have a web-based interface for handing invoices, customer records and other transaction records which interacts currently with a database of all the aforementioned stored upon the same machine. As you can imagine, this is quite a simple set-up consisting of a web-app (PHP) and a database (MySQL). However, the ideal scenario is to keep the records on the machine they are currently on (easy) and move the web-app to another server within the same network (again, easy) ... but in addition, provide facilities on a public-facing website for managing accounts by customers and so forth. The problem is this - the public-facing web server is located in a completely separate location as it is a dedicated server provided by a well-known ISP.
What would be the best way to enable the records to be accessible from this other server whilst ensuring that all communications are secure. Speed is not a huge factor, although any outages on either side should be handled gracefully. Initially my thoughts went towards web services (XML-RPC/SOAP/Hessian), but these options seem to present difficulties (security being the main one, overcomplexity as well).
The web-app must remain PHP-based. The public-facing site is likely to be PHP-based as well, although Python (likely using Django) is another option. The introduction of any other technologies (Java etc) is not a problem, although it is preferred if they be Linux-friendly (so .NET would not be the best fit here).
Apologies if this question is somewhat verbose and vague. I am testing the water somewhat in regards to this kind of problem. Any advice or suggestions gratefully received.
I've done something similar. You can expose a web service to the internet that will do the database access, but requests to the service must match a strong hashed and salted password (which will be secured on the ISP's server in the DMZ.)
Either this or some sort of public/private key encryption scheme.
OK, this might seem a bit silly, but what if you just used mysql replication?
Instead of using all sorts of fancy web services, just have a master sql server on one machine, then have it replicate to another server that holds the slave sql server as well as the web app

How can I uniquely identify a desktop application making a request to my API?

I'm fleshing out an idea for a web service that will only allow requests from desktop applications (and desktop applications only) that have been registered with it. I can't really use a "secret key" for authentication because it would be really easy to discover and the applications that use the API would be deployed to many different machines that aren't controlled by the account holder.
How can I uniquely identify an application in a cross-platform way that doesn't make it incredibly easy for anyone to impersonate it?
You can't. As long as you put information in an uncontrolled place, you have to assume that information will be disseminated. Encryption doesn't really apply, because the only encryption-based approaches involve keeping a key on the client side.
The only real solution is to put the value of the service in the service itself, and make the desktop client be a low-value way to access that service. MMORPGs do this: you can download the games for free, but you need to sign up to play. The value is in the service, and the ability to connect to the service is controlled by the service (it authenticates players when they first connect).
Or, you just make it too much of a pain to break the security. For example, by putting a credential check at the start and end of every single method. And, because eventually someone will create a binary that patches out all of those checks, loading pieces of the application from the server. With credentials and timestamp checks in place, and using a different memory layout for each download.
You comment proposes a much simpler scenario. Companies have a much stronger incentive to protect access to the service, and there will be legal agreements in effect regarding your liability if they fail to protect access.
The simplest approach is what Amazon does: provide a secret key, and require all clients to encrypt with that secret key. Yes, rogue employees within those companies can walk away with the secret. So you give the company the option (or maybe require them) to change the key on a regular basis. Perhaps daily.
You can enhance that with an IP check on all accesses: each customer will provide you with a set of valid IP addresses. If someone walks out with the desktop software, they still can't use it.
Or, you can require that your service be proxied by the company. This is particularly useful if the service is only accessed from inside the corporate firewall.
Encrypt it (the secret key), hard-code it, and then obfuscate the program. Use HTTPS for the web-service, so that it is not caught by network sniffers.
Generate the key using hardware speciffic IDs - processor ID, MAC Address, etc. Think of a deterministic GUID.
You can then encrypt it and send it over the wire.