hide api key for a Github page - ajax

I have a github page for my organization where I would like to call data from a 3rd party api where I need an auth token. Can I publish this github page without having the auth token displayed on the public repo?

In short, no. If your GitHub repo is public, all its assets are public. You can make the repo private and it will still publish on GitHub Pages if named with the username.github.io convention or if it has a gh-pages branch. While that's an option, that's not necessarily the right thing to do.
If your key is in your GitHub Pages repo, it sounds like it's used for client-side API calls in JavaScript. If so, your auth token is publicly visible whether it's in your public repo or sent in your client-side files to the browser. This is usually fine. The third-party API might have generated the auth token based on your website's domain, and restrict calls using that token to pages originating on your domain. Otherwise, they might require the auth token only for logging requests and monitoring usage.
If the auth token is truly meant to be private, then you may need to write private server-side code to call the third-party API. Your GitHub Pages site could then hit your service for the data it needs. I've had to do that before where the web API had security concerns, but I still needed to retrieve non-sensitive data from the client-side.

In short yes, you can store the auth token in an environment variable and use gitignore on the .env file to hide the auth token in the public repo. Refresh the auth token on the client-side API then push changes to the public repo and redeploy your updates to the gh-pages branch. I've provided an example of this process below.
NOTE
If you committed a password or API key, change it! If you committed a key, generate a new one. Reference general best practices on GitHub.
If using React for your app, SKIP steps 1 and 2 as React already comes pre installed with custom environment variables. Reference Create React App.
The full explanation can be found below:
1. Install dotenv dependency in application root directory (will be using Node.js for this example) Reference npm, run command:
npm install dotenv
2. Add code below to import statements in index.js file.
require('dotenv').config();
3. Create .env file in root directory of app and add auth token as variable. Note when using React you must prepend variable name with REACT_APP_
AUTH_TOKEN=987asc8iks0lenv7
4. Use console.log() on process.env to check if the variable was stored correctly.
console.log(process.env.AUTH_TOKEN);
5. Update all references to auth token in application code.
OLD VARIABLE: const auth_token = '987asc8iks0lenv7';
NEW VARIABLE: const auth_token = process.env.AUTH_TOKEN;
6. Create and add .gitignore file to the root directory of application and add code below to have git ignore the .env file where the auth token is stored.
.env
7. Add, commit and push updates to application master branch on GitHub.
8. To deploy or redeploy updates to gh-pages branch. Use command below.
npm run deploy

The answer of Ashen won't work for this use case. Secrets configured through Github are only available to Github Actions (see documentation), and because of that - in practice - mostly to CI/CD-like applications. Not for e.g. client-side API calls.

The GitHub Actions should facilitate your need.
You can add secrets using the visual workflow editor or the repository settings. Once you create a secret, GitHub encrypts the value immediately and you can no longer view or edit the value. Anyone with write access to a repository can create and use secrets in that repository.
However, the GitHub Actions is currently available in public beta and therefore should be avoided for high-value workflows and content during this beta period.

Related

Is it safe firebase-messaging-sw.js in public folder [duplicate]

