I'm developing a little multiplayer game app which requires users to have profiles and allows them to have profile pictures.
The game servers will be hosted on AWS EC2 and as database I plan to use DynamoDB with an additional Redis Cache. To store profile pictures I want to use S3.
The S3 server will be accessible directly from the app since I dont want to route all traffic over my game servers. Now I need to create a secure way to let users
up and download profile pictures. Every user is allowed to upload his profile picture but not every other user may download it.
Uploading should not be a problem since I can use my game servers to sign a link for uploading.
My concern is more about download. There is a "friend system" in the game
and only your friends may see your profile picture. Now I though of several ways to store this pictures securely to ensure the privacy of my users.
Do something with the url:
So the basic idea of this is that I will us a url that is hard to guess for an attacker.
http://s3-aws-region.amazonaws.com/profilpictures/[userid+random 128bit]
But I dont know if thats just enough. Maybe if there are more random bits?
Encrypt the picture:
Just encrypt the image. I would use AES with an 128bit key which is different for each picture and geneated on the users device. The server would store the key and give it only to the right persons.
As url I could use http://s3-aws-region.amazonaws.com/profilpictures/userid what makes the url calculatable. Downside: An attacker could calculate the url and get the encrypted picture. Is that a problem?
Do both:
The approach that guarantees most privacy for my users is just a combination of the both above. But is this enough? Or maybe even too much?
So what do you think about these approaches? Is there anything I didnt think of?
Don't overcomplicate things. Just send signed URLs to those users who should see the picture.
http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURL.html
Related
I am currently learning Node.js authentication. There's something I don't understand and I would be grateful if you could help me. Well I know how to protect password with "passport", "session"... Currently I am making ToDo list website. If hacker somehow got access to my database, he would see all the data users have written without knowing password, right?
So is it necessary to encrypt the whole data?
I'm no security expert but you can think security as layers. Encrypting the whole database is another layer of security. If a hacker would get physical access to the server and the hard drive was not encrypted, yeah he/she probably could read the data. But I would still think that it's more important to have the "accessing" layer secure (login process etc.)
You need to decrypt the data for your users anyway and if the login process is not securely programmed, the hacker could access the data that way.
I am trying to utilize S3 to let my clients download my software package. What I envision is creating a simple web app with authorization For example (download.mysoftware.com) Once the user is authenticated, they will be presented with a S3 url used to download the software. I will create user accounts based on my customers.
My concern is, what happens if the user copies the S3 URL link and then gives it to someone who isn't authenticated to download the software?
Is it possible to create an S3 policy that would prevent this and work for my usecase? I looked at allowing only specific IPs, however, I won't have a way to find out IP of my customers and wouldn't want to ask them first and then add it to the policy each time.
One way allowing specific IPs would work is if I allow downloads only from the IP that is linked to (download.mysoftware.com) but then the downloads will really be happened from my web application as opposed to from S3. Which seems like double effort.
When a user makes a request to download your application, generate a pre-signed URL for them with a short expiration. It only needs to be valid for as long as it takes them to start downloading your file, so even a few minutes of validity is likely to be plenty.
While it's technically possible for a user to share one of these URLs, they would have to convey the URL to someone else and get them to download it very quickly, which is probably sufficient to deter them from trying to share the URL. (A perfect defense is more difficult, and is probably unnecessary anyways; there's no way to prevent a user from personally transferring a file they downloaded to someone else.)
I'm building an app that stores users' potentially-private notes. It's a little weird to me that I can just go into the Firebase Forge UI and look up anything which anyone has written, and it also means that anyone who somehow gains access to my Firebase account can then go in and select "Export JSON" to get all of my users' data.
Obviously I am careful with my account and am a scrupulous human being, but it generally seems like good practice for administrators to not have access to all of our users' data.
The only way I can think of to accomplish this would be to store everything in stringified JSON that has been encrypted by the user's password, but that obviously makes dealing with Firebase much more annoying, and would prevent granular access to data below the point at which things are stringified and encrypted.
Edit: This is, on second thought, not specific to Firebase, but is the case with most/all data stores unless you go out of your way to make it otherwise.
The only way to guarantee information security is to hand roll your own encryption on the server. You could host your firebase connectivity server-side and have your user send the data to that via SSL and from there do your encryption and then use the SSL address of firebase to store.
On the clientside, things are suspect to CSS attacks. If you really want to go down this route you can use js encryption from this lib: http://code.google.com/p/crypto-js/. Note that crpto-js works well in isolation but you will also need to be sure your webpages are not tampered with (quite hard to do IMOP, cause you don't know whats infected the users machine)
Suppose we have a web application for ebook shopping, users can only download books they have paid. And all those ebooks data(like epub data) are stored in S3, users will got a S3 download url when our app validated the user already bought one book.
I know S3 will generate a temporary and time-limited URLs to the user. But the problem is even the url is temporary and time-limited, what will happen if by any chance another user get the temporary url within the limited time?
Ok so one way seems to be letting the limited-time very short, like 10 seconds, but the potential risks still there.
I know this question is rigorous, how would you deal with it? Or forget it?
If the concern is that the buyer would distribute the URL, they could equally well distribute the file they've downloaded.
If the concern is that someone would get hold of the URL without the buyer's knowledge, then perhaps you could protect the download with a token that only the buyer would know (e.g. a password of some sort). This would make the URL unusable to anyone other than the buyer. The downside is that this will inconvenience the very people who've paid for your product.
I'm trying to create a private podcast feeds. Each user of my service gets an account and depending on what they pay, they will receive different content. Some content is sensitive so security is reasonably important; if any of the enclosed audio files made the rounds around the internet, it could be catastrophic for our business.
I am currently prototyping the service and MP3s are stored on S3 and they are not secured. It's time to secure them. From my research, I understand that I can, in fact, secure files on S3 with an access expiry period. But, because I have many users, signing the request with my "global" key and have an expiry probably isn't a good idea because
If I need to revoke access, I'll need to do it for everyone
Since I don't know when, exactly, their podcatcher will request the file, I don't know when to set the expiry. Sometimes, the podcatcher downloads the feed XML, but only later fetches the MP3 file so the URLs could expire before the client has a chance to fetch them (I'm thinking about iTunes, but there could be others).
The way I see it, I have two options and I'm not sure if either are workable:
Edit Another potential way, I suppose, would be to role my own security, and simply redirect to an MP3 on S3 with a short expiry if the user is good to go. This seems most sensible.
I can create user accounts on Amazon for ALL of my users and link them to an Amazon token in my database. Everyone's MP3 urls are signed with their secret token and expiry a long time from now. I don't like the idea of storing their tokens on my database, and I'm not sure if the Amazon ACL was designed for this scenario. It also means the files can still be shared if you know the URL.
I can proxy every request through my server. This means I only have one Amazon account, and I can role my own security system. But proxying every MP3 download through my server sounds slow, wasteful and expensive.
Any ideas on the best way to do this.
P.S. I'm not married to S3. Other solutions could be considered. And I'm on Heroku using Ruby, in case you care.
I am going with the redirect solution suggested elsewhere. This seems to give me the most flexibility and very low overhead. What you definitely should not do is is using links directly to S3 in your feed, because they likely expire before they are downloaded by the client.