Heroku - Keep Keys Hidden Upon Inpect Element - ruby-on-rails

I have deployed an application to Heroku and have used the heroku config:set command to set environmental variables such as keys for certain things (Google Maps API, for example). When I view the page and inspect element, the key shows up in the url in the console. Should this be the case? I was under the impression that keys should be kept hidden to keep others from knowing what they are for security reasons. Please advise. Thank you.

You can't. Anything which is sent to the client is not secret. That includes any values used in javascript.
But don't worry - most API's like Google Maps use a public key. And applications where you use Oauth only allow a whitelist of callback domains.
In fact in the Google Maps Javascript API your API key is used in constructing the URLs used to request resources so attempting to hide it would be a true fools errand.
Some API's do however provide client secrets for calling the API from the server side. These should be kept secret and placed in an ENV var on the server.

Related

What's the correct way of using Google SSO with random URLs (for testing)?

We use Netlify to deploy our frontend and use deploy previews to test each PR. This means the URLs we use to access our application is random following the format https://deploy-preview-<RANDOM_STUFF>.netlify.app. When we try to log in using Google OAuth, we get this error:
What's the correct way to handle this? Security is not super important here because it's only staging/qa.
To clarify: Netlify picks up every single branch and PR, and Netlify generates a new URL with <RANDOM_STUFF>. Adding each of them by hand to Google OAuth's configuration is not an option.
The javascript origin configured for your app must exactly match where you are sending from.
In this case https://deploy-preview-<RANDOM_STUFF>.netlify.app

How to use Youtube api v3 on client computer without API-key?

I am planning to make a browser extension which uses Youtube data API v3. Since the code is public to the user, I am unable to use my API-key in the code. What is the correct way to use API in such a scenario? Also, since the API call will be made from user's browser, is there any other way to fetch data without using API-key at all?
TL;DR
On the API screen of Google Cloud Console, create a new key or edit an existing one to have no restriction. This will enable anyone to use this key to make requests the moment you publish it. There is no way to use the YouTube API without a key (or token respectively, when using OAuth). Your clients are allowed to consume up to 50.000.000 quota units per day, after which your app will essentially break for the rest of the day unless you buy more quota.
However, I have to disagree with the statement that you cannot (or "shouldn't") publish your API key; in certain scenarios, this may very well be desired.
Detailed Explanation
Web application keys used to be organized in two groups: Server keys and browser keys, the former of which where to be kept secret on the server of the web application, while the latter was sent to the client for use in JavaScript. Server keys could be configured to only be accepted from certain IP addresses. That way, even if someone got hold of your key, they wouldn't be able to use it. Browser keys could be restricted to a specified referrer, i.e. the domain (as in DNS) of your web application, so it wouldn't work on other sites beside your own either.
Nowadays, there is no distinction between server and browser keys anymore, they are simply called "API keys". This union makes perfect sense to me, since the only difference between the two types was how they were restricted. With the new API keys, one can still choose how to restrict its usage - or choose to not restrict the key at all.
This is where we get back to your case: It is, of course, possible to publish a key and at the same time not restrict it. Depending on how many users are using your app (and will be using it in the future) and how many are using your key for their own app (which you have no control over), the 50 million quota limit will work out for you or it will not.
An then there's responsibility as well. You are responsible for the queries that are made with your API key. This is probably one of the reasons why YouTube doesn't allow for requests without a valid key: They need to stay in control of their service and, naturally, want to protect it from DOS attacks. If someone does mischief with your key, you are the one who gets punished for it, usually by deactivation of the key.

Dynamically set api keys on frontend

