After reading several topics about this, I tried to put my API URL in gradle as BuildConfigField, but when I decompile it, I was able to see.
Is there any current way to hide it now?
Use a secret manager service as Hashicorp Vault or AWS Secret manager
From AWS Secret manager page:
The service enables you to easily rotate, manage, and retrieve database credentials, API keys, and other secrets throughout their lifecycle. Users and applications retrieve secrets with a call to Secrets Manager APIs, eliminating the need to hardcode sensitive information in plain text
I'm facing the same problem as you now and it looks to be the solution for my use case.
Related
In my app, I need to pass client_id and client_secret to make my API calls.
What is the most secure way of storing client_id and client_secret's on the android app?
I have read about SharedPreferences and I am sure they are not secure. Also read about Keystore but not sure if that is the right approach. Can you please suggest what would be the most secure way of storing such information?
Thanks
R
The best approach is to use Android's Keystore. It will handle the key generation, storage for you. Your app will be communicating through KeyChain API which offers the following advantages:
It performs all the cryptography for you
Hard to extract from device
Each app can only access their own keys (enforced by Keystore)
Securing the user's secrets in a keychain
Mobile OAuth Authorization flow
In my app, I need to pass client_id and client_secret to make my API calls.
It seems to me that you are not using the correct OAuth authorization flow in your mobile app because the one you are using now requires the client_secret. I think you may be trying to use the flow meant for m2m(machine to machine) authorization.
The correct flow to use for a mobile app is the Authorization Code Flow with Proof Key for Code Exchange (PKCE).
From auth0.com/docs:
The PKCE-enhanced Authorization Code Flow introduces a secret created by the calling application that can be verified by the authorization server; this secret is called the Code Verifier. Additionally, the calling app creates a transform value of the Code Verifier called the Code Challenge and sends this value over HTTPS to retrieve an Authorization Code. This way, a malicious attacker can only intercept the Authorization Code, and they cannot exchange it for a token without the Code Verifier.
You can read that this is the recommended approach in the OAuth 2.0 RFC8252 for Native Apps, that is about the best practices for mobile apps:
Abstract
OAuth 2.0 authorization requests from native apps should only be made
through external user-agents, primarily the user's browser. This
specification details the security and usability reasons why this is
the case and how native apps and authorization servers can implement
this best practice.
Status of This Memo
This memo documents an Internet Best Current Practice.
This document is a product of the Internet Engineering Task Force
(IETF). It represents the consensus of the IETF community. It has
received public review and has been approved for publication by the
Internet Engineering Steering Group (IESG). Further information on
BCPs is available in Section 2 of RFC 7841.
Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
https://www.rfc-editor.org/info/rfc8252.
Securely storing secrets in the mobile app
What is the most secure way of storing client_id and client_secret's on the android app?
Also read about Keystore but not sure if that is the right approach. Can you please suggest what would be the most secure way of storing such information?
Yes, the Android Keystore is the correct way to go. You can use it from the Android Security Library to store your secrets but bear in mind that an attacker can use an instrumentation framework to hook at runtime into the code that uses the client_id and client_secret already decrypted and extract them for use outside of your mobile app. A popular instrumentation framework used for this propose is Frida:
Inject your own scripts into black-box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
I invite you to read my answer to the question Store Client Certificate and key (.pem) in Android securely to see more details about using the Android Keystore with the security library, and the answer includes some code examples.
Do You Want To Go The Extra Mile?
In any response to a security question I always like to reference the excellent work from the OWASP foundation:
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
OWASP - Mobile Security Testing Guide:
The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.
There are lots of questions and articles on how to do this with .NET, but how/is it possible to easily authenticate for local development through Azure AD shared secret credential using Java (Spring Boot specifically)?
For .NET, it is as easy as specifying the RunAs=CurrentUser property in the connection string to connect to the Azure Key Vault (per this article: https://learn.microsoft.com/en-us/azure/key-vault/service-to-service-authentication), connecting automatically (assuming my account is listed in the access policy for the key vault I want to access). Ideally, I would not want to use a thousand Java dependencies to do this, I could manually obtain a token to authenticate, but it would be nice to save developers the hassle of having to manually obtain a token from Azure every time we wanted to test things for local development.
Thanks!
Here is an example os using MSICredentials Read Azure key vault secret through MSI in Java
Just try using the AzureCliCredentials instead https://azure.github.io/azure-sdk-for-java/com/microsoft/azure/credentials/AzureCliCredentials.html
The question is how can I set application secrets to make them available in application.yml?
On heroku I was doing it simply, by setting environment variable for dyno, and acces it as:
server:
port: ${PORT}
security:
user:
password: ${USERPASSWORD}
eureka:
client:
register-with-eureka: false
fetch-registry: false
instance:
hostname: localhost
securePortEnabled: true
password: ${EUREKAPASSWORD}
How to achieve that in Google App Engine? I was trying with datastore:
Unfornately I don't know how to inject those values into my *.yml file.
EDIT:
One more important thing to add. I am using maven appengine plugin to deploy my app via CI pipeline, so there is no possibility for me to push app.yaml file to App Engine
If you want to store secrets that are available to the app at runtime, keeping them in the datastore isn't a bad idea. I know of many apps that do that.
Here's an app used by the Khan Academy that's a good example of storing secret credentials in the datastore. It's in Python, but you can get the general idea. Note that on first admin login, it prompts for secrets to store.
Google has also a tutorial on how to store encrypted secrets.
https://cloud.google.com/kms/docs/store-secrets
TLDR: a separate bucket to store the encrypted secrets, instances download it when needed, decrypt using Google KMS (https://cloud.google.com/kms/) and remove afterwards.
The best and secure way is to use GCP KMS or some third party secrets manager product like vault.
GCP KMS
We need to use a service account with encrypt and decrypt permission(role) to encrypt the credentials(secrets) file.
Upload the encrypted credential file to GCS
Fetch the encrypted credential from GCS and decrypt and parse it(E.g. parse to plain java object) at runtime in your application code.
Datastore
Yes. We can store credentials/secrets environment variables into datastore and fetch them at runtime in application code.
Pros:
Simple
It can be used almost everywhere, GAE standard environment, GAE flexible environment, GCE, GCF, GKE, Cloud Run.
Cons:
Security is not as good as KMS.
GCE metadata
I used to use GCE metadata server to store my secret environment variables.
Pros:
It supports GAE, GCE, GKE.
Very simple. We just need to send HTTP requests to http://metadata.google.internal/computeMetadata/v1/ endpoint to fetch our custom metadatas(the secrets environment variables).
Cons:
Last year, GCE metadata doesn't support Cloud Function. (runtime: nodejs10).I can't fetch my custom secrets environment variables from GCE metadata within cloud function. But built-in metadatas can be fetched, like projectId.
security is not as good as KMS.
configmap and secrets(Only for GKE)
Simple base64 encryption is possible. Medium difficulty to use. Security is not as good as KMS.
Another hack way
I also create a post for this question here: How to pass system environment variables to app.yaml?
Yes, the Linux script way can do everything. But I don't like these hack way.
I am trying to create a prototype using Firebase on AppEngine, and I keep hitting the 9-hour quota as described here: https://cloud.google.com/solutions/mobile/firebase-app-engine-android-studio#configuring_the_app_engine_backend_to_use_manual_scaling
The doc states the following:
To use Firebase with App Engine standard environment, you must use manual scaling. This is because Firebase uses background threads to listen for changes and App Engine standard environment allows long-lived background threads only on manually scaled backend instances.
I am just using Firebase Authentication and Need to verify the clients hitting my app engine endpoints which I do using Firebase Admin SDK. so does it still need to spawn threads to listen for changes? Is there a way to configure Firebase to not need these background threads, and therefore, not need manual scaling?
OR is there any other easy way to Do OAUTH custom authentication for anonymous & different social providers ?
yes you can use the Firebase Authentication without using Backend Instances. You need to use Java Admin SDK 4.0.4. then you can run an automatic scaling instance (Frontend Instance)
Please see the following post
Verify Firebase Token at Google App Engine
You do not need manual scaling to use Firebase Authentication with App Engine standard environment applications.
This tutorial is for Python, but the pattern and flow would be the same for Java. The overall flow would be similar in that you'd trigger on the client side your authorization flow, the user would choose from your allowed auth providers, Firebase would return the JWT token to your front-end script, you would send that token to your backend where you would decode it using the Firebase certificates and exchange it for your auth tokens.
From that tutorial, the client-side HTML and Javascript would be identical for you. You would just need to recreate the backend logic for Java.
Again, the automatic scaling instances would work just fine for you.
We have mobile application backend running in AWS. Backend build using Java spring front end supported for native iOS, native Android and angular js based website, it has own authentication using email id and password. Now we are planning to integrate our app authentication with our organisation Active directory which available in Azure AD.
We have outline idea about Azure portal application creation, use ADAL library to get token from azure. But we are not clear about how we can validate token at web service side. Could you please enlighten us about integration process
Unfortunately, Azure AD doesn't have great guidance on securing a web API in Java at this time. However, taking the open-source approach isn't terribly difficult in this case.
Azure AD's access tokens are JWTs, which are essentially just base64 encoded JSON strings with a signature. jwt.io has compiled a nice list of open-source libraries that can be used to validate JWTs (some libraries for generating them too, fyi). The best reference material available at this time is:
The claims listed in this token reference article where necessary (ignore the comment about id_tokens only, that's incorrect).
The OpenID Connect spec also has some good tidbits on how to validate tokens. You should also make sure to validate the scope claim, which won't be mentioned there.
This code sample shows how to take this approach, but it's in .NET. You can follow its patterns for Java.
The hardest part will be robustly fetching, caching, and refreshing the Azure AD public signing keys, making sure your app can handle key rollover. Microsoft's .NET open source library, for instance, refreshes the keys every 24 hours and refreshes them immediately any time signature validation fails. Most JWT libraries won't do that for you. The signing keys are available via Azure AD's OpenID Connect metadata endpoint,
https://login.microsoftonline.com/<tenant-or-common>/.well-known/openid-configuration
The OpenID Connect spec also has information on the format of the data available there.