Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Rails 보안 위협:인증

이 시리즈의 1부, 주입 공격을 다룹니다.

OWASP 상위 10가지 웹 애플리케이션 보안 위험에 대한 시리즈의 두 번째 기사에서는 깨진 인증 및 데이터 노출 위협에 대해 자세히 알아보겠습니다.

더 구체적으로 설명하자면 해커가 여러분이 만든 코드를 속이고 사용자 데이터를 얻기 위해 공격을 수행하는 것이 얼마나 쉬운지에 대해 설명합니다.

  • 사용자 열거 :데이터베이스에 존재하는지 확인하기 위해 가능한 사용자 목록을 무차별 대입 테스트하여 로그인 페이지를 악용하는 경우.
  • 약한 비밀번호 :시스템에서 약한 암호를 허용하면 해커가 사용자의 암호를 추측하기 위해 무차별 대입 공격을 수행할 수 있습니다.
  • 무제한 쿠키 :시스템이 적절한 보안 설정 없이 민감한 데이터를 쿠키에 저장하면 해커가 XSS 공격을 통해 정보를 훔칠 수 있습니다.

또한 다음과 같은 취약성을 위해 충분히 보호되지 않은 민감한 데이터에 대해 자세히 설명합니다.

  • 안전하지 않은 민감한 저장소 :민감한 데이터가 MD5와 같은 약한 알고리즘으로 암호화된 경우.
  • 민감한 데이터 노출 :예를 들어 개발자가 URL 또는 숨겨진 필드에 암호화되지 않은 민감한 데이터를 의도하지 않게 노출하는 경우.

시리즈의 첫 번째 기사와 마찬가지로 RailsGoat를 사용하여 이러한 위협 각각을 실제로 탐색할 것입니다. 처음 사용하는 경우 이전 문서를 참조하여 앱을 설정하고 실행하세요.

바로 뛰어들자!

인증 위협

우리는 인증 없이는 살 수 없습니다. 백엔드 API에 있든 프론트엔드 양식에 있든 보안 조치의 경계 한계를 강조하기 때문에 애플리케이션 개발에서 가장 중요한 단계 중 하나입니다.

인증 자체뿐만 아니라 다음 단계인 세션 관리를 위한 것입니다. 비밀번호와 토큰을 어디에 저장하시겠습니까? 제대로 암호화되어 있습니까? 신뢰할 수 있는 알고리즘을 사용하고 있습니까? 비밀번호가 충분히 복잡합니까?

지켜봐야 할 질문이 많이 있습니다. 이를 조금 세분화하여 Rails 애플리케이션 내에서 인증 및 세션 관리와 관련된 몇 가지 일반적인 공격을 이해하겠습니다.

사용자 열거

사용자 열거는 공격자가 (무차별 대입을 통해) 주어진 데이터가 시스템 내에 존재하는지 확인하는 데 사용하는 유명한 기술입니다.

이 공격의 가장 악명 높은 예 중 하나는 현재 Facebook 로그인 페이지에서 발생합니다. 아래 이미지에 표시된 것과 같이 유효하지 않은 임의의 자격 증명을 입력하면 Facebook에서 요청을 처리하고 데이터베이스 내에서 사용자의 존재를 확인합니다.

Rails 보안 위협:인증

Facebook의 로그인 페이지입니다.

로그인을 클릭하면 버튼을 누르면 Facebook에서 사용자 이름(이메일 또는 전화번호일 수 있음)이 유효하지 않다는 오류 메시지를 반환합니다.

Rails 보안 위협:인증

잘못된 사용자 이름 메시지입니다.

따라서 공격자는 응용 프로그램이 사용자가 등록되었는지 여부를 알려준다는 것을 알고 있습니다. 무료입니다.

공격자가 이메일 목록을 가지고 있는 경우(임의로 생성되었거나 어딘가에서 구입했는지 여부) 응용 프로그램에 암호가 올바른지 묻는 것도 가능합니다.

Rails 보안 위협:인증

잘못된 비밀번호 메시지입니다.

공격자가 시스템이 각 유효성 검사에 대해 개별적으로 응답하는 방법을 알게 되면 possible users 목록을 만들 수 있습니다. 및 일반/약한 암호. 그런 다음 액세스 권한을 얻을 때까지 시스템에 대해 무차별 대입 테스트를 반복적으로 수행할 수 있습니다.

물론 Facebook 개발자는 이에 대해 알고 있으며 특정 IP 주소에서 오는 요청 수에 대한 유효성 검사 및 보이지 않는 보안 문자와 같은 추가 보호 기능을 구현한 이유입니다.

사용자 열거를 피하기 위해 할 수 있는 일 중 하나는 사용자 이름과 암호를 함께 확인하고 일반 메시지를 반환하는 것입니다. 이 접근 방식을 실제로 봅시다!

