환경 변수를 통해 비밀을 전달하는 것이 "매우 안전하지 않은" 것으로 간주되는 이유는 무엇입니까?

환경 변수를 통해 비밀을 전달하는 것이 "매우 안전하지 않은" 것으로 간주되는 이유는 무엇입니까?

환경 변수를 통해 프로그램에 비밀(비밀번호)을 전달하는 것은 다음과 같이 "매우 안전하지 않은" 것으로 간주됩니다.MySQL 문서(보안 관점에서) 좋지 않은 선택입니다.기타 리소스.

왜인지 궁금합니다. 내가 무엇을 놓치고 있는 걸까요? 언급된 MySQL 매뉴얼(저는 이것을 예시로 사용하고 있습니다)에서 -p명령줄의 옵션을 통해 비밀번호를 전달하는 것은 "불안정"그리고 환경 변수를 다음과 같이 전달합니다"극도로 불안함”, 굵은 이탤릭체.

나는 전문가는 아니지만 기본 사항은 알고 있습니다. ps권한이 없는 사용자가 실행한 경우에도 간단한 명령은 모든 프로그램과 명령 인수를 읽습니다.그리고 동일한 사용자만(물론 루트도) 프로세스 환경을 읽을 수 있습니다. 따라서 프로세스가 시작된 환경만 root읽을 수 있는 반면, 해커 스크립트는 모든 것을 읽습니다 .johndoejohndoewww-dataps

여기에 내가 놓친 뭔가 큰 것이 있을 것입니다. 그렇다면 내가 놓친 것이 무엇인지 설명해 주시겠습니까?

내 목표는 일반적으로 비대화형 방식으로 한 프로그램에서 다른 프로그램으로 비밀을 전송하는 방법을 찾는 것입니다.

답변1

매우 안전하지 않으므로 사용해서는 안 됩니다.ps의 일부 버전에는 실행 중인 프로세스의 환경을 표시하는 옵션이 포함되어 있습니다. 일부 시스템에서는 MYSQL_PWD를 설정하면 ps를 실행하는 다른 사용자에게 비밀번호가 노출됩니다.


이건 설명됐어여기(통과하다):

배경: 이 과정에서 이미지 argv[]와 envp[]는 같은 방식으로 나란히 저장됩니다. "클래식" UNIX에서 /usr/bin/ps는 일반적으로 setgid "kmem"(또는 유사한 그룹)이며, 이를 통해 활성 프로세스에 대한 정보를 읽기 위해 /dev/kmem을 파헤칠 수 있습니다. 여기에는 시스템에 있는 모든 사용자의 프로세스 매개변수와 환경을 읽는 기능이 포함됩니다.

이러한 "권한이 있는 ps 해킹"은 기본적으로 요즘 과거의 일입니다. UNIX 시스템은 모두 이러한 정보를 쿼리하는 다양한 방법(Linux의 /proc 등)을 제시하며, 내 생각에 그들 모두(?)는 프로세스의 환경은 해당 uid로만 읽기에 액세스할 수 있습니다. 따라서 환경 내 비밀번호 등 보안에 민감한 데이터는 유출되지 않습니다.

그러나 기존 방식이 100% 사라지는 것은 아닙니다. 예를 들어, 다음은 제가 액세스할 수 있는 AIX 5.2 시스템에서 루트가 아닌 사용자로 실행되는 예입니다.

[AIX 5.2는 2009년에 수명이 종료되었습니다. AIX(최소 6100-09 이상) 및 7.2에서 확인되어 이제 루트가 아닌 사용자가 "ps ewwwax" 명령을 사용하여 다른 사용자의 프로세스 환경을 볼 수 없습니다. ]

...

기록에 따르면, 우리는 얼마 전에 OpenBSD 5.2에 다른 로컬 사용자에게 환경을 노출시키는 보안 취약점이 있다는 사실을 (IRC에서) 발견했습니다(그러나 이 문제는 출시 직후 수정되었습니다).

[2012년 출시된 OpenBSD 5.2]

이것은 MySQL 매뉴얼에서 환경 변수를 사용하는 것이 왜 생각되는지 설명하지 않습니다.극도로명령줄 매개변수에 비해 안전하지 않습니다. 이 질문에 대한 다른 답변을 참조하세요. 간단히 말해서, 매뉴얼이 혼란스럽거나 환경 변수가 실수로 너무 쉽게 "유출"됩니다.

답변2

MySQL 문서의 이 조언은 잘못된 표현입니다.

