Запрос к данным firestore возвращает учетные данные базы данных вместо коллекции или документа - PullRequest
1 голос
/ 11 июля 2020

Когда я запрашиваю данные из своего приложения JS Nest, я получаю объект JSON, который, кажется, состоит из всего, что связано с моей базой данных, кроме данных, которые я запрашиваю. У меня есть закрытый ключ, версия firestore, время его создания и все такое. Я не только хочу знать, как исправить эту проблему, но я хочу знать, как предотвратить запрос текущих результатов так, как я их запрашиваю, потому что я полагаю, что кто-то может легко взломать мою базу данных таким образом.

Я подключаюсь к базе данных, используя метод, описанный на страницах do c, который является кодом ниже.

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();
    
  }

В моем контроллере Nest JS у меня есть эта функция, которая отправляет запрос функции 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":******
    }
}

Что я делаю здесь не так с тем, как я вызываю свои данные, и как я могу убедиться, что могу защитить себя от того, что кто-то может просто сделать тот же запрос, чтобы получить мои учетные данные?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2020

Если подумать об этом сейчас, имеет смысл, что объект моментального снимка содержит учетные данные, поскольку он должен иметь возможность самостоятельно запрашивать Firestore. Но передача этой информации злоумышленнику может иметь фатальные последствия, поскольку он получит доступ администратора к вашему проекту Firebase.

У меня нет четкого мнения о том, как этого избежать. А пока я думаю, что я go использую эту простую функцию, которая должна предотвратить худший сценарий, даже если все другие меры предосторожности не сработают.

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))
})
0 голосов
/ 11 июля 2020

Вы возвращаете вызывающей стороне весь DocumentSnapshot объект . Помимо данных из вашего документа, он содержит некоторые метаданные publi c и некоторую внутреннюю информацию, как вы видите в возвращаемом значении. При быстром сканировании эта информация не является секретной, но даже в этом случае я согласен, что нет необходимости возвращать ее сюда.

Вы захотите выборочно вернуть информацию из DocumentSnapshot. По крайней мере, это будет DocumentSnapshot.data, но посмотрите документацию по DocumentSnapshot классу , чтобы узнать, нужно ли вашим клиентам больше.

...