행동 중인 위협

RailsGoat 앱에서 user.rb를 엽니다. 앱/모델의 파일 폴더를 찾아 authenticate 방법. 그 안에서 다음 코드 스니펫을 찾을 수 있습니다.

raise "#{email} doesn't exist!" if !(user)
if user.password == Digest::MD5.hexdigest(password)
  auth = user
else
  raise "Incorrect Password!"
end

정확히! 메시지는 공격자가 사용자가 존재하지 않거나 암호가 잘못된지 여부를 알 수 있는 방식으로 설정됩니다.

테스트해 보세요. RailsGoat 로그인 페이지로 이동하여 임의의 이메일과 비밀번호를 입력하십시오. 다음과 같은 오류 메시지가 표시될 수 있습니다.

Rails 보안 위협:인증

사용자가 존재하지 않습니다.

그렇지 않고 사용자가 존재하는 경우([email protected] , 예) 하지만 비밀번호가 잘못된 경우 다음 메시지가 표시됩니다.

Rails 보안 위협:인증

잘못된 비밀번호입니다.

앱이 강력한 비밀번호만 허용한다는 점을 고려하면 공격자는 여전히 열거된 유효한 클라이언트 이메일 목록을 만들고 피싱 이메일을 대상으로 삼아 사용자가 악의적인 작업을 요청한 사람이라는 인상을 줄 수 있습니다.

이 문제를 해결하는 방법

더 안전하게 만들기 위해 취할 수 있는 가장 빠른 조치는 메시지를 변경하고 해커의 삶을 복잡하게 만드는 것입니다.

sessions_controller.rb 내 (app/controllers 폴더)에서 create를 찾습니다. 메소드를 변경하고 다음 코드 스니펫을 변경합니다.

flash[:error] = e.message

다음으로:

flash[:error] = "Your credentials aren't valid."

이제 사용자가 잘못된 사용자 이름이나 비밀번호를 입력할 때마다 다음과 같은 메시지를 받게 됩니다.

Rails 보안 위협:인증

잘못된 자격 증명입니다.

이를 수행하는 또 다른 방법은 users.rb 내의 두 메시지를 변경하는 것입니다. 모델.

약한 비밀번호

우리는 이것을 충분히 강조할 수 없습니다. 사용자에게 강력한 비밀번호를 입력하도록 요구 그리고 강력한 비밀번호 기준을 충족하는지 확인하기 위해 확인 코드를 생성해야 합니다.

이것은 사용자 열거를 방지하는 가장 중요한 단계 중 하나입니다.

행동 중인 위협

RailsGoat에서 user.rb를 엽니다. 파일을 만들고 클래스 정의 바로 앞의 첫 번째 코드 줄을 찾습니다.

validates :password,
    presence: true,
    confirmation: true,
    length: {
      within: 6..40
    },

    ...

이것은 길이만 확인하기 때문에 암호가 약하게 검증되는 분명한 예입니다.

이 문제를 해결하는 방법

솔루션은 매우 간단합니다. 다음과 같은 몇 가지 더 강력한 요구 사항에 대해 암호를 확인하십시오.

  • 최소 1개의 소문자와 1개의 대문자,
  • 최소 1자리
  • 최소 10자

더 많은 요구 사항을 추가할수록 암호가 더 안전해집니다. 너무 많이 사용하면 사용성과 비밀번호 복구 흐름이 복잡해질 수 있으므로 너무 많이 사용하지 않도록 하세요.

RailsGoat 내에서 이 문제를 해결하려면 length 속성을 다음으로 대체하면 됩니다.

:format => {:with => /\A.*(?=.*[a-zA-Z])(?=.*[0-9])(?=.{10,}).*\z/},

그런 다음 가입 페이지로 이동하여 필드를 채우고 약한 비밀번호를 입력합니다. 제출하면 다음과 같은 오류 메시지가 표시됩니다.

Rails 보안 위협:인증

비밀번호가 잘못되었습니다.

무제한 쿠키

이전 기사에서 우리는 XSS 공격이 어떻게 발생하는지 이해하는 데 시간을 할애했습니다. 공격자가 악성 스크립트를 실행하도록 허용함으로써 발생하므로 document.cookie와 같은 속성에 대한 액세스를 차단하지 않으면 세션 쿠키에서 중요한 정보를 훔칠 수 있습니다. JavaScript 코드에서.

웹 저장소와 쿠키 간의 분쟁은 커뮤니티 내에서 자주 논의된다는 점을 기억하십시오. 웹 저장소가 더 실용적이지만 공격자는 XSS 위협에 대한 적절한 보호 없이 웹 저장소에 저장된 개체에 대한 전체 액세스 권한을 얻을 수 있습니다.

