How can I hide an API key in a GitHub public repo? - github-pages

I am doing a simple front-end project where I (or a user) make an API call to the openweathermap api, fetch weather info and display it on a website.
Simple HTML, CSS and vanilla JS
So I want to keep the repo public & host the site with GitHub Pages... but my js file contains the API key which is required at runtime.
Extra Info:
(all this I found when I searched)
I know there is a way to keep an API key in a GitHub secret, then reference it in a yml file as an environmental variable in GitHub Actions.
But how can I put that secret in js code at runtime for any user who access my website?

Please note that what you're attempting to do is not secure. Even if there was a way to get GH Pages to inject the secret API key into the js file at the time of the request, every web client would then have a copy of that js file with the cleartext key embedded.
You will need some sort of minimal backend which stores the API key securely and relays calls from your static web page to the openweathermap API.
There are many ways to set up such a backend. The older question linked in the comments discusses some approaches. Note that nowadays, you could use a serverless FaaS service such as AWS Lambda or Azure Functions.
This is a perfectly valid question by the way and you're certainly not "too dumb". Good luck!

Related

Displaying data retrieved through GraphQL in a Django website

(Disclaimer : I'm just getting started with Django, and with web dev in general)
I have a backend app that stores different kinds of resources. Some are public and some are private. The application is accessible only to identified users. A GraphQL API allows me to access the resources.
On another server, I'd like to create a website that will be accessible to everyone. I want to use Django to create it.
The website will display a list of resources tagged as "public" in the backend app, with a pagination system and, say, 20 resources by page. The CSS will differ from the backend app and there will be a search section.
From what I understand, I should be able to retrieve the data through the GraphQL API, but I'm a bit confused here. All the documentation and tutos I can find about Django and GraphQL seem to be about setting up a GraphQL API server with Django. All I want to do is to build custom queries and to display them on my different html pages.
How can I do that? Where should I start?
You should connect your project with a GraphQL client. As per my research, I have found that there are implementations and examples for graphene-mongoengine in Flask (Flask has a direct GraphQL client).
Mongoengine Flask with GraphQL Tutorial
For Django you can check this out
Edit- I was able to get the data from my database with python-graphql-client. Now I am able to display them in my template.
Let me know if this helps

In Squarespace Developer Mode, can one save the AWS CLI SDK to the website's server-side "Home" directory? If so, how?

The Current Situation
My Squarespace website uses client-side, custom JavaScript and JQuery injected into the Head section of a page as well as the Amazon Web Services Command Line Interface SDK. The custom JS, the JQuery and JS Libraries, and the SDK are loaded into the page Head each time the page is loaded.
That Is Objectionable
The SDK uses two predetermined, static, handshake credentials to connect to the AWS server. They are stored in a file, "credentials," in a hidden directory, .aws, created by the SDK when it first loads. At that point, however, they have no values.
The Situation Exposes Supposedly Secret AWS Login Credentials To A Potential Hack
Currently, it is necessary to set their values programmatically when the page loads by executing a CLI "updateConfig" command in the custom JS. The credential values are thus in a plain-text config file client-side.
As such, they are not so secret. Any site visitor who loads the page in his browser could use the browser's developer tools to view the source code and, potentially, discover the supposedly secret credentials thus compromising the security of the AWS account.
One Ought Not Put The Secret Credentials In Client-side JS
For that reason, AWS rather forcefully insists that one not put the credentials in client-side source code. The preferred method is to instantiate the SDK on the server-side and set the credentials one time only. Thereafter, the hidden .aws directory and the credentials file persist server-side at the root level of the website's Home Directory.
The Problem
So the problem is to load the SDK in the server-side Home Directory where it will persist over the site's lifetime.
The Question
The question is on a Squarespace website can one load the SDK server-side at the root level on the site's Home Directory. Can it be done in Developer Mode? How?
Unfortunately, Squarespace doesn't support the use of server-side/back-end code:
You can't add server-side code. Server-side code is handled by a server, not by a browser, and includes:
- PHP
- Ruby
- Ruby on Rails
- SQL
That would also include server-side JavaScript/Node. Because Squarespace only supports the front-end addition of HTML, CSS and Javascript within Code Injection, Code Blocks, and Developer Mode, you need to use front-end JavaScript in order to utilize third-party APIs (which is what you're doing currently).
Enabling Developer Mode only exposes template files for the site. Beyond the JSON-T templating engine, Developer Mode doesn't enable any sort of server-side logic or requests to take place. Therefore, it seems the answer to your question is no.
A potential alternative solution may be to use Google Apps Script or Google Cloud Functions instead, storing the credentials in the code there, and making a front-end request (via JavaScript on your website) to that endpoint in order to perform the handshake and get back the data you need.

YouTube Player API with Exposed GCP API keys

Recently I received this Alert in the Google Play Console
Your app contains exposed Google Cloud Platform (GCP) API keys
I am using the YouTubeApi Player, and I believe the only why you can initialize it is using this line of code
youTubePlayer.initialize(DEVELOPER_KEY, this);
So beside added restrictions to my API key, is there any other way to remove the API Key from the code?
I tried using the GCP service accounts as suggested by Google, but I do not see how I can still use the YouTube Player without the initialize line of code.
I have same problem, and fixed this by using string R.string.google_api_key generated by google_services.json
change your code to:
youTubePlayer.initialize(getString(R.string.google_api_key), this);
how to get google_services.json:
create firebase project https://firebase.google.com/docs/android/setup?hl=id
get your google_services.json https://support.google.com/firebase/answer/7015592?hl=id
There are some tips on how to secure your API keys at Using API Keys documentation.
It is stated that embedding API keys directly in the code should be avoided, which is the way you are having it right now, therefore you are getting the warning message.
Follow the tips on that page and you should properly secure your API key. As soon as you do so, the warning will go away.
UPDATE
To avoid having a long discussion in comments, allow me to elaborate further providing this update.
Google provides different ways of authentications to give you more options for securing your apps based on your needs. The warnings are helpful tips to make your apps more secure when going in production or exposing to public. So in your case, it would be better to use a different way of authentication.
API keys can be used in server side. e.g. If you are using an API key to authenticate a 3rd party service from an App Engine app, you can use this key as you already have it, since it is impossible for the key to get exposed. (Avoid using API keys in JavaScript since inspecting the page in the browser will expose the API key as well)
In your case, since you are developing an Android app and/or an iOS app, having the API key in the code is dangerous. Because, anyone can use the .apk or the .ipa file and find a way to access it. Therefore, for developing Android apps and iOS apps it is suggested going with different authentication method. The other authentication method supported in YouTube player API is using OAuth 2.0. For more information you can check the Registering your application documentation.

Hiding AWS secret from application

I'm a Java backend engineer working on a feature that the frontend (SPA and Android) must send (large) files to S3. Since I have to manage with a lot of requests. Because of network overload reasons I'm avoiding to make a 'proxy' service where the frontend send me the file so that I can send it to S3 but I have some concern about the best way to keep my apps secure.
I looked for some solutions but I cannot find one that manages exactly what I want.
Amazon S3 upload with not showing secret key in frontend
This post has almost my answer but I don't have enough score to comment.
S3 upload directly in JavaScript
I read some documentation on AWS but I still have some questions and some requisites.
The solution may permit the client an authenticated user to send a file to s3 directly
It may make a GET call to get some token or something like that (without sending a lot of data)
It's to be secure (no secret key knowledge at the frontend)
Which solution may be good for me?
The backend may generate a signing key and send it to frontend making the request to AWS (http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html)
I can use STS to generate a temporary credential for each upload.
Do you think these approach will work? Which one do you think is better? What are the trade offs? Is there other way to deal with this problem?
Best thing to do here is use the Cognito service to generate anonymous credentials in the app that allow an upload to S3. For Android you can use the SDK then to do multi-part uploads from the device to S3, which will speed up the process as well.
I couldn't find an exact Android example, but this is one for iOS and the terminology should transfer the same, just with the other SDK: iOSTransferManager .
You can also call Cognito directly from javascript, if you have a web based app: Cognito in JS example
Hope that helps!
- Chris

Authenticating a Google Drive service account owned by a Django app?

I'm new to Django and relatively new to OAuth. I'm building a Django app that's basically aiming to be a wrapper around Google Drive that implements tagging and user permissions. A few users who have important documents share them with the service account, and then the app provides a nice interface.
I'm generally confused about how to organize this, since Django seems to have many, many moving parts.
The app needs to almost constantly be authenticated with and talking to the Google Drive API.
Where does this authentication go? A model? Is it part of a site template that gets inserted on every page?
Here's sample app of integrating Django with OAuth2. You especially want to take a look at this file where it saves user credential using Storage class. There is also a documentation with better explanation about how OAuth flow with Storage works in Django.
To answer your question, you would want to define credential at Django user profile in order to save it easily associated with users. Also, your OAuth flow (creating auth url and authenticating) works at view.