首页 > 解决方案 > 对 Firestore 数据的查询返回数据库凭据而不是集合或文档

问题描述

当我从我的 NestJS 应用程序查询数据时,我得到一个 JSON 对象,它似乎包含关于我的数据库的所有内容,除了我正在查询的数据。我有我的私钥,firestore 版本,它的创建时间,各种各样的东西。我不仅想知道如何纠正这个问题,还想知道如何防止以我查询的方式查询当前结果,因为我想有人可以通过这种方式轻松破解我的数据库。

我使用文档页面中概述的方法连接到数据库,该方法是下面的代码。

const admin = require("firebase-admin");

const serviceAccount = require("../path_to_my_file");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "link_to_database"
});

const db = admin.firestore();

firebase serve --only functions我像这样在我的服务文件中运行并进行查询

async getSampleData(){
    const dataFetcher = db.collection('product_index_list').doc('golden_ratio_dividers');

    return await dataFetcher.get();
    
  }

在我的 NestJS 控制器中,我有这个函数,它将请求发送到getSampleData()服务中的函数。

@Get('get-sample-data')
getSampleData(){ return this.appService.getSampleData(); }

因此,当我导航到localhost:3333/api/get-sample-data以下对象时,我删除了所有值

{
    "_fieldsProto":{
        "title":{
            "stringValue":"Golden Ratio Dividers",
            "valueType":"stringValue"
        }
    },
    "_ref":{
        "_firestore":{
            "_settings":{
                "credentials":{
                    "private_key":"******",
                    "client_email":"***"
                },
                "projectId":"***",
                "firebaseVersion":"***",
                "libName":"****",
                "libVersion":"***",
                "servicePath":"****",
                "port":******,
                "clientConfig":{},
                "scopes":["*****","****"]
            },
            "_settingsFrozen":*****,
            "_serializer":{
                "allowUndefined":***
            },
            "_projectId":"*****",
            "registeredListenersCount":***,
            "_lastSuccessfulRequest":********,
            "_backoffSettings":{
                "initialDelayMs":****,
                "maxDelayMs":****,
                "backoffFactor":****
            },
            "_preferTransactions":****,
            "_clientPool":{
                "concurrentOperationLimit":****,
                "maxIdleClients":***,
                "activeClients":{},
                "terminated":****,
                "terminateDeferred":{
                    "promise":{}
                }
            }
        },
        "_path":{
            "segments":["*****","******"]
        },
        "_converter":{}
    },
    "_serializer":{
        "allowUndefined":****
    },
    "_readTime":{
        "_seconds":****,
        "_nanoseconds"****
    },
    "_createTime":{
        "_seconds":******,
        "_nanoseconds":******
    },
    "_updateTime":{
        "_seconds":*****,
        "_nanoseconds":******
    }
}

我在调用我的数据的方式上做错了什么,我如何确保我可以防止有人能够提出同样的请求来获取我的凭据?

标签: javascripttypescriptgoogle-cloud-firestorenestjs

解决方案


现在考虑一下,快照对象拥有凭据是有道理的,因为它需要能够自行查询 Firestore。但是将此信息泄露给恶意用户可能会产生致命的后果,因为他们将获得对您的 Firebase 项目的管理员访问权限。

我对如何防止这种情况发生没有明确的意见。现在我想我会使用这个简单的功能,即使所有其他预防措施都失败了,它也应该可以防止最坏的情况。

import * as express from 'express'
function addValidation(this: any, res: express.Response) {
  const originalSend = res.send
  res.send = function (response: any): express.Response {
    if (response && response._firestore) {
      return res.status(500).send({ error: 'FATAL: Attempt to send an invalid response' })
    } else {
    return originalSend.bind(this)(response)
    }
  }
}

function sendResponseSafe(res: express.Response, callback: () => Promise<void>) {
  addValidation(res)
  callback()
}

export const getUser = functions.https.onRequest(function (req, res) {
  return sendResponseSafe(res, () => _getUser(req, res))
})

推荐阅读