쿠키는 HttpOnly 플래그.

즉, 세션 정보를 보유하고 HttpOnly로 설정되는 쿠키입니다. 플래그는 JavaScript Document.cookie에서 액세스할 수 없습니다. API. 이렇게 하면 서버만 수신하게 됩니다.

또는 Secure도 있습니다. 이 속성을 사용하면 요청이 HTTPS 내에서 발생하는 경우에만 쿠키가 서버로 전송됩니다(HTTP 내에서는 아님). 이렇게 하면 누군가가 요청을 중간자로 스니핑하는 경우에 대비하여 요청이 더 안전해집니다. .

행동 중인 위협

Rails는 HttpOnly로 모든 쿠키를 자동으로 설정함으로써 귀하를 대신합니다. 깃발. 이는 인식하지 못하는 개발자가 앱이 해킹되는 것을 방지하는 데 도움이 되기 때문에 좋습니다.

이 예제를 테스트하려면 RailsGoat이 session_store.rb 내에서 명시적으로 수행한 이 기능을 비활성화해야 합니다. config/initializers에 있는 파일 폴더. 확인해 보세요!

그런 다음 다시 한 번 등록 페이지로 이동하여 필드를 올바르게 채우고 이름에 다음 내용을 입력합니다. 필드:

<script>
  alert(document.cookie);
</script>

양식을 제출하면 다음 경고 메시지와 함께 사용자가 생성됩니다.

Rails 보안 위협:인증

RailsGoat 세션 쿠키를 노출하는 경고 메시지입니다.

이 문제를 해결하는 방법

이 경우 매우 간단합니다. HttpOnly를 비활성화하지 않도록 하십시오. Rails 앱에 플래그를 지정합니다.

따라서 httponly: false를 제거하십시오. 설정하고 서버를 다시 시작하십시오. 동일한 작업을 수행하려고 하면 다음 경고 메시지가 표시됩니다.

Rails 보안 위협:인증

빈 경고 메시지입니다.

기타 시나리오

공공 도서관 컴퓨터나 LAN 하우스와 같이 안전하지 않은 컴퓨터에서 웹 응용 프로그램에 액세스한다고 상상해 보십시오. 지정된 시간 동안 활동이 없으면 애플리케이션이 올바르게 로그아웃되도록 구성되지 않은 경우 세션이 계속 유지됩니다.

단순히 브라우저 탭을 닫는 것만으로는 애플리케이션에서 로그아웃할 수 없습니다.

개발자 코드의 또 다른 일반적인 문제는 프런트 엔드에서 모든 종류의 ID를 노출하는 경우입니다. 사용자가 서버에 추가로 다른 것을 요청할 때 사용자의 ID를 숨겨진 입력 또는 URL에 보관하면 삶이 더 쉬워지는 시나리오를 생각하는 것은 그리 어렵지 않습니다.

그러나 이것은 도용 공격의 절반입니다.

민감한 데이터 노출

이 주제는 민감한 정보의 보안을 보장하기 위해 충분한 노력을 기울인다는 점에서 가장 과소평가된 주제 중 하나일 것입니다.

데이터가 지속적으로 전송 중이든 정지 상태이든 상관없이 일반 데이터를 민감한 데이터와 분리하는 것은 매우 중요합니다. 민감한 데이터에는 신용 카드 번호 및 코드, 비밀번호, 개인 식별 번호 또는 규정 준수 또는 개인 정보 보호법(예:EU의 GDPR 및 PCI)과 관련된 모든 것이 포함됩니다.

그 외에 애플리케이션이 실행되는 특정 비즈니스 영역에 따라 다른 규정 준수 규칙도 적용되는지 여부를 결정하기 위해 현지 법률을 참조하는 것이 중요합니다.

다음은 이 취약점의 몇 가지 명확한 예입니다.

  • 데이터가 어떻게든 암호화되거나 웹을 통해 일반 텍스트로 전송됩니까?
  • 데이터를 암호화하는 경우 어떤 알고리즘을 사용하고 있습니까? 최신 유형의 암호화 공격에 대해 강력하고 신뢰할 수 있습니까?
  • 제공되지 않은 기본 암호화 키를 사용합니까?
  • HTTP 요청이 적절한 보안 헤더에 의해 시행되는지 확인하셨습니까?

가장 일반적인 몇 가지 시나리오를 분석해 보겠습니다.

안전하지 않은 민감한 저장소

한동안 웹 애플리케이션을 사용해 왔다면 MD5 메시지 다이제스트 알고리즘에 대해 들어봤거나 사용했을 가능성이 있습니다. 암호 해싱에 여전히 널리 사용되지만 매우 취약한 것으로 판명되었습니다.