The Firebase Web-App guide states I should put the given apiKey in my Html to initialize Firebase:
// TODO: Replace with your project's customized code snippet
<script src="https://www.gstatic.com/firebasejs/3.0.2/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
};
firebase.initializeApp(config);
</script>
By doing so, the apiKey is exposed to every visitor.
What is the purpose of that key and is it really meant to be public?
The apiKey in this configuration snippet just identifies your Firebase project on the Google servers. It is not a security risk for someone to know it. In fact, it is necessary for them to know it, in order for them to interact with your Firebase project. This same configuration data is also included in every iOS and Android app that uses Firebase as its backend.
In that sense it is very similar to the database URL that identifies the back-end database associated with your project in the same snippet: https://<app-id>.firebaseio.com. See this question on why this is not a security risk: How to restrict Firebase data modification?, including the use of Firebase's server side security rules to ensure only authorized users can access the backend services.
If you want to learn how to secure all data access to your Firebase backend services is authorized, read up on the documentation on Firebase security rules. These rules control access to file storage and database access, and are enforced on the Firebase servers. So no matter if it's your code, or somebody else's code that uses you configuration data, it can only do what the security rules allow it to do.
For another explanation of what Firebase uses these values for, and for which of them you can set quotas, see the Firebase documentation on using and managing API keys.
If you'd like to reduce the risk of committing this configuration data to version control, consider using the SDK auto-configuration of Firebase Hosting. While the keys will still end up in the browser in the same format, they won't be hard-coded into your code anymore with that.
Update (May 2021): Thanks to the new feature called Firebase App Check, it is now actually possible to limit access to the backend services in your Firebase project to only those coming from iOS, Android and Web apps that are registered in that specific project.
You'll typically want to combine this with the user authentication based security described above, so that you have another shield against abusive users that do use your app.
By combining App Check with security rules you have both broad protection against abuse, and fine gained control over what data each user can access, while still allowing direct access to the database from your client-side application code.
Building on the answers of prufrofro and Frank van Puffelen here, I put together this setup that doesn't prevent scraping, but can make it slightly harder to use your API key.
Warning: To get your data, even with this method, one can for example simply open the JS console in Chrome and type:
firebase.database().ref("/get/all/the/data").once("value", function (data) {
console.log(data.val());
});
Only the database security rules can protect your data.
Nevertheless, I restricted my production API key use to my domain name like this:
https://console.developers.google.com/apis
Select your Firebase project
Credentials
Under API keys, pick your Browser key. It should look like this: "Browser key (auto created by Google Service)"
In "Accept requests from these
HTTP referrers (web sites)", add the URL of your app (exemple: projectname.firebaseapp.com/* )
Now the app will only work on this specific domain name. So I created another API Key that will be private for localhost developement.
Click Create credentials > API Key
By default, as mentioned by Emmanuel Campos, Firebase only whitelists localhost and your Firebase hosting domain.
In order to make sure I don't publish the wrong API key by mistake, I use one of the following methods to automatically use the more restricted one in production.
Setup for Create-React-App
In /env.development:
REACT_APP_API_KEY=###dev-key###
In /env.production:
REACT_APP_API_KEY=###public-key###
In /src/index.js
const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
// ...
};
I am not convinced to expose security/config keys to client. I would not call it secure, not because some one can steal all private information from first day, because someone can make excessive request, and drain your quota and make you owe to Google a lot of money.
You need to think about many concepts from restricting people not to access where they are not supposed to be, DOS attacks etc.
I would more prefer the client first will hit to your web server, there you put what ever first hand firewall, captcha , cloudflare, custom security in between the client and server, or between server and firebase and you are good to go. At least you can first stop suspect activity before it reaches to firebase. You will have much more flexibility.
I only see one good usage scenario for using client based config for internal usages. For example, you have internal domain, and you are pretty sure outsiders cannot access there, so you can setup environment like browser -> firebase type.
The API key exposure creates a vulnerability when user/password sign up is enabled. There is an open API endpoint that takes the API key and allows anyone to create a new user account. They then can use this new account to log in to your Firebase Auth protected app or use the SDK to auth with user/pass and run queries.
I've reported this to Google but they say it's working as intended.
If you can't disable user/password accounts you should do the following:
Create a cloud function to auto disable new users onCreate and create a new DB entry to manage their access.
Ex: MyUsers/{userId}/Access: 0
exports.addUser = functions.auth.user().onCreate(onAddUser);
exports.deleteUser = functions.auth.user().onDelete(onDeleteUser);
Update your rules to only allow reads for users with access > 1.
On the off chance the listener function doesn't disable the account fast enough then the read rules will prevent them from reading any data.
I believe once database rules are written accurately, it will be enough to protect your data. Moreover, there are guidelines that one can follow to structure your database accordingly. For example, making a UID node under users, and putting all under information under it. After that, you will need to implement a simple database rule as below
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
No other user will be able to read other users' data, moreover, domain policy will restrict requests coming from other domains.
One can read more about it on
Firebase Security rules
While the original question was answered (that the api key can be exposed - the protection of the data must be set from the DB rulles), I was also looking for a solution to restrict the access to specific parts of the DB.
So after reading this and some personal research about the possibilities, I came up with a slightly different approach to restrict data usage for unauthorised users:
I save my users in my DB too, under the same uid (and save the profile data in there). So i just set the db rules like this:
".read": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()",
".write": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()"
This way only a previous saved user can add new users in the DB so there is no way anyone without an account can do operations on DB.
Also adding new users is posible only if the user has a special role and edit only by admin or by that user itself (something like this):
"userdata": {
"$userId": {
".write": "$userId === auth.uid || root.child('/userdata/'+auth.uid+'/userRole').val() === 'superadmin'",
...
EXPOSURE OF API KEYS ISN'T A SECURITY RISK BUT ANYONE CAN PUT YOUR CREDENTIALS ON THEIR SITE.
Open api keys leads to attacks that can use a lot resources at firebase that will definitely cost your hard money.
You can always restrict you firebase project keys to domains / IP's.
https://console.cloud.google.com/apis/credentials/key
select your project Id and key and restrict it to Your Android/iOs/web App.
It is oky to include them, and special care is required only for Firebase ML or when using Firebase Authentication
API keys for Firebase are different from typical API keys:
Unlike how API keys are typically used, API keys for Firebase services are not used to control access to backend resources; that can only be done with Firebase Security Rules. Usually, you need to fastidiously guard API keys (for example, by using a vault service or setting the keys as environment variables); however, API keys for Firebase services are ok to include in code or checked-in config files.
Although API keys for Firebase services are safe to include in code, there are a few specific cases when you should enforce limits for your API key; for example, if you're using Firebase ML or using Firebase Authentication with the email/password sign-in method. Learn more about these cases later on this page.
For more informations, check the offical docs
I am making a blog website on github pages. I got an idea to embbed comments in the end of every blog page. I understand how firebase get and gives you data.
I have tested many times with project and even using console. I am totally disagree the saying vlit is vulnerable.
Believe me there is no issue of showing your api key publically if you have followed privacy steps recommend by firebase.
Go to https://console.developers.google.com/apis
and perfrom a security steup.
You should not expose this info. in public, specially api keys.
It may lead to a privacy leak.
Before making the website public you should hide it. You can do it in 2 or more ways
Complex coding/hiding
Simply put firebase SDK codes at bottom of your website or app thus firebase automatically does all works. you don't need to put API keys anywhere

Which function is called while a user requests a file in go-ipfs?

I am working with go-ipfs locally for my project. I have created a private IPFS cluster for my project. Now I want to add an extra layer of access authorization while a user requests a file using its CID. In this layer, the go-ipfs would contact the smart contract that I have deployed and check for user authorization. So I want to figure out before which function call in go-ipfs should I add this authorization check?
go-ipfs repository
Thanks.

Storing credentials inside slack framework, needed by custom app for slack api integration

For a custom integration, we are looking an a scenario where we want to save some access keys in private variables during transaction. Currently we are planning on using heroku as platform and node.js as the framework. Now we don't want to store these variables inside either node.js or heroku, as it would still be accessible from outside slack. Do we have any mechanism where we can store such values inside the slack framework and then access them? Using slack user datatable or something similar?
Slack does not have a mechanism to store credentials.
As a workaround you can post the credentials to some private channel and can retrieve it from there. But it is not recommended.
Ideally you should store these credentials to a secure encrypted place.
May be you should use some kind of secure database/cache/cloud vault.

How to integrate key vault with Bot composer

I want to make an http request from bot composer but one thing to pass while making http request needs to be kept a secret. So I want to fetch that value from key vault. Can someone tell how to integrate bot composer with key vault.
I'll assume you are using Azure to run the bot, so I'll answer with that in mind. Otherwise let me know and I can expand the answer.
Take the secret from the settings of the bot. It's just like how you access turn.activity.text, but using settings scope instead of the turn scope. So: settings.apiSecret.
Local Env
Now in development, local environment, you can just put the secret in the settings file.
In Azure
When you deploy to your azure app service, you can use Key Vault References in the Configuration blade. Remember you need to give the app service Secret Get permission to that Key Vault.
This is the easiest way since you don't need to write code to query KeyVault via the API.
From DevOps to Azure
There's a way to get the secret in the pipeline, but I believe this is not something you need in this scenario, you just want to set the variable in the App Service. So in the App Service Deployment task, under Application and Configuration settings -> App Settings: you can add the same thing you'd put in the Configuration blade in the azure portal.
So you can add to the textbox: -apiSecret #Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/) or click on the button with the elipsis on the right and enter it on the form

Why save the personal access client id and secret in .env?

I am new to laravel passport and i am figuring out how laravel passport works
Question 1
Why save the personal access client id and secret in .env according to the docs here? if the id and secret is created by executing this command php artisan passport:client --personal and stored in the database
Question 2
According to docs, it is said to save it in .env file. which application is it saved in? the passport application or the frontend javascript application. I have 2 different projects one is the laravel passport(backend) and the other is the nuxtjs(frontend)
Answer 1
You should never hardcode secrets; that is one of the most basic security best practices. The reason behind that is that when you push your code into any remote(usually Github), you let anybody see that secret.
Even if your repository is private, you may not want all members to have access to it or if you decide to make it public you won't want to worry about secrets being leaked. So it's best to not include them in the code.
More about your oAuth secret key here.
Answer 2
It is not loaded to any application by default. What you're doing is just saving the information to a file called .env. You then have to configure one of your applications to load environmental variables from it, probably using a library(how laravel does it, how you can load .env files in nuxt.js.
In your case, the Nuxt app does not need to have access to that secret so there is no need to load it there.
Note that you will have to use .gitignore or an equivelant to your source-control system in order to prevent the .env file from being uploaded to a remote and avoid the problems of answer 1.

Resources