[javascript] Firebase apiKey를 공개하는 것이 안전합니까?

중포 기지 웹 응용 프로그램 가이드는 내가 주어진 놓아야 상태 apiKey중포 기지를 초기화 내 HTML에서 :

// TODO: Replace with your project's customized code snippet
<script src="https://www.gstatic.com/firebasejs/3.0.2/firebase.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: '<your-api-key>',
    authDomain: '<your-auth-domain>',
    databaseURL: '<your-database-url>',
    storageBucket: '<your-storage-bucket>'
  };
  firebase.initializeApp(config);
</script>

이렇게함으로써 apiKey모든 방문자에게 노출됩니다. 그 열쇠의 목적은 무엇이며 실제로 공개되어야 하는가?



답변

이 구성 스 니펫의 apiKey는 Google 서버에서 Firebase 프로젝트를 식별합니다. 누군가가 그것을 아는 것은 보안 위험이 아닙니다. 실제로 Firebase 프로젝트와 상호 작용하려면이를 알아야합니다. Firebase를 백엔드로 사용하는 모든 iOS 및 Android 앱에도 이와 동일한 구성 데이터가 포함됩니다.

그런 의미에서 동일한 스 니펫에서 프로젝트와 연관된 백엔드 데이터베이스를 식별하는 데이터베이스 URL과 매우 유사합니다 https://<app-id>.firebaseio.com. 이것이 보안 위험이 아닌 이유에 대한이 질문을 참조하십시오. Firebase 데이터 수정을 제한하는 방법은 무엇입니까? 승인 된 사용자 만 백엔드 서비스에 액세스 할 수 있도록 Firebase 서버 측 보안 규칙 사용을 포함하여

Firebase 백엔드 서비스에 대한 모든 데이터 액세스를 보호하는 방법을 배우려면 Firebase 보안 규칙 설명서를 참조하십시오 .


이 구성 데이터를 버전 관리에 커밋 할 위험을 줄이려면 Firebase 호스팅SDK 자동 구성을 사용해보십시오 . 키는 여전히 같은 형식으로 브라우저에 표시되지만 더 이상 코드에 하드 코딩되지 않습니다.


답변

prufrofro와 프랭크 반 Puffelen의 답변을 바탕 여기 , 내가 함께 긁어 방지하지 않지만, 약간 어렵게 API 키를 사용하여 만들 수 있습니다이 설정을 넣어.

경고 : 이 방법을 사용하더라도 데이터를 얻으려면 Chrome에서 JS 콘솔을 열고 다음을 입력하십시오.

firebase.database().ref("/get/all/the/data").once("value", function (data) {
    console.log(data.val());
});

데이터베이스 보안 규칙 만이 데이터를 보호 할 수 있습니다.

