As per the object, is secure to push sensitive data to Amazon SQS?
For example, I want a user sets its credentials in a form on website A, so website will push a message that is then pulled by Website B, so website B can create an account.
So, is this flow secure?
If you are worried about security, then you should be worried about putting sensitive data in an SQS queue. Anyone that has/obtains sufficient privileges or access within the AWS infrastructure could read you messages.
One option is for message producer to encrypt the message before sending and the message consumer to decrypt the message upon receipt. The SQS message is a string, so you will have to encode (e.g., base64) your encrypted bytes as a string.
By encrypting before sending and decrypting after receiving, your message is secure.
Related
I'm not sure if I'm being over cautions; I'm implementing the ios push notifications and there's is a part where I need to send the device token to the server, so that's clear, all I had to do is send a request like this:
www.mysite.com?registerIosToken=asdfgadsfhgakjhsf
So my server can register the token in the db.
But what if someone sends multiple random requests to this url?, how can I detect ignore fake requests?,
I was thinking using the app public certificate, and I can decrypt it in the server with my private key, but if the key is public, everyone can encrypt it...
For iOS applications that require push notifications, it must first request the user for permission to do so. After that, a device token is generated and with this, the remote server may communicate to the user through this token.
I have read a similar question here and I do not feel it is enough. The picture below is a trusted certificate, it allows me to view all traffic that happens on this device.
With Fiddler2 as well as CertMaker, I can sniff HTTPS traffic, which means the client can probably know what data they are sending, and to where.
My question is, knowing that SSL is not secure from protecting my clients from seeing what I send to the remote server, should I simply encypt with a secret key found within my application?
Such as encrypt("device_token","secretkey_a0a0a0a") (pretend this is Objective-C)?
Couldn't someone just find that key within my application? I also read this question, and it seems that it would be possible to get back the secret key.
My plan for this goes like this:
Within the iOS application, Generate a random string named activate.
Encrypt (not hash), the token by the random string and a secret key that I only know. (secretkey_a0a0a0)
Send the encrypted string along with the generated randomly generated string (active).
Within serverside, I check if I can decrypt a valid token from using the active and my secret key.
I save the token in my database if it is valid.
This prevents people from random entering tokens yes, however, secretkey_a0a0a0 is a string literal. It's very possible to get this within the application binary itself.
My question is, how do I protect this secret key? The answer can also be, how can I prevent people from sending invalid tokens to my server as well.
I have heard of encryption, but doesn't that only apply to resource files?
How should I approach this?
If you do SSL-Pinning ( AFNetworking has this implemented ) you won't be able to (in a reasonable timeframe) sniff the https traffic between the client and server if you don't have the servers private key.
If your fear is that man in the middle can steal your token and send fake push notifications to users of your application, be sure that this cant happend. Since requests to apple apn servers must be signed with pem file, the main concern should be how to keep certificate file secured, and not apn token. If you want to prevent writing invalid tokens in your database then you should implement some CRC or odd/even bit mechanism.
You might want to check the security section in the Push Notifications Guide, in particular the section titled "Token Generation and Dispersal".
The device token is generated by the device connecting through the Apple's APNS. My guess (they don't say in the docs) is that it's unique for a given app identifier.
The APNS then will probably match those identifiers with the pem certificate you use to communicate with it thus validating that the push notifications are actually originating from your app.
Encrypting the device token seems overkill in this scenario.
To prevent someone maliciously spamming your server with tokens, I would hash the token when a secret key and send both the token and the hash to the server. You can then hash the token again on the server, with your secret key, and check that the request is valid.
I have a server side java application which send bulk push messages to apple server. Recently i'm getting multiple SSLSocketException: Connection closed by remote host OR SSLSocketException: Broken pipe expcetions.
I understand that in case i'm sending invalid tokens, apple forcefully closes the connection. I also have a feedback loop, but the failing tokens never appear on feedback loop since they are not even accepted by apple.
Is there any algorithm or method to know, why the device token is "invalid" ?
Why the device token is invalid?
Assuming you got all your device tokens from Apple and didn't create dummy tokens, the most likely cause for invalid tokens is a DB that has both production tokens and sandbox tokens.
How to find which tokens are invalid :
You should use the enhanced APN format, in which you specify the message ID. After each message you send to Apple, you should try reading from the socket after setting the timeout to a large enough value. Apple will send you error responses for the invalid tokens, which specify the message ID. This will let you find the invalid tokens and remove them from your DB.
Note that you should only use this method (reading responses after each message with a long timeout) in order to clean your DB. After your DB is clean from invalid tokens you don't want to use it, since it will make the notifications delivery very slow.
After extensive research, I have not been able to find a clear answer to my question. Firstly, can anyone tell me the basic logic of handling "login functionality" for a native iphone app connecting to a web service? For instance, the facebook app ask for a username and password immediately after launch, and from there you have full access to your account in all successive views of the app. Each time you post something etc, you do not have to re-login... Can someone please explain this process to me? Is it done through cookies or sessions? is Keychain involved?
I have a semi-working app right now but I'm almost positive I could be doing it better and more securely. Here is what I'm doing:
1) Set up a local server with a database of users (username and password columns and other tables etc.) using mysql. Wrote a simple web-service that takes in POST data and queries the database to check that the username exists... and if it does, that the passwords are equal. Using sha1 hashing. Echo true or false accordingly.
2) My app has an initial login screen with a 2 textfields (1 for username and 1 for password) and a button that calls the login method. My login method does the following:
init an *NSURL with a string (the url of my web service: #"http://webservice.com/login.php")
init an *ASIFormDataRequst with that url
set the post value with the password and email text in the text fields
set the delegate to itself
call startAsycronous on the request
implemented the requestFininshed method to retrieve the "true" or "false" echo-ed from the webservice
depending on the response, move forward to the next view, else, make an alert telling the user to retry
So, my questions are:
1) Is this secure for sending passwords? (via ASIHTTPRequest and the POST method?)
2) In the succeeding views, the user should be able to interact with their account (like posting messages and status's and pictures on the Facebook) How do I persist the user's logged in status so that every time the user interacts with the database, I can ensure that the user is still logged in and that it's the same user? For instance, the only way I can think of doing this is if I store a cookie on the users device with the username and password, and then every successive interaction with the web service / database, it does an authentication with the cookie values (username and password).
There has got to be a better way of doing this? Maybe sessions or cookies? or by using keychain??
Thanks for the help guys, and sorry for the long question!
Here are my thoughts based on what I know:
1) Is this secure for sending passwords? (via ASIHTTPRequest and the POST method?)
You need to make sure you are sending this information via https (SSL) and not a plain Http. The reason is, you don't have control over where the user wireless access point is. For all you know, the user could connect to open access point that is belong to a particular hacker. Having it transmitted will enable him to sniff the packet and get the required information to access the WebService even though the password is hashed. Having it send via https would ensure that the packet is encrypted with strong key. Even if a hacker manage to sniff the packet out, it will take him a long time before he/she is able to decrypt the message.
In the succeeding views, the user should be able to interact with their account (like posting > messages and status's and pictures on the Facebook) How do I persist the user's logged in status > so that every time the user interacts with the database, I can ensure that the user is still logged in
and that it's the same user?
One commonly employed method to do this is to get the session token after the user logged in. That is, you create a random generated ID that you return upon successful login. You would then map this token with the user id in the backend and it is associated with a session time out. You refresh this time out every time the user connects to a webservice and time it out after certain period to avoid breach of security. You would then persist the session token in your device and then used that for subsequent call. As long the session is alive then the user is logged in. As the token is associated with a specific user, you also ensure the identity of the caller.
To prevent someone else using other people token is the reason why you need SSL to secure the channel and prevent sniffing. Assuming that you have secured your connection channels, the only way to get the token is
to verify the identity via login
The phone is stolen by hackers who could take the token by inspecting the local storage.
The mapping is necessary so you could validate the token is a real token that has been associated with the user via login activity. Furthermore,for number 2, you can offer remote wipe out feature that basically kills the mapping and making that token invalid.
Another very important part of this token is the token cannot be guessable and have to be random cryptographically (see Randomness Recommendations for Security). If the token is only based on pseudo randomness, a clever hacker might be able to guess its algorithm and can guess its next/previous token and has a possibility of obtaining any valid token in the table.
There are many algorithm to generate this token. For example, Java Programming Language provides a SecureRandom class in order to provide cryptographically randomness and .NET has similar secure RandomGenerator class.
If you want to look at the algorithm OATH has proposed Time-Based One-Time Password Algorithm (TOTP) which is an extension of HOTP. Most of the languages/platforms would have the cryptographically strong random generator that you could leverage immediately though without you having to write it yourself.
Depending on your service implementation/platform, you might want to ask SO for a suitable class/module for cryptographically random generator such as the one asked here "How do you generate cryptographically secure random numbers with php"
I'm planning to use Facebook as the only sign-on mechanism for an application that I'm building and need some feedback on the design. Here it goes -
User opens the app and is presented with a register screen. The facebook authorization flow starts and let's assume it succeeded and the user has successfully registered himself. Upon success, the app calls the Facebook graph API and gets the user's firstname, lastname, email, date of birth etc. With this data, the app then calls a web service method called RegisterUser(string Fullname, string FirstName, string LastName ...) which creates the user record in the database.
Now for subsequent calls to the API, I need to authenticate that the request is really coming in from my application (not necessarily a particular user). I've looked up the S3 REST API and it seems that with every request there's a HTTP header called Authorization that the client creates by appending a bunch of other HTTP Headers like Date, Method, Request data, signing it with the client's private key and computing its base64 encoded value. This is verified on the server side to authenticate the client.
Now, I'm comfortable implementing all this, but a few questions:
If I have a private key, is it safe to include it as a part of the iOS application itself? Can someone extract the key from the iOS application binary? If so, how do I deal with this?
Are there any other changes you'd make to this design ?
Thanks,
Teja.
Make sure you apply a one-way hashing algorithm to the value to base64 encode - base64 is a two-way encoding, so you don't want eavesdroppers reverse engineering your private key from that. Amazon S3 does this with performing a SHA-1 before doing the base64.
As with all (AFAIK?) compiled binaries, your app shouldn't be able to be decompiled.