루비의 변수 "무효화"[중복]

Dec 06 2020

보안상의 이유로 더 이상 필요하지 않은 순간에 일부 데이터를 폐기해야하는 사용 사례가 있습니다.

로그인과 비밀번호를 다루는 Ruby로 서버를 작성하고 있습니다. BCrypt를 사용하여 데이터베이스에 암호를 저장합니다. 내 서버는 암호를 받고 bcrypt 해시를 만든 다음 더 이상 원래 암호를 사용하지 않습니다.

RAM에서 바로 데이터를 훔치는 것과 관련된 일종의 사이버 공격에 대해 알고 있으며, 암호가 아직 메모리에있는 기간 동안 공격자가 원시 문자열 형식의 사용자 암호를 훔칠 수 있다는 점이 우려됩니다. 단순히 사용하는 password_in_string_form = nil것으로 충분 할지 모르겠습니다 .

사용자 암호를 사용하는 순간 사용자의 암호를 보유하는 변수를 무효화하고 싶습니다 . nullify는 0으로 무언가를 채우기 위해 / dev / null을 사용하는 것과 비슷한 것을 의미합니다. 최종 목표는 데이터를 되돌릴 수없는 파괴입니다 .

답변

4 JohnBollinger Dec 06 2020 at 03:47

단순히 사용하는 password_in_string_form = nil것으로 충분 할지 모르겠습니다 .

아니, 충분하지 않습니다. 객체는 즉시 가비지 수집 될 수도 있고 수집되지 않을 수도 있으며, 그렇더라도 메모리에서 내용이 지워지지는 않습니다.

그러나 고정되지 않은 경우 Ruby 문자열은 변경 가능 합니다. 따라서 암호 문자열을 고정하지 않는 한 그 내용을 0 또는 임의의 문자로 대체 할 수 있습니다. 특히, 이것은 나중에 다룰 몇 가지 단정을 주제로 작동합니다.

(0 ... password_in_string_form.length).each do |i|
    password_in_string_form[i] = ' '
end

그러나 더 우상적으로 보일 수있는이 접근 방식 은 효과가 없기 때문에주의를 기울여야합니다 .

# SURPRISE! This does not reliably remove the password from memory!
password_in_string_form.replace(' ' * password_in_string_form.length)

대상 문자열의 내용을 제자리에서 업데이트하는 대신 replace()내용을 Ruby의 내부 할당 자 (수정하지 않음)에 릴리스하고 교체 세부 정보를 기반으로 새 내용에 대한 전략을 선택합니다.

그러나이 두 가지 접근 방식 간의 효과 차이는 큰 경고 플래그가되어야합니다. Ruby는 매우 높은 수준의 언어입니다. 이는 많은 레버리지를 제공하지만 데이터가 메모리에 유지되는지 여부와 기간과 같은 세부 사항을 제어하는 ​​비용이 발생합니다.

그리고 그것은 저를 provisos로 가져옵니다. 주요 내용은 다음과 같습니다.

  • 암호 문자열을 처리 할 때 암호 문자열 또는 그 일부의 복사본을 만들지 않도록주의하거나 모든 복사본을 캡처하여 폐기해야합니다. 그러한 사본을 만드는 것이 매우 쉽기 때문에 세부 사항에 약간의 규율과주의가 필요합니다.

  • 비밀번호 문자열 자체를 폐기하는 것만으로는 목표를 달성하기에 충분하지 않을 수 있습니다. 또한 암호 문자열을 분리하는 업스트림에서와 같이 메모리에있는 다른 암호 복사본을 폐기해야합니다. 예를 들어 웹 응용 프로그램 인 경우 암호가 응용 프로그램에 전달 된 HTTP 요청의 내용과 격리 된 암호 문자열보다 파생 된 문자열이 더 많을 것입니다. 다른 종류의 응용 프로그램에도 유사하게 적용됩니다.

  • 암호 만 보호해야하는 것은 아닙니다. 공격자가 호스트 컴퓨터의 메모리에서 암호를 훔칠 수있는 위치에 있으면 사용자가 로그인 한 후 액세스하는 민감한 데이터를 훔칠 수있는 위치에 있습니다.

이러한 이유와 다른 이유로 서버에 대한 보안 요구 사항에 따라 사용자 암호의 메모리 내 복사본이 더 이상 필요하지 않은 즉시 폐기되어야하는 경우 (순수한) Ruby가 적절한 구현 언어가 아닐 수 있습니다.

반면에 적이 메모리 / 스왑에서 암호를 긁어 낼 수있는 충분한 액세스 권한을 얻으면 이미 게임이 끝났을 것입니다. 최소한 애플리케이션이 액세스 할 수있는 모든 것에 액세스 할 수 있습니다. 그렇다고해서 암호가 전혀 문제가되지는 않지만이 문제에 얼마나 많은 노력을 기울이는지를 평가할 때이를 고려해야합니다.

1 JörgWMittag Dec 06 2020 at 03:27

Ruby에서는 불가능합니다.

이를 보장하기 위해 각 구현 (Opal, TruffleRuby, JRuby, Rubinius, MRuby, YARV 등)에 특정한 코드를 작성해야합니다. 구현에 따라 사용자가 직접 관리하는 별도의 메모리가 없으면 구현의 관리되는 메모리 내부 에서 수행하는 것이 전혀 불가능할 수도 있습니다 .

즉, 자신의 작은 네이티브 메모리를 관리하고이를 Ruby 프로그램에 삽입하는 작은 네이티브 코드가 필요할 것입니다.