filzfreunde.com

Maximizing Security: Leveraging Firebase Functions with Service Accounts

Written on

Understanding Firebase Functions and Their Risks

Firebase Tools, developed by Google, is a widely used library that simplifies the process of developing and deploying Firebase applications. This toolset is highly recommended for deploying serverless functions to Firebase and Google Cloud, as it operates on top of Google's cloud infrastructure. The Firebase Command Line Interface (CLI) allows developers to manage their Firebase projects directly from the command line, enabling functionalities like:

  • Deploying code and assets to Firebase projects
  • Running a local web server for Firebase Hosting
  • Interacting with Firebase databases
  • Importing and exporting users from Firebase Auth

Over the past two years, I have utilized Firebase to build a web application. Recently, I began integrating Google Cloud's Secret Manager to securely store sensitive information. However, I soon uncovered a critical flaw in the default configuration of firebase-tools, especially concerning how Firebase suggests authenticating in personal and CI/CD environments.

What Went Wrong?

The issue arose while I was setting up a new non-production stage for my application. I created a fresh Google Cloud Project, established new service accounts, and configured new secrets, only to face failures in my CI/CD jobs on GitHub. The testing phase was failing, which meant the deployment process was halted before it even began.

The failure was traced back to the Rest API's inability to connect to the intended in-memory database. The logs indicated that the in-memory database was created successfully, but there was a concerning error message indicating a closed connection to an IP address associated with MongoDB Atlas.

Note from the author: Do not attempt to connect to the MongoDB instance referenced above; I have since terminated it. 🙂

Upon investigating the IP address, I found it was a Google IP, which led me to initially suspect that my CI/CD environment may have been compromised. However, this seemed improbable since there was no sensitive data to exploit.

Reflecting on recent changes, I recalled that I had configured a new non-production stage and utilized Secret Manager to generate secrets in that environment. My CI/CD system referenced the same non-production environment to initiate emulated services, which raised suspicions.

Could it be possible that the emulated services were accessing actual Google Cloud production services, including the Secret Manager? One of the secrets I created contained the database URL, prompting me to enable debug logging to verify the actual database URL being used during the build process.

To my astonishment, the logs revealed that the database URL was indeed stored in Google Cloud's secrets, indicating that the application was not connecting to the local in-memory database but rather to a MongoDB Atlas instance on Google Cloud. This misconfiguration caused the build to fail since the MongoDB Atlas was set to deny all unknown incoming connections.

The Root Cause

Examining the configuration of one of my cloud functions, I noted that it included settings such as ingressSettings, memory, CPU allocation, and attached secrets. Although I intended for the cloud platform to attach secrets to the function at runtime, discovering that these secrets were accessible during CI/CD builds and in emulated environments was unexpected.

This led me to consider whether the CI/CD pipeline was configured to impersonate my identity, thus granting it access to production configurations, including sensitive secrets. A quick review of Firebase's documentation regarding CI/CD authentication confirmed my suspicion.

Firebase suggested using the command npx firebase login:ci to initiate an OAuth 2.0 refresh token, allowing the CI/CD system to have access to my personal Google account, which possessed full administrative rights over the Google Cloud project. This posed a significant security risk.

It would have been less problematic had I used a dedicated account lacking owner permissions for the Google Cloud project. However, creating multiple Google accounts can be impractical, especially as Google monitors account activity.

Why Opt for a Service Account?

A service account is a unique type of account designed for applications or compute workloads, rather than individual users. Managed through Identity and Access Management (IAM), service accounts allow applications to operate with dedicated permissions that are independent of personal accounts.

Utilizing service accounts enables us to restrict access to APIs, allowing for read-only or limited write capabilities. For instance, we can create a service account that permits building applications but not deploying them, or one that can access a database while others are restricted.

Had I employed a service account initially, I could have avoided the confusion and time spent troubleshooting this issue. While no user data was compromised this time, larger organizations could face severe consequences from such vulnerabilities.

Additional Considerations

The challenges outlined above are not exclusive to Firebase functions. Functions lacking dedicated service accounts often have more permissions than necessary, as default service accounts created by various Google Cloud services typically possess excessive permissions. This could lead to significant security breaches if an attacker exploits a vulnerability in your application to disrupt services or gain unauthorized access.

To mitigate such risks, I will provide code snippets demonstrating how to run a Google Cloud Function with a dedicated service account. Additionally, I will follow up with a tutorial on setting up service accounts with Firebase, as the existing documentation is insufficient.

For NodeJS-based Google Cloud Functions, a standard service account can be defined using the setGlobalOptions function from the firebase-functions SDK:

import { defineString } from 'firebase-functions/params'

import { setGlobalOptions } from 'firebase-functions/v2/options'

const gcpCloudRegionParam = defineString("DSQ_GCP_CLOUD_REGION")

setGlobalOptions({

region: [gcpCloudRegionParam],

serviceAccount: cloud-run-functions@${process.env.GCLOUD_PROJECT}.iam.gserviceaccount.com

})

When using the gcloud CLI for deployments, the service account can be specified for v2 Functions using the --run-service-account command line argument:

gcloud functions deploy api

--entry-point=api

—gen2

--run-service-account=cloud-run-functions@${PROJECT}.iam.gserviceaccount.com

—source=.

--trigger-http

Thank you for reading! If you have feedback or further suggestions, feel free to reach out to me on Twitter @stfsy.

The first video titled "5 uses for Cloud Functions | Get to know Cloud Firestore #12 - YouTube" explores various applications of Cloud Functions, demonstrating how they can streamline workflows and enhance application functionality.

The second video, "Build a Serverless API with Firebase Cloud Functions, TypeScript and Firestore - YouTube," provides a comprehensive tutorial on constructing a serverless API, showcasing best practices and essential techniques.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

# Mastering Focus: Transforming Distractions into Productivity

Discover strategies to minimize distractions and enhance productivity, paving the way for personal growth and self-improvement.

# Rethinking Our Relationship with Smartphones and Dumbphones

Explore the impact of smartphones on our lives and the concept of

# 5 Distinct Habits of Optimistic Individuals That Set Them Apart

Explore five key habits of positive individuals that contribute to their longer, healthier lives and enhanced well-being.

Unlocking Extraordinary Productivity: 5 Essential Rules

Discover five essential productivity rules that top achievers use to reach extraordinary results and enhance their effectiveness.

Rethinking Road Safety: The Impact of Warning Signs on Drivers

Research reveals that warning signs can unintentionally increase accident rates on highways, countering their intended purpose.

Understanding Why College Students Struggle with Programming

An exploration of the reasons behind college students' challenges with programming and suggestions for improvement.

Unlocking the Potential of Medium for Content Creators

Discover how to maximize your impact on Medium and potentially earn up to $30,000 as a content creator.

# Exciting App of the Week: Discovering Headway

Dive into the features of Headway, an app designed to enhance your learning and personal growth through bite-sized content.