What are the best practices for delivering an Adobe Air app that needs a private key in order to communicate with some online API?
Adobe Air apps seem like they are delivered to the user with full source code, so storing any keys within the source would be a really bad idea. I've read some suggestions saying to download the key from your server, but that has the same problem because the url allowing the download would have to be stored in source code. Also, suggestions saying to store in the encrypted local storage don't make sense to me either, because I still have to obtain the private key somehow.
I think this is a global problem of delivering secret keys in any application, since everything can be reverse-engineered (disasamble for executables, IL readers, etc.)
No matter what you do, if the client application needs to somehow "know" a secret key, then the user can know the secret key.
Assuming that:
You deliver a product ("client application") which relys on some 3rd party web service ("the service").
Your company has just one secret key ("company key") for using the service.
The company key must never be exposed (due to possible abuse)
Every piece of information held by or transmitted by the client application is exposed
A solution might be to use some proxy:
The proxy implements the API of the service
The client application connects to the proxy
The proxy connects to the service using the company key
The proxy delegates all calls from the client to the service and vice-versa
Related
I have a file hierarchy that gets files and folders from one of the users hub. All of these calls are on server side. Can these calls reside on the client side and still remain secure? None of these calls have my client secret from my Forge application. To clarify can you answer what calls can be client or server sided and still be 100% secure.
Get 3 legged auth(exposes client secret) - secure or not on client side
Get hubs - secure or not on client side
Get projects - secure or not on client side
Get files in folders - secure or not on client side
Get versions of files - secure or not on client side
Download files - secure or not on client side
As you can read in this article: https://developer.autodesk.com/en/docs/oauth/v2/overview/scopes/ Autodesk says about the scopes that on client side only the scope viewables:read should be available.
"Because this means that the token is exposed on the client-side, it is important to make sure that the token is restricted for Viewer calls to the viewables:read scope, which limits access to the end user’s viewable output files (SVF, PNG, etc). This is particularly important in a two-legged context, where a malicious end user could use an unscoped token to take actions across the platform on the developer’s behalf and compromise the developer’s data."
I don't know what kind of application you are building but you have to ask yourself what your users are able to do with the scopes you give them.
Since you give scopes on your whole account and not on specific buckets you also have ask yourself if clients who have access to folder "a" also can see the content of folder "b".
None of the calls can be secure on the client as you need to expose a token with a specific scope (data:read, data:write or both ...). The way to secure your app is to performs all calls to Forge from your server only, then expose the features you need on the client through controlled endpoints, either REST or GraphQL like in my latest article.
This way you expose only the data you want/you and can have a better control over what use is done of it, for example you can limit the rate of use of your endpoints so you avoid DDOS attack using your keys. If you use node.js it is easy: express-rate-limit.
Securing a web application is a very broad topic, there are many areas you may want to explore, but keep in mind that everything that is exposed to a client is considered not secured.
Hope that helps
Currently I'm developing a Node.js webserver-app that I then want to make available for download and use. This app should feature accounts, so that you can log in with your account on the website created by the server.
Since that would require a password, I also have to think about security obviously. But now, I don't really know how I should protect the password while sending and receiving it.
For storage, I was about to simply create a hash of the password and store that hash somewhere, but what about the transfer?
I was thinking about SSL/https, but this would require a SSL certificate, and even if I got it for free somewhere, I couldn't share it in an open-source app(?).
I could also somehow hash the password in the website, and then just send the hash to the server, but I think this wouldn't be the highest standard of security as well, would it? Considering that no SSL would cause more disadvantages than just worse/none encryption.
Any ideas?
I was thinking about SSL/https, but this would require a SSL certificate, and even if I got it for free somewhere, I couldn't share it in an open-source app(?).
Use SSL/TLS. Even if it's an open source app, it doesn't mean that you need to share your private key too. This would undermine the whole concept.
Open source means that you share the code with some license. What the licensor does with it is not your consern as long as they conform to the license. If they want to use their own instance of your software under their own domain, they will have to create their own certificate (under their domain).
I could also somehow hash the password in the website, and then just send the hash to the server, but I think this wouldn't be the highest standard of security as well, would it? Considering that no SSL would cause more disadvantages than just worse/none encryption.
This is no solution, because you now changed the thing you want to protect to something else. The model doesn't change just because you hash it on the client. Now you need to protect the hash on the transport channel which is actually the same problem as you would have had before with sending a password.
Currently I'm developing a Node.js webserver-app that I then want to make available for download and use. This app should feature accounts, so that you can log in with your account on the website created by the server.
Federated accounts
If you want federated accounts across multiple instances of your app which are hosted by different parties.
You could look into OpenID as an identity provider for all instances of your app. You would then either require that users use a known OpenID provider or you setup your own default provider. You could release the code for your provider as open source, but it wouldn't be necessary for the app to function.
If the OpenID interface is not enough, there is always a way to establish a pairing between instances of your app. You would have to build an interface where different instances may share data.
Unconnected instances
If this is only about securing the communication without SSL/TLS, then I must say, this is impossible in the general sense.
You could however let every student register in person and use that password on client and server to derive a shared secret key (i.e. for AES). Then you could use CryptoJS to encrypt everything with AES and send it using AJAX. The problems are of course that (1) there must be a person that handles the registration and (2) this is vulnerable to man-in-the-middle attacks, because JavaScript crypto is bad.
Good thing is that Let’s Encrypt will be online soon. It will enable a semi-automated way to request free certificates for your domain. It will be so easy that you can do this as part of the normal NPM install workflow.
http://letsencrypt.org works great for this and is now available (I understand I am a little late to this one.)
You can check out https://github.com/DylanPiercey/auto-sni for automated Letsencrypt certificates.
My server must receive data from a number of devices who have downloaded my application through an app store or otherwise trusted channel. I need a method to verify that data my server receives is actually from these devices. The server does not have access to a list of these devices ahead of time.
What are some popular ways to accomplish this?
Depends on the platform. The accepted answer to the linked question offers the idea (of using SSL for authentication).
I'd like to add to that answer, that if the client has some API with non-exportable private keys (either hardware-based or encrypted like CryptoAPI certificate storage in Windows), then you can store client certificates there.
I've setup a Windows Azure database with the data accessible via oData. I'm trying to work out how to secure the connection between a WP7 device and the database. By secure I mean I only want users of the app to be able to access the data from within the app.
I've considered SSL but it's quite expensive for me - is there another way of securing this connection?
Thanks!
There are multiple definitions of "secure". You will need authentication, so Azure only lets the correct users access the data. This is usually handled by a user name and password supplied by the WP7 app.
The WP7 app needs to ensure it is talking to the correct server. SSL handles this using a digital certificate. There are other mechanisms but using something based on a public/private key pair is best because you can validate you are connecting to the correct server without being able to impersonate that server. However, the RSA algorithm used in most cases is computationally expensive.
The data sent between the WP7 app and Azure also needs to be confidential, including the user's password. This is normally handled by encryption. You an choose computationally less expensive algorithm or only encrypt certain data.
The data sent between the WP7 app and Azure also needs some form of tamper detection. Otherwise someone could corrupt the data sent or received. Maybe this is something you can accept for the app but it needs to be a way that an attack cannot easily reproduce. As Shanin's Maxim says, the attacker knows the system.
The problem is that SSL gives you all of these. Yes, it can be expensive but it is one of the best general purpose solutions available. You can change the cipher suites offered by Azure using using Group Policy, code or PowerShell.
If you do not want to use SSL, you need to know what you can sacrifice. In general I would not recommend doing your own encryption mechanism or protocol because us mere humans tend to screw it up.
I'm building an (amateur) application that uses the Twitter API, which supports authentication via the OAuth protocol.
Part of the OAuth sign-in process involves each application being assigned a Consumer Key and Consumer Secret (both strings), which are used to generate signatures for communication with the Twitter server.
The Twitter dev guide explicitly states that one should 'Keep the "Consumer secret" a secret. This key should never be human-readable in your application.'. This is obviously important, as if a malicious individual obtains your credentials, they can impersonate your app.
However, I do not see how this can be achieved. In order for the application to use the string, it must be accessible to the app somehow (either directly coded into the app, stored in a bundled database, or accessible via a linked web service) - and if it's accessible to the app, it must be accessible to the user. It can be obfuscated by splitting, character-shifting, etc., but not (as far as I can see) in any way that can't be undone.
This SO answer confirms my suspicions that this is a problem - I was wondering if there had been any progress since it was posted in December '09?
The problem with mobile devices is that is in the users hands. And with enough time/effort the user can pull any data out of the device. It isn't an OAuth security problem, it is an overall security problem that there really isn't an answer for.