정보 해싱과 암호화의 차이점을 이해하는 것이 중요합니다. 암호화는 데이터 암호 해독에 일종의 키가 사용될 때 발생합니다. 해싱은 변환 방법을 나타냅니다. 데이터를 해시로 변환할 수 있지만 그 반대로는 불가능합니다.

MD5는 대부분 암호 해싱과 함께 사용되는 것으로 알려져 있지만 이는 모든 종류의 민감한 정보에 적용됩니다. 예를 들어 애플리케이션이 사용자의 사회 보장 번호(SSN)를 유지하는 경우 데이터베이스 내에 안전하게 저장하고 데이터가 앱을 통해 다른 데이터베이스, 특히 브라우저로 전송되는 방식을 관찰해야 합니다.

행동 중인 위협

우리가 보았듯이 RailsGoat은 의도적으로 사용자의 비밀번호를 MD5 해시로 저장합니다. user.rb에서 확인할 수 있습니다. 모델:

def hash_password
  if self.password.present?
      self.password = Digest::MD5.hexdigest(password)
  end
end

사용자가 로그인할 때마다 앱은 제공된 비밀번호를 해시하고 결과가 동일한지 확인합니다. 그렇지 않으면 비밀번호가 일치하지 않아 오류가 발생합니다.

이 문제를 해결하는 방법

이 문제를 해결하는 방법은 여러 가지가 있지만 가장 유명한 방법 중 하나는 BCrypt에서 제공하는 것과 같은 솔트 해시를 사용하는 것입니다.

Rails에는 Bcrypt를 처리할 수 있는 기본 기능이 포함되어 있지만 이 용도로 악명 높은 lib가 널리 사용되었습니다. bcrypt-ruby:

gem install bcrypt

모델을 매핑할 때 데이터베이스에서 암호를 설정하고 얻는 방법이 정의됩니다. lib는 다른 모든 것을 자동으로 조정합니다.

require 'bcrypt'

class User < ActiveRecord

  include BCrypt

  def password
    @password ||= Password.new(password_hash)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end
end

그러나 흐름에는 추가 문자열 열(password_hash ) BCrypt 알고리즘에 대한 암호 해시를 저장하기 위해 테이블에.

이렇게 하면 모델 개체에 직접 암호 값을 설정할 수 있으며 BCrypt가 안전하게 해싱합니다. 사용자의 입력과 비교하기 위해 비밀번호를 검색할 때도 마찬가지입니다.

너무 많이 노출

예를 들어 REST API로 작업하든 GraphQL 엔드포인트로 작업하든 클라이언트가 작동하도록 하는 데 필요한 것만 반환해야 합니다.

JavaScript 클라이언트가 API에서 정보를 요청하고 그 중 일부만 사용하는 경우 공격자가 엔드포인트를 잡고 다시 한 번 호출하여 전체 응답을 검색하거나 프록시 도구로 이를 스니핑하는 것을 방해하지 않습니다.

항상 API를 검토하여 반환되는 민감한 정보에 관계없이 적절한 암호화를 통해 올바른 위치에서 반환될 것임을 확인하십시오.

행동 중인 위협

사용자 데이터와 관련하여 민감한 정보가 누출되지 않도록 하는 보안 메커니즘을 만드는 것이 중요합니다.

users_controller.rb를 엽니다. api/v1의 파일 폴더. 여기에서 다음 방법을 찾을 수 있습니다.

def show
  respond_with @user.as_json
end

간단하지만 웹 클라이언트가 액세스할 때 이 끝점은 암호를 포함하여 응답 내에 채워진 모든 사용자 필드를 반환합니다.

user 뿐만 아니라 모델뿐만 아니라 민감한 정보를 보유하는 다른 모델도 API에 표시될 속성을 선택하는 방법이 필요합니다.

이 문제를 해결하는 방법

운 좋게도 Rails는 이를 매우 쉽게 처리할 수 있는 방법을 제공합니다. as_json을 재정의합시다. 다음과 같은 방법:

def as_json
  super(only: [:id, :email])
end

이제 기본적으로 모든 것을 노출하는 대신 필요한 데이터로만 응답합니다. 각 모델에 대해 중요한 필드를 선택하고 동일한 경험 법칙을 적용해야 합니다.

마무리

오늘 우리는 깨진 인증과 민감한 데이터 노출의 바다를 헤쳐나갔습니다. 이러한 규칙을 따르면 사용자와 클라이언트에게 훨씬 더 안전한 애플리케이션을 보장할 수 있습니다.

또한 공식 Ruby on Rails 보안 문서를 살펴보는 것의 중요성은 아무리 강조해도 지나치지 않습니다. 여기에서 세션 하이재킹, 저장 메커니즘 및 가능한 최선의 방법으로 데이터를 암호화하는 전략에 대한 자세한 정보를 찾을 수 있습니다.

다음 정류장에서 만나요!