How to block Google Firestore access from the Google Firestore api - go

I am working with Google Firestore in native mode and CRUD'ing data within it using the "cloud.google.com/go/firestore" api in Go. Access to the data is wide open as long as you know the project id and using the Firestore API on a server. I don't want to try the rules until I figure out how to secure the data from server attacks that. Again, all the API requires is the project id to access the data so I need to lock that down firstly before I move any further. Rules are only for mobile/web clients from what I read and Server side clients completely bypass the rules. Please help. I do not want to use the Firebase API because attackers can still use the Firestore api to access the data.

It's unclear from the limited information in your question but, your Firestore database is not open to anyone with the Project ID.
The service is only accessible to any thing (human|machine) that has valid credentials. Either humans with e.g. Gmail accounts or Service Account key holders.
In either case, only identities that you've explicitly added to the project will be able to access its resources and then only those with the appropriate IAM roles|permissions.
Google provides an elegant facility called Application Default Credentials (ADCs) that simplifies authenticating clients.
I suspect that your code is using ADCs to authenticate you to the project|service.

Access to the data is wide open as long as you know the project id and using the Firestore API on a server.
If that is a concern, consider disallowing all access in the Firebase security rules for your Firestore database.
Also have a look at my answer here to understand why sharing your project ID is not a security concern, and in fact is necessary if you want to allow direct access from client-side devices: Is it safe to expose Firebase apiKey to the public?. If you don't want to allow direct client-side access, closing down the security rules (as they are by default, unless you choose test mode when creating the database) is the way to go.

Related

Saving organization-wide application settings in Teams app

I have a Teams application (Tab). I am an ISV provider, and provide a multi-tenant application that is installed by customers via Teams App Store in their organizations.
How do I save settings for my application organization-wide for the customers? For example, CustomerA has installed the app and then CustomerB. I want some storage that would be unique for CustomerA and CustomerB and the app, and located in customer's environment. The settings I want to save are not per-user, but per-organization (tenant).
Somewhat similar to "App Data" folder you have in Windows Desktop for example.
Does such a storage exist? Does API for this storage exist?
A tab app is a simply a web application that you render inside of Teams. As a result, what the app does, and where and how it does it, is totally up to you. This includes any data storage you choose to have behind the scenes. For example, your tab could be built in PHP and use MySQL, or built in ASP.Net and use SQL Azure or CosmosDB. It's totally up to you, but you need to implement it yourself, as an ISV.
The important piece to differentiate clients, however, is being aware of the TenantId for each user, so you can look up which client's settings you need from the database. The most simple way to do this is simply the tid property on the Teams tab context. You can read more about that here. Unfortunately, because it's just accessed via Javascript, it's not entirely secure - for a more secure mechanism, you should be creating an Azure Application, and generating jwt tokens that you can authenticate against in your backend. It's a much more complex topic, but hopefully this answer at least gives the background you need. For more info on the security aspects (validating the token etc.), please see this question: How to restrict access to Azure Function to only allow requests from a custom Microsoft Teams App?.

AppSync security best practices for 100% public, unauthenticated API's

We are currently deploying to AppSync using the serverless-appsync plugin and the serverless-framework (naturally).
Our API is 100% public and unauthenticated. All queries and mutations are basically public, since we have at this point no need for users (via a Cognito pool for example).
We have added a first layer of security using api keys but this is undoubtedly not much, as the api key is included as-is in the frontend sources. We would like to add extra roadblocks to make it harder for malicious users to abuse that frontend API.
A few things come to mind:
rate limiting (not currently supported by AppSync but I've read it's apparently in the works). I do not want to do this using a custom made solution in a Lambda for example.
making sure only traffic from the website is allowed to use our API, in addition to our own devs... I could probably do this with pipeline resolvers but I am not too keen with doing that in that obscure and unwieldy VTL language.
cors, ...
I'm considering switching to Apollo Server since this solution seems more open and configurable...
I would recommend using AppSync's IAM auth option and then use Amazon Cognito Identity Pools to vend temporary AWS credentials to your client applications. Identity pools (as opposed to user pools) vend temporary AWS credentials that assume the access of a role of your choosing. When configuring the identity pool, you can define a role with full access to the AppSync API or you may selectively provide access. From the client applications, you use the temporary credentials to sign the requests to AppSync using SigV4 and AppSync will only allow requests with a valid signature to be executed. The temporary credentials also provide an extra layer of security as even if they are compromised, each credential will only provide access up to the max allowed time.
I'll also add that you can use multiple auth modes at once with an AppSync API. This allows you to protect all fields as mentioned above and then selectively mark specific other fields such that they are authorized via some other mechanism like user pools or OIDC.

Authentication using Using DIrectMail SDK?

