1

I am planning to use the Flickr API in a Windows Universal (UWP) application, written in C#. Early on in my prototype I stumbled upon a security flaw that I have been unable to find a reasonable solution for.

To authenticate a user, I need to obtain a request token using my API key and shared secret. At the moment this information is hard-coded in the application but this can be easily obtained by disassembling the executable with ILSpy. The risk here is that another application can behave as mine and use up my own API call quota.

I did some research but couldn't find any concrete solutions to the problem. Most people seem to suggest a proxy (with no extra details on how this would work in the context of authenticating) or just leave the details hard-coded and generate new keys if it became a problem (which seems like an evasion rather than a solution).

What are my options in this scenario? Am I worrying about something that's not a huge problem? Are there known secure ways of doing this sort of authentication that I'm missing?

Useful Links:

0

The concept of the proxy leaves the question of authentication up to you. As you know the basic idea is that you create a server-based service that is a facade for communicating with Flickr. The UWP apps communicate only with your web service, which in turn holds your secrets and uses them to communicate with Flickr, returning only the results to the end user, never exposing the secrets.

This model leaves the question of end-user authentication up to you. You can create a mechanism that forces your UWP app users to authenticate individually with your web service before communicating with Flickr, or you can allow them to access your web service unauthenticated.

Even if they are un-authenticated, however, this model provides you with several critical advantages.

  1. You can monitor access to the service. If the secrets are embedded in the app, as you've noted they can be stripped out and abused by a malicious user, and you'll never know the difference and have no ability to intervene. If the requests need to go through a service you control, you have the ability to spot potentially abusive patterns, and at least know what is going on, and hopefully have the ability to mitigate the abuse as well by identifying and blocking offending clients.

  2. If there are issues with the credentials, such as they're blocked or expire and need to be changed, you can update them on the server-side without having to push updates to every single client. In the current model, if the creds cease to be valid for any reason, all of your clients are broken until you can publish an update with new secrets, and every client installs it. In this model, the clients are only broken until you update the secrets on the service, and then they magically work again.

  • Thanks for clarifying the proxy, do you have any insight on how this model can support multiple users? Should I be sending a request to the proxy with the standard Flickr metadata (for the API call I need to make) plus the client token & secret such that the request can then be forwarded to the Flickr API from the proxy? Conceptually I don't feel like I should be holding the client secret (since a compromised proxy would result in all accounts being vulnerable) but this information is needed for each request. – Steve Aug 29 '16 at 19:55
  • your proxy becomes both the flickr client and a "backend" to your client. – dandavis Aug 29 '16 at 20:43
0

To add to Xander's excellent answer regarding the proxy, here are a few common alternate approaches in no particular order:

  1. Have each client generate their own API keys (client_id/client_secret) for the service and load them on the app. This could imply a reduction of usability depending on the API provider's setup procedure.
  2. Use the "password" flow, where your app uses uses the actual user credentials to obtain a token. Some OAuth providers implement this flow without client authentication to allow for thick clients where this flow is usually more acceptable.
  3. Fetch the API key online on startup. This isn't very secure (the user can read the key off of memory) but it's a middle ground between having the keys hardcoded and implementing your own proxy. It allows for key revocation/renewal/rotation as necessary

The preferred option would of course be the proxy, but each app has different needs and constraints and some of the alternatives may work where others don't.

-1

If I understand you correctly, you want to supply some private information for an application that you built? I assume this is the case.

Hardcoding any information is never best practice, unless it is the application version number. For webapplications it is common to inject configuration via the environment. Just set the ENV's variables as can be done both on Windows and Unix. This also allows you to change configuration per server/host.

Some frameworks provide a special config file for such settings. This file is excluded from git/version control and you create it per server. This is also where your database settings are stored.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.