Many code examples suggest to use token cache provided by msal to cache the access token and to take advantage of the nice feature that msal can silently acquiring token. But how does msal protect the access token in cache? Is it safe or can it be easily hacked?
Thanks you in advance.
The security of the cache depends on which token cache you use, generally dictated by your application's scenario. I'll focus on MSAL.NET from here but similar concepts apply to the libraries in other languages and environments.
In .NET web apps and APIs, there are several options available including in-memory and distributed caches such as Redis, SQL Server, Cosmos DB, or a custom solution. In-memory caching is only accessible from the same process. For distributed caches, it is the responsibility of the developer to protect these data sources from unauthorized access and instrument them to detect when a security breach has occurred.
In .NET desktop and mobile apps, token caching uses OS-specific tools for encrypting and storing tokens. How access is granted to tokens stored in these are OS-specific.
In all cases (except mobile), you can write your own, custom token serialization and caching mechanism. I don't recommend this for all but the most advanced scenarios.
Related
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.
We have a Azure APIM gateway where we are integrating 100s of different API for other teams. We have two clients mobile and web and with user token we will be calling Azure APIs and before calling 100s of API we generate on behalf of user token. We would like improve performance by caching all 100s of on behalf of user token per user in external redis cache . Would like to know is there any better way to do this?
In this advanced token cache sample, we cover a similar scenario of sharing the same external token cache with multiple applications, including background services that don't have user interactions but still can use the users token cached.
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.
Getting a bit lost in the diverse documentation endpoints (here, here, to name a few…)
This one is pretty usable for a given account by providing a json key as an environment variable.
The thing is, I just don't see how commands can be run on the behalf of a user authenticated via oauth — practically speaking, where do you specify the oauth user token ?
Thanks for sharing this insight
Best
google-cloud-ruby (which you linked in your question) is designed to provide access via service account credentials, as you noted. For help with "lower-level" access in which you managing your own OAuth tokens, you might consider google-auth-library-ruby. However, if you can use a service account instead of a user account to use the higher-level access provided by google-cloud-ruby, I believe it's probably the best approach, as recommended in Google Cloud Storage Authentication:
Due to the complexity of managing and refreshing access tokens and the security risk when dealing directly with cryptographic applications, we strongly encourage you to use a verified client library.
what is the purpose of enabling API in the Google developer console? Is it just for monitoring / fees / etc? If an app is using OAuth 2.0, you can tell from the token the identity of the app so you can just monitor that way. What is the purpose of this additional step?
Thank you for your help.
As you've already mentioned, it is for monitoring traffic, enforcing quota, and handling billing. An application does not necessarily have to use an OAuth 2.0 token to access Google APIs though. There are cases where when accessing APIs that do not require user data, API keys can be used instead. It also would not make sense to simply have all APIs enabled, as it is more reasonable to only activate the ones you need.