I want to use the Direct Mail SDK(Java) directly within client application which is distributed across. The way to authenticate users within the application, I need to provide access keys as below,
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", "<your accessKey>", "<your accessSecret>");
How can I prevent user to know the Access Keys and still prevent the need of third-party API? Is it possible?
First, it is bad practice to code an application that requires secrets that runs on the client. You should manage everything on the server and provide an API that the client software interfaces with.
Second, there is no way to hide those credentials once passed to the client. You could encrypt the credentials but at some point the client application will need to decrypt them. Even amateur programmers can figure out how you are processing your credentials.
Ignoring the above advice, Alibaba Cloud supports STS which provides temporary access keys. Using your Alibaba credentials, you would call AssumeRole which creates temporary access keys giving the user permission call DirectMail. You can limit the time that the credentials are valid. The range is 900 to 3600 seconds. After that duration the keys become invalid.
Keep in mind that 900 seconds is a long time. A bad actor getting access to those keys could send thousands of emails using your account. Therefore implement strong user authentication, STS and temporary access keys.
If you think that just keeping your interface secret is enough, don't. There are millions of script kiddies on the Internet poking at every IP address. Launch a new ECS instance and you will see attacks within hours.
As you said since it is a Java Web Application(assuming), currently I think of something using similar to JBOSS Vault to store the access keys securely.
If it is some standalone client application still you can use some encryption methodologies to store the data. But this will only prevent easy access to the data/keys. But it is not impossible. The best bet would be creating another third-party API

What is the usage of the client_secrets.json file?

I am working on writing a program using the Google Tasks API in Python. I have downloaded and run the sample application from Google, and it comes with a file called client_secrets.json. I understand that the file is used for OAuth authentication, but my question is should I distribute this file to users? Should I push it to my public source repo? Or is it supposed to be kept secret? If I shouldn't share it, how would other users do the authentication?
Thanks for reading.
The Google API Client Library OAuth2 docs states,
Keep your client secret private. If someone obtains your client
secret, they could use it to consume your quota, incur charges against
your Developers Console project, and request access to user data.
So don't commit or otherwise distribute the file.
If you want to publicly share your application source code, instruct others to use their own Google Developer account to register their own Google Developer project and generate their own app OAuth credentials (client_secrets.json file) for use with their "installation" of the app.
If you were making the application commercially available, you would seemingly need to share the app credentials with them in a trusted, legally protected, or secure manner.
Apparently the client_secrets.json file does not have to be kept secret for installed application. From https://developers.google.com/identity/protocols/OAuth2?csw=1#CS in the "Installed applications" section:
The process results in a client ID and, in some cases, a client secret, which you embed in the source code of your application. (In this context, the client secret is obviously not treated as a secret.)
So if you're making a webapp, keep it secret. If it's a python app that you distribute to users and they run on their own, it does not have to be kept secret.

Best way to handle user authentication across website and gem client

We are working on a service that will have website access for stats and other tasks, but the majority of use will be through a client gem and rake tasks. What is the best way to handle authentication for both pieces.
It looks like fiveruns_tuneup, getexceptional, New Relic and others have websites with username and pass, but use API keys stored in ./config/serviceName.yml Any reasons it is better to have API keys opposed to user/pass in the config (do they use keys because often the key is checked into SCM and used across the project, where ours would not be checked in and would be a per user setting)
GitHub has you put your public key on the github servers and uses that, but I think git supports public/private key by default.
Would it be preferred to keep a ./config/serviceName.yml or since we have to create a subdirectory with other information have ./serviceName/config.yml? (does the per user, not stored in SCM mean it is better to keep it all in one excluded directory?)
Just looking for some thoughts and ideas on best practices before starting implementation.
I recommend that you use username/password combos for website accounts, and API keys for any web services. Here are the advantages of this technique:
By linking API keys to an account, you could have many API keys for the same user. Perhaps this could be used for many remote web servers that consume this data service, or to perform unique tracking.
Attaching API keys to an account also lets you keep the user's username and password uncompromised since an API key will not contain them. Many users use the same username and password on many services, so you are helping to protect them.
You could limit access to portions of functionality for each API key, but give their username access to everything their account should have access to. Additionally, you can even give them the ability to limit how much access an API key might have.
Most of the major services (Yahoo! API, Flickr, Google API, etc) use accounts with a username and password to login to the web account, and API keys for integration points.
Never use user/pass when you can help it. The security issues are horrible. If the user/pass leaks out, you have to change your password or they get access to your whole account.
API keys are better because they're easier to change and can be limited to only the part you need access to with the APIs (ie, if someone has your password they can change your password. They can't if they just have an API key).
Different API key per client or secure token exchange (such as OAuth) is the best solution if you'll have more than just your client on the API.
The github approach is bootstrapping on top of existing git practices, however it's not a bad idea since presumably each user will have their own private key to match a published public one in the central authority. Since key-agent's already furnish a means of safe authentication this seems like a very safe approach. Public/private keys are a well thought out authentication scheme, which has unfortunately been reinvented many times to limited success.
The problem with the API key is that anyone who gets a copy of the API key can do whatever that authorizes. Storing the API key somewhere in the project begs the users to share a key. If you are associating public keys with a user, it is possible to grant rights to the client on a per user basis, and a proper key-agent approach suggests that those will not be stored in an SCM anywhere.
I'm not sure I follow what the distinction between config/serviceName.yml, or serviceName/config.yml is. It doesn't seem as if it would be pertinent if you have public/private keys as an authentication method for the client.

Resources