그럼에도 불구하고 프로덕션 API 키 사용을 다음과 같이 도메인 이름으로 제한했습니다.

  1. https://console.developers.google.com/apis
  2. Firebase 프로젝트를 선택하십시오
  3. 신임장
  4. API 키에서 브라우저 키를 선택하십시오. ‘ 브라우저 키 (Google 서비스에서 자동 생성)
  5. 년은 ” 이러한 HTTP 리퍼러의 요청 허용 (웹 사이트) 앱 URL을 추가, (exemple를 :” projectname.firebaseapp.com/*)

이제 앱은이 특정 도메인 이름에서만 작동합니다. 그래서 로컬 호스트 개발을 위해 비공개로 될 또 다른 API 키를 만들었습니다.

  1. 신임 정보 작성> API 키를 클릭하십시오.

Emmanuel Campos가 언급 한대로 기본적으로 Firebase는 화이트리스트 localhost및 Firebase 호스팅 도메인 만 허용 합니다 .


실수로 잘못된 API 키를 게시하지 않도록하기 위해 다음 방법 중 하나를 사용하여 프로덕션에서 더 제한된 키를 자동으로 사용합니다.

Create-React-App 설정

에서 /env.development:

REACT_APP_API_KEY=###dev-key###

에서 /env.production:

REACT_APP_API_KEY=###public-key###

/src/index.js

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  // ... 
};

Webpack에 대한 나의 이전 설정 :

Webpack을 사용하여 프로덕션 앱을 빌드하고 index.html평소처럼 개발자 API 키를 내부에 넣습니다 . 그런 다음 webpack.production.config.js파일 내 index.html에서 프로덕션 빌드에 복사 할 때마다 키를 바꿉니다.

plugins: [
    new CopyWebpackPlugin([
      {
        transform: function(content, path) {
          return content.toString().replace("###dev-key###", "###public-key###");
        },
        from: './index.html'
      }
    ])
  ]


답변

보안 / 구성 키를 클라이언트에 노출 시키지는 않습니다. 누군가 개인 정보를 훔칠 수 있기 때문에 누군가가 과도한 요청을하고 할당량을 소진하고 Google에 많은 돈을 빚을 수 있기 때문에 안전한 것으로 생각하지 않습니다.

사람들이 의도하지 않은 위치, DOS 공격 등에 액세스하지 못하도록 제한하는 많은 개념에 대해 생각해야합니다.

나는 클라이언트가 먼저 웹 서버에 충돌하는 것을 더 선호합니다. 거기에서 방화벽, 보안 문자, 클라우드 플레어, 클라이언트와 서버 사이 또는 서버와 파이어베이스 사이에 사용자 지정 보안을 배치하면 좋습니다. 최소한 의심스러운 활동이 firebase에 도달하기 전에 먼저 중지 할 수 있습니다. 훨씬 더 융통성이 있습니다.

내부 사용을 위해 클라이언트 기반 구성을 사용하는 좋은 사용 시나리오가 하나만 보입니다. 예를 들어 내부 도메인이 있고 외부인이 액세스 할 수없는 것이 확실하므로 브라우저-> firebase 유형과 같은 환경을 설정할 수 있습니다.


답변

데이터베이스 규칙이 정확하게 작성되면 데이터를 보호하기에 충분하다고 생각합니다. 또한 데이터베이스를 적절하게 구성하기 위해 따라야 할 지침이 있습니다. 예를 들어, 사용자 아래에 UID 노드를 만들고 그 아래에 모든 정보를 넣습니다. 그런 다음 아래와 같이 간단한 데이터베이스 규칙을 구현해야합니다.

  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid",
        ".write": "auth != null && auth.uid == $uid"
      }
    }
  }
}

다른 사용자는 다른 사용자의 데이터를 읽을 수 없으며 도메인 정책은 다른 도메인에서 오는 요청을 제한합니다. Firebase 보안 규칙 에서 자세한 내용을 읽을 수 있습니다


답변

사용자 / 암호 가입이 활성화되면 API 키 노출로 인해 취약점이 발생합니다. API 키를 사용하여 누구나 새 사용자 계정을 만들 수있는 공개 API 엔드 포인트가 있습니다. 그런 다음이 새 계정을 사용하여 Firebase Auth 보호 앱에 로그인하거나 SDK를 사용하여 사용자 / 패스로 인증하고 쿼리를 실행할 수 있습니다.

나는 이것을 구글에보고했지만 그들이 의도 한대로 작동한다고 말합니다.

사용자 / 암호 계정을 비활성화 할 수없는 경우 다음을 수행해야합니다. 클라우드 기능을 생성하여 새 사용자를 자동으로 비활성화합니다. 액세스를 관리 할 새 DB 항목을 생성하고 생성합니다.

예 : MyUsers / {userId} / 액세스 : 0

exports.addUser = functions.auth.user().onCreate(onAddUser);
exports.deleteUser = functions.auth.user().onDelete(onDeleteUser);

액세스> 1 인 사용자에 대한 읽기만 허용하도록 규칙을 업데이트하십시오.

오프 리스너에서 리스너 기능은 계정을 충분히 빨리 비활성화하지 않으므로 읽기 규칙으로 인해 데이터를 읽을 수 없습니다.


답변

이 내용을 읽은 후 가능성에 대해 조사한 후 권한이없는 사용자의 데이터 사용을 제한하는 약간 다른 접근 방식을 찾았습니다.

사용자도 DB에 저장하고 프로필 데이터를 저장합니다. 그래서 나는 다음과 같이 db 규칙을 설정했다.

".read": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()",
".write": "auth != null && root.child('/userdata/'+auth.uid+'/userRole').exists()"

이렇게하면 이전에 저장된 사용자 만 DB에 새 사용자를 추가 할 수 있으므로 계정이없는 사람은 DB에서 작업을 수행 할 수 없습니다. 또한 사용자에게 특별한 역할이 있고 관리자 또는 해당 사용자 만 편집 할 수있는 경우에만 새 사용자를 추가 할 수 있습니다.

"userdata": {
  "$userId": {
    ".write": "$userId === auth.uid || root.child('/userdata/'+auth.uid+'/userRole').val() === 'superadmin'",
   ...


답변

이 정보를 노출해서는 안됩니다. 공개, 특히 API 키. 개인 정보 유출로 이어질 수 있습니다.

웹 사이트를 공개하기 전에 숨겨야합니다. 두 가지 이상의 방법으로 할 수 있습니다

  1. 복잡한 코딩 / 숨김
  2. Firebase SDK 코드를 웹 사이트 나 앱 하단에두면 Firebase가 자동으로 모든 작업을 수행합니다. 어디서나 API 키를 넣을 필요가 없습니다.