반대로, 환경 변수에 비밀번호를 전달하는 것은 명령줄에 비밀번호를 전달하는 것보다 더 안전하지 않습니다. 대부분의 최신 unices는 ps명령 및 기타 유사한 소프트웨어를 통해 모든 사용자에게 프로세스의 명령줄 매개변수를 노출하지만 해당 환경은 노출하지 않습니다. 예외도 있지만 그 반대(환경은 노출하지만 매개변수는 노출하지 않음)를 수행하는 시스템에 대해서는 들어본 적이 없습니다.

대화형 쉘에 입력하는 명령에 비밀번호를 포함시키는 것은 좋지 않습니다. 왜냐하면 비밀번호는 결국 쉘 기록에 나타나기 때문입니다. 쉘 기록을 꺼도 괜찮지만 그렇게 해야 한다는 것을 기억해야 합니다. 이는 비밀번호가 매개변수로 전달되거나 환경에 전달되는지 여부에 따라 적용됩니다.

환경 변수는 변수가 다른 프로세스로 전달되면 더 위험합니다. 예를 들어, 데이터베이스 비밀번호를 설정하는 것은 .profile모든 프로그램에 표시되므로 매우 나쁜 생각입니다. 또한 export MYSQL_PWD=…해당 범위 밖의 많은 명령을 실행하는 스크립트를 상단 근처에서 실행하는 mysql것은 좋지 않습니다 . 그러나 환경 변수가 mysql명령에만 전달되면 문제가 없습니다.

MySQL 문서에서는 환경 변수를 통해 비밀번호를 전달하는 것이 명령줄 매개변수를 통해 비밀번호를 전달하는 것보다 덜 안전하다고 간주하는 언어를 사용해서는 안 됩니다. 정반대. (환경 설정이 mysql명령 범위를 벗어나지 않는 한, 문서에 설명된 시나리오는 아닙니다.)

답변3

환경 변수에 비밀을 전달할 때의 주요 문제는 해당 환경의 범위를 비밀을 사용하는 프로세스로 적절하게 지정하고 비밀이 없어야 하는 프로세스에 제공하지 않는 것입니다.

해당 환경 변수를 사용하는 특정 프로세스를 시작하기 위해서만 환경 변수를 설정하는 것이 안전합니다.

그러나 셸의 전역 환경(현재 세션에 대해)에서 비밀을 설정하는 것은 안전하지 않습니다(셸의 ​​전역 시작 파일( .bash_profile, .bashrc, .profile)에서는 더 나쁩니다). 왜냐하면 해당 셸에서 시작된 모든 프로세스는 해당 프로세스에 이 비밀을 갖기 때문입니다. 비밀의. 환경. 일부는 의도적으로(악성 프로그램) 또는 의도하지 않게(셸 명령 기록 또는 환경의 전체 내용을 로그 파일이나 원격 서버의 충돌 보고 모듈에 덤프하는 것을 생각해 보세요) 유출할 수 있습니다.

불행하게도 애플리케이션 개발자의 관점에서는 애플리케이션 사용자가 환경 범위를 올바르게 지정하도록 강제하는 것은 불가능합니다. 나는 그 안에 너무나 많은 비밀이 담겨 있다는 것을 내 눈으로 직접 보았다 ~/.profile.

따라서 사용자가 환경을 잘못 사용하는 것을 방지하려면 환경에 직접 암호를 로드하는 것이 아니라(누출의 영향을 줄이기 위해) 환경 변수를 사용하여 암호가 실제로 저장된 위치에 대한 링크를 전달하는 것이 더 안전합니다. 간접지정의 추가 레이어.

답변4

다음 시나리오를 고려하십시오.

  • php/ruby/whatever + mysql 애플리케이션을 구축했습니다.
  • 귀하의 응용 프로그램/서버에서 오류 500이 발생하도록 했습니다. 특정 구성은 내 브라우저에 ENV 및 모든 종류의 스택 추적을 생성합니다.
  • 나는 재미와 이익을 위해 비밀리에 mysql이나 smtp를 사용합니다.

또한 이것에 대해 생각해보십시오:

  • apache/nginx 폴더를 올바르게 구성하지 못했지만 .env 파일 자체에 액세스할 수 있었습니다.
  • 다시 말하지만, 저는 재미와 이익을 위해 mysql이나 smtp 비밀을 사용합니다.

결론: 비밀 공급자를 사용하십시오(사용하기 쉽고 비용이 많이 들지 않음). 그러나 감당할 수 없는 경우 웹 서버 공개와 같은 설정의 다른 측면에서 최대 보안을 올바르게 설정했는지 확인하십시오. .env 파일 또는 env 변수 공개.

관련 정보