Is there any way to set the variables for api keys on the front end. I am used to setting ENV variables on the backend, but is there something similar on the front end?
I'm assuming you're asking whether you can set an API key on the client-side, i.e., in JavaScript. You probably can in some scenarios, but in my opinion you shouldn't.
By its nature, data that you send to the client-side for processing (e.g., JavaScript, HTML, and CSS) can (and must) be read by that browser. In order to set an API key and send a request to an API from the client-side (assuming you've already worked around the same-origin policy), you'll have to send that API key over the wire and allow the browser to read it -- which is bad.
The API key identifies and authenticates you, and there can be damaging consequences if a stranger gets a hold of it. I would keep it on the server-side and make your API requests from there.

Parse.com REST API authentication

Parse.com's REST API docs (https://www.parse.com/docs/rest) say: Authentication is done via HTTP headers. The X-Parse-Application-Id header identifies which application you are accessing, and the X-Parse-REST-API-Key header authenticates the endpoint. In the examples with curl that follow, the headers are stored in shell variables APPLICATION_ID and REST_API_KEY, so to follow along in the terminal, export these variables.
I am building a Sencha Touch app as a native app on iOS and Android using Phonegap, and I was wondering whether it is secure to expose these keys to the client while making the REST calls?
Also, can someone explain to me how does security work in this scenario? Help is much appreciated! Thanks!
Without phonegap , in a proguard , post processed android apk , the string values of the 2 headers you mention are exposed client-side . not a big issue. TLS covers the http header values during network leg and far more important for app security, you have Full ACL at the DB row level(parse/mongo) contingent on permissions of 'current user()'. So with no access to logon, some outsider doesn't have any more than obfuscated string value to an app-level access token.
. One odd thing is that with parse the lease time on the client-side token value foapi key is permanent rather than say a month.
Parse REST security is robust n well executed.
Can't speak to what PG framework offers in obfuscate/minify/uglify area but you should check that.

What is the standard way to handle twitter API keys in GPL'd desktop applications?

While developing an desktop application that needs to access twitter API , one must somehow pass the API key (application specific consumer key and consumer secret ) for the application to the user. Twitter's API TOS states that the application's API key cannot be publicly available and if that happens, they reset it. When that application is under GPL , meaning the developer needs to provide the source code to the user, how that user would be able to obtain the API key without it being publicly available ? Is there a standard way to handle this issue ?
Thanks.
Edit:
To clarify the situation, I was storing them in plain text in my code for cree.py so far as a conscious decision. But yesterday Twitter support team contacted me that they have reseted my key and their reasoning was the following :
C. You should not solicit another developer's consumer keys or consumer secrets especially if they will be stored or used for actions outside of that developer's control. Keys and secrets that are compromised will be reset by Twitter. For example, online services that ask for these values in order to provide a "tweet-branding" service are not allowed.
https://dev.twitter.com/terms/api-terms
If an application's keys are posted publicly, it allows for external parties to hijack the application's API access. This presents an enormous abuse risk, and as such we've reset your API keys. Please take care to ensure that these keys are not posted publicly again.
Thanks,
Twitter API Policy
Well, TTYtter evidently uses the honour system:
# yes, this is plaintext. obfuscation would be ludicrously easy to crack,
# and there is no way to hide them effectively or fully in a Perl script.
# so be a good neighbour and leave this the fark alone, okay? stealing
# credentials is mean and inconvenient to users. this is blessed by
# arrangement with Twitter. don't be a d*ck. thanks for your cooperation.
$oauthkey = (!length($oauthkey) || $oauthkey eq 'X') ?
"XXXXXXXXXXXXXXXXXXXXX" : $oauthkey;
$oauthsecret = (!length($oauthsecret) || $oauthsecret eq 'X') ?
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : $oauthsecret;
(I have replaced the actual keys with Xs, to make it a little less likely that anyone will go to the trouble to abuse them, but rest assured that they are present in full in the actual source!)
Also, I don't see anything in the Rules of the Road actually requiring you to keep these things secret: the closest thing I see is the statement "Keys and secrets that are compromised will be reset by Twitter."; they never actually say what "compromised" means, though.
I might be dense here, but why don't you store them in a configuration file, the Windows registry etc and get them from there? Then distribute the application without the file, and you're done.
Maybe another solution would be to use a server, the server interacts with the twitter api, and the you request information to your server with your desktop application
Like that, the API key is only stored on the server, and not any user can get it.

Resources