1부: 로그인 방법
인증을 위해 서버 측의 스크립트에 값을 게시하는 로그인+비밀번호 HTML 양식을 작성하는 방법을 이미 알고 있다고 가정합니다. 아래 섹션에서는 건전한 실용적인 인증을 위한 패턴과 가장 일반적인 보안 함정을 피하는 방법을 설명합니다.
HTTPS로 또는 HTTPS로?
연결이 이미 안전하지 않은 한(즉, SSL/TLS를 사용하여 HTTPS를 통해 터널링됨) 로그인 양식 값(비밀번호를 포함하여 헐떡임)이 일반 텍스트로 전송되어 브라우저와 웹 서버 사이의 회선을 도청하는 모든 사람이 통과할 때 로그인을 읽을 수 있습니다. 이러한 유형의 도청은 정부에서 일상적으로 수행하지만 일반적으로 '소유' 전선에 대해서는 다음과 같이 말하지 않습니다. HTTPS를 사용하세요.
본질적으로 로그인 중 도청/패킷 스니핑으로부터 보호하는 유일한 실용적인 방법은 HTTPS 또는 다른 인증서 기반 암호화 체계(예: TLS ) 또는 입증되고 테스트된 시도 응답 체계(예: Diffie-Hellman 기반 SRP). 다른 방법은 도청 공격자 가 쉽게 우회할 수 있습니다.
물론 약간 비실용적이라면 일종의 이중 인증 체계(예: Google Authenticator 앱, 물리적 '냉전 스타일' 코드북 또는 RSA 키 생성기 동글)를 사용할 수도 있습니다. 올바르게 적용하면 보안되지 않은 연결에서도 작동할 수 있지만 개발자가 SSL이 아닌 2단계 인증을 구현하려는 것은 상상하기 어렵습니다.
(하지 마십시오) 자체 JavaScript 암호화/해싱
(지금은 피할 수 있지만) 웹사이트에서 SSL 인증서를 설정하는 데 드는 비용과 기술적 어려움을 감안할 때 일부 개발자는 보안되지 않은 회선을 통해 일반 텍스트 로그인을 전달하는 것을 피하기 위해 자체 브라우저 내 해싱 또는 암호화 체계를 사용하려는 유혹을 받습니다.
이것은 고귀한 생각이지만 위의 것 중 하나와 결합되지 않는 한 본질적으로 쓸모가 없습니다( 보안 결함이 될 수 있음). 즉, 강력한 암호화로 회선을 보호하거나 검증된 시도 응답을 사용 메커니즘(이것이 무엇인지 모르는 경우 가장 증명하기 어렵고 설계하기 가장 어렵고 디지털 보안에서 개념을 구현하기 가장 어려운 것 중 하나라는 것만 알아두십시오).
비밀번호 해싱이 비밀번호 노출 에 대해 효과적일 수 있는 것은 사실이지만 재생 공격, 중간자 공격/하이재킹(공격자가 보안되지 않은 HTML 페이지에 도달하기 전에 몇 바이트를 삽입할 수 있는 경우)에 취약합니다. 브라우저에서는 JavaScript에서 해싱을 주석으로 처리하거나 무차별 대입 공격(공격자에게 사용자 이름, 솔트 및 해시된 암호를 모두 전달하기 때문에)을 간단히 주석 처리할 수 있습니다.
인류에 대한 보안문자
CAPTCHA 는 한 가지 특정 공격 범주인 자동화된 사전/무차별 대입 시행착오를 방지하기 위한 것입니다. 이것이 실제 위협이라는 데는 의심의 여지가 없지만 CAPTCHA, 특히 적절하게 설계된 서버 측 로그인 제한 체계를 필요로 하지 않는 원활하게 처리하는 방법이 있습니다. 이에 대해서는 나중에 논의하겠습니다.
CAPTCHA 구현은 비슷하게 생성되지 않는다는 점을 알아두십시오. 그것들은 종종 인간이 해결할 수 없으며, 대부분은 실제로 봇에 대해 비효율적이며, 모두 값싼 제3세계 노동에 대해 비효율적이며( OWASP 에 따르면 현재 착취 공장 비율은 500개 테스트당 $12임), 일부 구현은 다음과 같을 수 있습니다. 일부 국가에서는 기술적으로 불법입니다( OWASP 인증 치트 시트 참조).
CAPTCHA는 시각 장애인에게 좋지 않습니다. 전통적인 복사는 첫 번째 시도에서 완벽한 20/20 시력을 가진 인간조차도 완성하는 것이 거의 불가능했습니다. 따라서 기존의 보안 문자를 사용하지 마십시오!
CAPTCHA를 사용해야 하는 경우 Google의 reCAPTCHA를 사용하십시오. 정의상 OCR이 어렵고(이미 OCR로 잘못 분류된 책 스캔을 사용하기 때문에) 사용자 친화적으로 매우 열심히 노력하기 때문입니다.
개인적으로 저는 CAPTCHAS를 성가시게 여기는 경향이 있으며 사용자가 여러 번 로그인에 실패하고 조절 지연이 최대일 때 최후의 수단으로만 사용합니다. 이것은 거의 받아들일 수 없을 만큼 발생하며 시스템 전체를 강화합니다.
비밀번호 저장 / 로그인 확인
이것은 우리가 최근 몇 년 동안 본 모든 널리 알려진 해킹 및 사용자 데이터 유출 이후에 마침내 일반적인 지식일 수 있지만 말해야 합니다. 암호를 데이터베이스에 일반 텍스트로 저장하지 마십시오. 사용자 데이터베이스는 SQL 주입을 통해 일상적으로 해킹, 유출 또는 수집되며, 원시 일반 텍스트 암호를 저장하는 경우 로그인 보안에 대한 즉각적인 게임 오버입니다.
따라서 비밀번호를 저장할 수 없는 경우 로그인 양식에서 게시한 로그인+비밀번호 조합이 올바른지 어떻게 확인합니까? 답은 키 파생 함수를 사용하여 해싱하는 것입니다. 새 사용자가 생성되거나 암호가 변경될 때마다 암호를 가져와서 Argon2, bcrypt, scrypt 또는 PBKDF2와 같은 KDF를 통해 실행하여 일반 텍스트 암호("correcthorsebatterystaple")를 길고 무작위로 보이는 문자열로 바꿉니다. , 데이터베이스에 저장하는 것이 훨씬 더 안전합니다. 로그인을 확인하려면 입력한 암호에 대해 동일한 해시 함수를 실행합니다. 이번에는 솔트를 전달하고 결과 해시 문자열을 데이터베이스에 저장된 값과 비교합니다. Argon2, bcrypt 및 scrypt는 이미 해시와 함께 소금을 저장합니다. 자세한 내용은 sec.stackexchange에서 이 기사를 확인하십시오.
솔트를 사용하는 이유는 해싱 자체로는 충분하지 않기 때문입니다. 즉, 레인보우 테이블 에 대해 해시를 보호하기 위해 소위 '소금'을 추가해야 합니다. 솔트는 정확히 일치하는 두 개의 비밀번호가 동일한 해시 값으로 저장되는 것을 효과적으로 방지하여 공격자가 비밀번호 추측 공격을 실행하는 경우 전체 데이터베이스가 한 번에 스캔되는 것을 방지합니다.
사용자가 선택한 암호가 충분히 강력하지 않고(즉, 일반적으로 충분한 엔트로피를 포함하지 않음) 암호 추측 공격이 해시에 액세스할 수 있는 공격자에 의해 비교적 짧은 시간에 완료될 수 있기 때문에 암호 저장에 암호 해시를 사용해서는 안 됩니다. KDFs가 사용되는 이유이다 -이 효과적으로 "키 스트레칭" 1 만 배 느린 암호를 추측 공격자 원인 모든 암호가 공격자의 차종을 생각한다는 의미는 예를 들어, 10,000 번 해시 알고리즘의 여러 번 반복됩니다,.
세션 데이터 - "Spiderman69로 로그인했습니다."
서버가 사용자 데이터베이스에 대해 로그인 및 비밀번호를 확인하고 일치하는 항목을 찾으면 시스템은 브라우저가 인증되었음을 기억할 방법이 필요합니다. 이 사실은 세션 데이터의 서버 측에만 저장되어야 합니다.
세션 데이터에 익숙하지 않은 경우 작동 방법은 다음과 같습니다. 무작위로 생성된 단일 문자열이 만료되는 쿠키에 저장되고 서버에 저장된 데이터 모음(세션 데이터)을 참조하는 데 사용됩니다. MVC 프레임워크를 사용하는 경우 의심할 여지 없이 이미 처리되었습니다.
가능하면 세션 쿠키에 브라우저로 보낼 때 보안 및 HTTP 전용 플래그가 설정되어 있는지 확인하십시오. HttpOnly 플래그는 XSS 공격을 통해 읽혀지는 쿠키에 대한 보호 기능을 제공합니다. 보안 플래그는 쿠키가 HTTPS를 통해서만 다시 전송되도록 하여 네트워크 스니핑 공격으로부터 보호합니다. 쿠키의 값은 예측할 수 없어야 합니다. 존재하지 않는 세션을 참조하는 쿠키가 있는 경우 세션 고정 을 방지하기 위해 해당 값을 즉시 교체해야 합니다.
세션 상태는 클라이언트 측에서도 유지될 수 있습니다. 이는 JWT(JSON Web Token)와 같은 기술을 사용하여 달성됩니다.
2부: 로그인 상태를 유지하는 방법 - 악명 높은 "기억하기" 확인란
영구 로그인 쿠키("기억하기" 기능)는 위험 영역입니다. 한편으로는 사용자가 로그인을 처리하는 방법을 이해할 때 기존 로그인만큼 안전합니다. 다른 한편으로는 공용 컴퓨터에서 사용하고 로그아웃하는 것을 잊거나 브라우저 쿠키가 무엇인지 또는 삭제하는 방법을 모를 수 있는 부주의한 사용자의 손에 엄청난 보안 위험이 있습니다.
개인적으로 정기적으로 방문하는 웹 사이트에 대한 영구 로그인을 좋아하지만 안전하게 처리하는 방법을 알고 있습니다. 사용자가 동일한 사실을 알고 있다고 확신한다면 깨끗한 양심으로 영구 로그인을 사용할 수 있습니다. 그렇지 않다면 로그인 자격 증명에 부주의한 사용자가 해킹을 당했을 때 스스로 자격 증명을 가져왔다는 철학에 동의할 수 있습니다. 그것은 우리가 사용자의 집에 가서 모니터 가장자리에 줄 지어 있는 비밀번호가 있는 얼굴에 손바닥을 적시게 하는 포스트잇 메모를 모두 찢는 것과는 다릅니다.
물론, 일부 시스템은 해킹 어떤 계정이 여유가 없다; 그러한 시스템의 경우 지속적인 로그인을 정당화할 수 있는 방법이 없습니다.
영구 로그인 쿠키를 구현하기로 결정했다면 다음과 같이 하십시오.
먼저 시간을 할애하여 해당 주제에 대한 Paragon Initiative의 기사를 읽으십시오. 많은 요소를 올바르게 가져와야 하며 이 기사는 각 요소를 훌륭하게 설명합니다.
그리고 가장 일반적인 함정 중 하나를 되풀이하여 데이터베이스에 영구 로그인 쿠키(토큰)를 저장하지 마십시오. 로그인 토큰은 암호와 동일하므로 공격자가 데이터베이스에 손을 대면 토큰을 사용하여 일반 텍스트 로그인-암호 조합인 것처럼 모든 계정에 로그인할 수 있습니다. 따라서 영구 로그인 토큰을 저장할 때 해싱을 사용하십시오( https://security.stackexchange.com/a/63438/5002 에 따르면 약한 해시는 이 목적에 적합합니다).
파트 III: 비밀 질문 사용
'비밀 질문'을 구현하지 마십시오 . '비밀 질문' 기능은 보안 안티 패턴입니다. 반드시 읽어야 할 목록의 링크 번호 4에 있는 논문을 읽으십시오. Sarah Palin에게 Yahoo! 그녀의 보안 질문에 대한 답변이... "와실라 고등학교"였기 때문에 이전 대선 캠페인에서 이메일 계정이 해킹당했습니다!
사용자 지정 질문이 있더라도 대부분의 사용자는 다음 중 하나를 선택할 가능성이 높습니다.
어머니의 결혼 전 이름이나 좋아하는 애완 동물과 같은 '표준'비밀 질문
누구나 자신의 블로그, LinkedIn 프로필 또는 이와 유사한 것에서 들어 올릴 수 있는 간단한 퀴즈
비밀번호를 추측하는 것보다 대답하기 쉬운 모든 질문. 괜찮은 비밀번호에 대해 상상할 수 있는 모든 질문은 무엇입니까?
결론적으로 보안 질문은 거의 모든 형태와 변형에서 본질적으로 안전하지 않으며 어떤 이유로든 인증 체계에 사용되어서는 안 됩니다.
보안 질문이 야생에 존재하는 진정한 이유는 재활성화 코드를 받기 위해 이메일에 액세스할 수 없는 사용자의 몇 번의 지원 호출 비용을 편리하게 절약할 수 있기 때문입니다. 이것은 보안과 Sarah Palin의 평판을 희생시키는 것입니다. 그만한 가치가 있습니까? 아마 아닐 것입니다.
파트 IV: 잊어버린 암호 기능
잊어버린/분실한 사용자 암호를 처리 하기 위해 보안 질문 을 사용해서는 안 되는 이유를 이미 언급했습니다. 또한 사용자에게 실제 비밀번호를 이메일로 보내서는 안 됩니다. 이 분야에서 피해야 할 아주 일반적인 함정이 적어도 두 가지 더 있습니다.
잊어버린 비밀번호를 자동 생성된 강력한 비밀번호로 재설정 하지 마십시오. 이러한 비밀번호는 기억하기 어렵기로 악명이 높기 때문에 사용자가 변경하거나 모니터 가장자리에 있는 밝은 노란색 포스트잇에 기록해 두어야 합니다. 새 비밀번호를 설정하는 대신 사용자가 즉시 새 비밀번호를 선택하도록 하세요. (사용자가 일반적으로 암호를 기록하지 않고는 기억할 수 없는 암호를 저장/관리하기 위해 보편적으로 암호 관리자를 사용하는 경우는 예외일 수 있습니다.)
항상 데이터베이스에서 분실된 암호 코드/토큰을 해시하십시오. 다시 말하지만 , 이 코드는 동일한 암호의 또 다른 예이므로 공격자가 데이터베이스를 손에 넣은 경우를 대비하여 해시해야 합니다. 분실한 암호 코드가 요청되면 일반 텍스트 코드를 사용자의 이메일 주소로 보낸 다음 해시하고 데이터베이스에 해시를 저장 하고 원본 . 비밀번호나 영구 로그인 토큰과 같습니다.
마지막 참고 사항: '비밀번호 분실'을 입력하기 위한 인터페이스가 최소한 로그인 양식 자체만큼 안전한지 항상 확인하십시오. 그렇지 않으면 공격자가 이를 대신 사용하여 액세스할 수 있습니다. 매우 긴 '분실된 비밀번호 코드'(예: 16개의 대소문자 구분 영숫자)를 생성하는 것이 좋은 시작이지만 로그인 양식 자체에 대해 수행하는 것과 동일한 제한 체계를 추가하는 것이 좋습니다.
파트 V: 암호 강도 확인
먼저 현실 확인을 위해 이 작은 기사를 읽고 싶을 것입니다. 가장 일반적인 비밀번호 500가지
좋아, 어쩌면 목록 어디서나 과거의 어떤 시스템에서 가장 흔한 패스워드의 표준 목록은 아니지만 장소에는 시행 정책이없는 경우 자신의 암호를 선택하는 방법이 저조한 사람들의 좋은 지표입니다. 또한 최근에 도난당한 암호에 대해 공개적으로 사용 가능한 분석과 비교할 때 목록이 집과 매우 유사해 보입니다.
따라서: 최소 암호 강도 요구 사항이 없으면 사용자의 2%가 가장 일반적인 암호 상위 20개 중 하나를 사용합니다. 의미: 공격자가 20번만 시도하면 웹사이트의 계정 50개 중 1개가 해킹될 수 있습니다.
이를 막으려면 암호의 엔트로피를 계산한 다음 임계값을 적용해야 합니다. NIST(National Institute of Standards and Technology) 특별 간행물 800-63 에는 매우 좋은 제안이 있습니다. 사전 및 키보드 레이아웃 분석(예: 'qwertyuiop'은 잘못된 암호임)과 결합하면 18비트 엔트로피 수준에서 잘못 선택된 모든 암호의 99%를 거부할 수 있습니다. 단순히 암호 강도를 계산 하고 사용자에게 시각적 강도 측정기 를 보여주는 것은 좋지만 충분하지 않습니다. 시행하지 않는 한 많은 사용자가 이를 무시할 가능성이 큽니다.
그리고 높은 엔트로피 암호의 사용자 친화성을 새로 고치려면 Randall Munroe의 Password Strength xkcd 를 적극 권장합니다.
Troy Hunt의 Have I Been Pwned API 를 사용하여 공개 데이터 침해로 인해 손상된 암호에 대해 사용자 암호를 확인합니다.
PART VI: 훨씬 더 - 또는: 빠른 로그인 시도 방지
먼저 숫자를 살펴보십시오. 암호 복구 속도 - 암호가 유지되는 기간
해당 링크의 테이블을 살펴볼 시간이 없다면 다음과 같은 목록이 있습니다.
주판으로 암호를 해독하더라도 취약한 암호를 해독하는 데는 거의 시간 이 걸리지 않습니다.
대소문자를 구분하지 않는 경우 영숫자 9자리 암호를 해독하는 데 시간이 거의 걸리지 않습니다.
길이가 8자 미만인 복잡한 기호, 문자, 숫자, 대문자 및 소문자 비밀번호를 해독하는 데 사실상 시간 이 걸리지 않습니다(데스크톱 PC는 한 문제에서 전체 키스페이스를 최대 7자까지 검색할 수 있음). 일 또는 몇 시간)
그러나 초당 한 번의 시도로 제한되는 경우 6자 암호라도 해독하는 데 엄청난 시간이 걸립니다!
그러면 이 숫자에서 무엇을 배울 수 있습니까? 글쎄요, 많이 하지만 우리는 가장 중요한 부분에 집중할 수 있습니다. 많은 수의 속사포 연속 로그인 시도(즉, 무차별 대입 공격)를 방지하는 것이 실제로 그렇게 어렵지 않다는 사실입니다. 하지만 이를 제대로 예방하는 것은 생각만큼 쉬운 일이 아닙니다.
일반적으로 말해서 무차별 대입 공격(및 사전 공격, 그러나 이미 강력한 암호 정책을 사용하고 있기 때문에 문제가 되지 않음) 에 대해 모두 효과적인 세 가지 선택이 있습니다.
N번의 시도 실패 후 보안 문자를 제시합니다(지옥처럼 짜증나고 종종 비효율적입니다. 하지만 여기서 반복합니다)
N번의 시도 실패 후 계정 잠금 및 이메일 확인 요구(발생하기를 기다리는 DoS 공격)
마지막으로 로그인 제한 : 즉, N번의 시도 실패 후 시도 사이에 시간 지연을 설정합니다(예, DoS 공격은 여전히 가능하지만 적어도 공격할 가능성은 훨씬 적고 훨씬 더 복잡합니다).
모범 사례 #1: 다음과 같이 실패한 시도 횟수에 따라 증가하는 짧은 시간 지연:
- 1번의 시도 실패 = 지연 없음
- 2번의 시도 실패 = 2초 지연
- 3번의 시도 실패 = 4초 지연
- 4회 실패 = 8초 지연
- 5회 실패 = 16초 지연
- 등.
이 계획을 공격하는 DoS는 매우 비현실적입니다. 그 결과 잠금 시간이 이전 잠금 시간의 합보다 약간 더 크기 때문입니다.
명확히 하기 위해: 지연은 브라우저에 응답을 반환하기 전의 지연이 아닙니다. 특정 계정 또는 특정 IP 주소에서 로그인을 시도하는 것이 전혀 허용되지 않거나 평가되지 않는 시간 초과 또는 불응 기간과 비슷합니다. 즉, 성공적인 로그인에서 올바른 자격 증명이 반환되지 않으며 잘못된 자격 증명이 지연 증가를 유발하지 않습니다.
모범 사례 #2: 다음과 같이 N번의 실패한 시도 후에 적용되는 중간 길이의 시간 지연:
- 1-4번의 실패 시도 = 지연 없음
- 5번의 실패한 시도 = 15-30분 지연
이 계획을 공격하는 DoS는 매우 비현실적이지만 확실히 가능합니다. 또한 이러한 긴 지연은 합법적인 사용자에게 매우 성가실 수 있다는 점에 유의해야 합니다. 건망증 사용자는 당신을 싫어할 것입니다.
모범 사례 #3: 두 가지 접근 방식 결합 - 다음과 같이 N번의 실패한 시도 후에 적용되는 고정된 짧은 시간 지연:
- 1-4번의 실패 시도 = 지연 없음
- 5회 이상 실패한 시도 = 20초 지연
또는 다음과 같이 고정된 상한으로 지연이 증가합니다.
- 1회 실패 = 5초 지연
- 2번의 시도 실패 = 15초 지연
- 3회 이상 시도 실패 = 45초 지연
이 최종 계획은 OWASP 모범 사례 제안(MUST-READ 목록의 링크 1)에서 가져온 것이며 제한적인 측면에서 인정하더라도 모범 사례로 간주되어야 합니다.
그러나 경험에 비추어 볼 때 암호 정책이 더 강력할수록 지연으로 인해 사용자에게 버그를 줄 필요가 줄어듭니다. 강력한(대소문자 구분 영숫자 + 필수 숫자 및 기호) 9자 이상의 암호가 필요한 경우 조절을 활성화하기 전에 사용자에게 지연되지 않은 암호 시도를 2-4번 제공할 수 있습니다.
이 최종 로그인 제한 체계를 공격하는 DoS는 매우 비현실적입니다. 그리고 마지막으로 항상 영구(쿠키) 로그인(및/또는 CAPTCHA 인증 로그인 양식)이 통과되도록 허용 하여 공격이 진행되는 동안 합법적인 사용자가 지연되지 않도록 하십시오. 그렇게 하면 매우 비현실적인 DoS 공격이 극도로 비현실적인 공격이 됩니다.
또한 관리자 계정이 가장 매력적인 진입점이므로 보다 적극적인 조절을 수행하는 것이 좋습니다.
PART VII: 분산 무차별 대입 공격
제쳐두고, 고급 공격자는 '활동 확산'을 통해 로그인 제한을 우회하려고 시도합니다.
IP 주소 플래그 지정을 방지하기 위해 봇넷에 시도 분산
한 명의 사용자를 선택하고 50,000개의 가장 일반적인 비밀번호를 시도하는 대신(저희의 제한 때문에 불가능함) 가장 일반적인 비밀번호를 선택하고 대신 50,000명의 사용자에 대해 시도합니다. 그렇게 하면 CAPTCHA 및 로그인 제한과 같은 최대 시도 횟수 측정을 피할 수 있을 뿐만 아니라 가장 일반적인 암호 1번이 49.995번보다 훨씬 높기 때문에 성공 가능성도 높아집니다.
레이더에 몰래 잠입하기 위해 각 사용자 계정에 대한 로그인 요청 간격(예: 30초)
여기에서 가장 좋은 방법은 시스템 전체에서 실패한 로그인 수를 기록하고 사이트의 잘못된 로그인 빈도의 실행 평균을 모든 사용자에게 적용하는 상한선의 기준으로 사용하는 것입니다.
너무 추상적인가요? 다시 말해보자:
귀하의 사이트에서 지난 3개월 동안 하루 평균 120회의 잘못된 로그인이 발생했다고 가정해 보겠습니다. 그것을 사용하여(실행 평균), 시스템은 전역 제한을 3배로 설정할 수 있습니다. 즉. 24시간 동안 360번 실패했습니다. 그런 다음 모든 계정에서 실패한 총 시도 횟수가 하루 이내에 해당 횟수를 초과하는 경우(또는 더 나은 경우 가속 속도를 모니터링하고 계산된 임계값에서 트리거) 시스템 전체 로그인 제한을 활성화합니다. 이는 모든 사용자에게 짧은 지연을 의미합니다. (여전히 쿠키 로그인 및/또는 백업 CAPTCHA 로그인 제외).
또한 분산 무차별 대입 공격을 방어할 때 까다로운 함정을 피하는 방법에 대한 자세한 설명과 정말 좋은 토론이 포함 된 질문을 게시했습니다.
파트 VIII: 2단계 인증 및 인증 제공자
자격 증명은 악용, 암호 기록 및 분실, 키가 있는 랩톱 도난, 사용자가 피싱 사이트에 로그인 입력 등으로 인해 손상될 수 있습니다. 전화 통화, SMS 메시지, 앱 또는 동글에서 받은 일회용 코드와 같은 대역 외 요소를 사용하는 이중 요소 인증으로 로그인을 더욱 보호할 수 있습니다. 여러 공급자가 이중 인증 서비스를 제공합니다.
인증은 다른 공급자가 자격 증명 수집을 처리하는 싱글 사인온 서비스에 완전히 위임될 수 있습니다. 이것은 문제를 신뢰할 수 있는 제3자에게 푸시합니다. Google과 Twitter는 모두 표준 기반 SSO 서비스를 제공하는 반면 Facebook은 유사한 독점 솔루션을 제공합니다.
웹 인증에 대해 반드시 읽어야 할 링크
- OWASP 인증 가이드 / OWASP 인증 치트 시트
- 웹에서 클라이언트 인증 시 해야 할 일과 하지 말아야 할 일(가독성이 뛰어난 MIT 연구 논문)
- 위키피디아: HTTP 쿠키
- 대체 인증을 위한 개인 지식 질문: Facebook 시대의 보안 질문(가독성이 뛰어난 Berkeley 연구 논문)
최종 기사
자격 증명 보내기
자격 증명을 100% 안전하게 보내는 유일한 실용적인 방법은 SSL 을 사용하는 것입니다. JavaScript를 사용하여 비밀번호를 해시하는 것은 안전하지 않습니다. 클라이언트 측 암호 해싱의 일반적인 함정:
- 클라이언트와 서버 간의 연결이 암호화되지 않은 경우 수행하는 모든 작업이 메시지 가로채기 공격에 취약 합니다. 공격자는 들어오는 자바 스크립트를 교체하여 해싱을 중단하거나 모든 자격 증명을 서버로 보낼 수 있으며 클라이언트 응답을 수신하고 사용자를 완벽하게 가장하는 등의 작업을 수행할 수 있습니다. 신뢰할 수 있는 인증 기관이 있는 SSL은 MitM 공격을 방지하도록 설계되었습니다.
- 서버에서 추가로 중복 작업을 수행하지 않으면 서버에서 받은 해시된 암호가 덜 안전합니다.
SRP 라고 하는 또 다른 안전한 방법이 있지만 특허를 받았고( 자유롭게 라이선스 가 있음에도 불구하고) 사용할 수 있는 좋은 구현이 거의 없습니다.
비밀번호 저장
데이터베이스에 암호를 일반 텍스트로 저장하지 마십시오. 자신의 사이트 보안에 관심이 없더라도 마찬가지입니다. 일부 사용자가 온라인 은행 계좌의 비밀번호를 재사용할 것이라고 가정합니다. 따라서 해시된 암호를 저장하고 원본을 버리십시오. 그리고 비밀번호가 액세스 로그 또는 애플리케이션 로그에 표시되지 않는지 확인하십시오. OWASP는 새로운 응용 프로그램에 대한 첫 번째 선택 으로 Argon2를 사용할 것을 권장합니다. 사용할 수 없는 경우 PBKDF2 또는 scrypt를 대신 사용해야 합니다. 마지막으로 위의 항목 중 아무 것도 사용할 수 없는 경우 bcrypt를 사용합니다.
해시 자체도 안전하지 않습니다. 예를 들어, 동일한 암호는 동일한 해시를 의미합니다. 이는 해시 조회 테이블을 한 번에 많은 암호를 해독하는 효과적인 방법으로 만듭니다. 대신 소금에 절인 해시를 저장하십시오. 솔트는 해시 전에 비밀번호에 추가된 문자열입니다. 사용자마다 다른(임의의) 솔트를 사용합니다. 솔트는 공개 값이므로 데이터베이스에 해시와 함께 저장할 수 있습니다. 이에 대한 자세한 내용은 여기를 참조하세요.
이것은 사용자에게 잊어버린 암호를 보낼 수 없음을 의미합니다(해시만 있기 때문에). 사용자를 인증하지 않은 경우 사용자의 비밀번호를 재설정하지 마십시오(사용자는 저장된(및 검증된) 이메일 주소로 전송된 이메일을 읽을 수 있음을 증명해야 합니다.)
보안 질문
보안 질문은 안전하지 않으므로 사용하지 마십시오. 왜요? 비밀번호 힌트는 무엇이든 비밀번호가 더 좋습니다. 이 위키에서 PART III: Using Secret Questions in @Jens Roland 답변을 읽으십시오.
세션 쿠키
사용자가 로그인한 후 서버는 사용자에게 세션 쿠키를 보냅니다. 서버는 쿠키에서 사용자 이름 또는 ID를 검색할 수 있지만 다른 사람은 이러한 쿠키를 생성할 수 없습니다(TODO 설명 메커니즘).
쿠키는 하이재킹될 수 있습니다. 쿠키는 클라이언트의 컴퓨터 및 기타 통신의 나머지 부분만큼만 안전합니다. 디스크에서 읽을 수 있고, 네트워크 트래픽에서 스니핑되고, 교차 사이트 스크립팅 공격에 의해 해제되고, 중독된 DNS에서 피싱되어 클라이언트가 쿠키를 잘못된 서버로 보낼 수 있습니다. 영구 쿠키를 보내지 마십시오. 쿠키는 클라이언트 세션이 끝날 때 만료되어야 합니다(브라우저 종료 또는 도메인 이탈).
사용자를 자동 로그인하려면 영구 쿠키를 설정할 수 있지만 전체 세션 쿠키와 구별되어야 합니다. 사용자가 자동 로그인하고 민감한 작업을 위해 실제 로그인해야 하는 추가 플래그를 설정할 수 있습니다. 이것은 귀하에게 원활하고 개인화된 쇼핑 경험을 제공하면서도 귀하의 금융 정보를 보호하고자 하는 쇼핑 사이트에서 인기가 있습니다. 예를 들어 아마존을 방문하기 위해 돌아오면 로그인한 것처럼 보이는 페이지가 표시되지만 주문을 하려고(또는 배송 주소, 신용 카드 등을 변경할 때) 확인을 요청합니다. 너의 비밀번호.
반면에 은행, 신용카드와 같은 금융 웹사이트는 민감한 데이터만 가지고 있으므로 자동 로그인이나 낮은 보안 모드를 허용하지 않아야 합니다.
외부 리소스 목록
나는 그냥 잘 작동하는 것으로 밝혀진 이 솔루션을 공유할 것이라고 생각했습니다.
나는 그것을 더미 필드( Dummy Field)라고 부릅니다.
간단히 말해서, 이것을 <form>
에 삽입하고 유효성을 검사할 때 비어 있는지 확인해야 합니다.
<input type="text" name="email" style="display:none" />
트릭은 봇이 데이터를 필수 필드에 삽입해야 한다고 생각하도록 속이는 것입니다. 그래서 입력 이름을 "이메일"이라고 지었습니다. 사용 중인 이메일이라는 필드가 이미 있는 경우 더미 필드 이름을 "회사", "전화" 또는 "이메일 주소"와 같은 다른 이름으로 지정해야 합니다. 필요하지 않은 것을 선택하고 사람들이 일반적으로 웹 양식에 채우는 것이 논리적이라고 생각하는 것처럼 들리는 것을 선택하십시오. 이제 숨길 input
가장 잘 맞는 어떤 - - CSS 나 자바 스크립트 / jQuery를 사용하여 필드를 바로 입력 설정하지 않는 type
에 hidden
그렇지 않으면 봇이 빠지지 않습니다.
이제 양식은 다음과 같습니다.
label[for="telephone"], input[type="tel"] { visibility: visible; /* to fool others */ color:white; width: 0; height: 0; position: absolute; top: -50px; left: -120px; }
<h1>Log In</h1> <p>Can you see a field called 'telephone number'?</p> <form action="/" method="post"> <label>username: <input type="text" name="username" /></label> <label>password: <input type="password" name="password" /></label> <!-- ta da. a label for it to seem even more realistic. aria-hidden="true" so screen readers will not be fooled.--> <label for="telephone" aria-hidden="true">telephone number</label> <input type="tel" name="telephone" id="telephone" title="enter your telephone number" /> <br /> <input type="submit" value="log in" /> </form>
양식(클라이언트 측 또는 서버 측)의 유효성을 검사할 때 더미 필드가 채워졌는지 확인하여 사람이 보낸 것인지 봇이 보낸 것인지 확인합니다.
귀하의 처리:
$fakefield = $_POST['telephone_number']; if (!$fakefield) { // log in // password_verify(...); // ... } else { echo 'no bots allowed'; }
예시:
사람의 경우: 사용자는 더미 필드(제 경우에는 "이메일"이라고 함)를 볼 수 없으며 채우기를 시도하지 않습니다. 따라서 양식이 전송되었을 때 더미 필드의 값은 여전히 비어 있어야 합니다.
봇의 경우: 봇은 유형이 text
이고 이름이 email
인 필드를 보고 논리적으로 적절한 데이터로 채우려고 시도합니다. 멋진 CSS로 입력 양식의 스타일을 지정했는지 여부는 상관하지 않습니다. 웹 개발자는 항상 이 작업을 수행합니다. 더미 필드의 값이 무엇이든 0
자보다 크면 상관 없습니다.
나는 CAPTCHA 와 함께 방명록에 이 방법을 사용했고 그 이후로 단 한 건의 스팸 게시물도 보지 못했습니다. 이전에 CAPTCHA 전용 솔루션을 사용한 적이 있지만 결국 시간당 약 5개의 스팸 게시물이 생성되었습니다. 양식에 더미 필드를 추가하면 (적어도 지금까지는) 모든 스팸이 표시되지 않습니다.
나는 이것이 로그인/인증 양식으로도 잘 사용될 수 있다고 생각합니다.
경고 : 물론 이 방법이 100% 완전하지는 않습니다. display:none
적용된 입력 필드를 무시하도록 봇을 프로그래밍할 수 있습니다. 또한 모든 양식 필드를 자동으로 채우기 위해 일부 형태의 자동 완성(대부분의 브라우저에 내장되어 있는 것처럼!)을 사용하는 사람들에 대해 생각해야 합니다. 그들은 더미 필드를 선택할 수도 있습니다.
더미 필드를 표시하지만 화면 경계 외부에 두어 이를 약간 변경할 수도 있지만 이는 전적으로 사용자에게 달려 있습니다.
참고 : 브라우저 기반 자동 채우기는 채우지 않습니다! 사용자가 입력할 수 없습니다.
창의력을 발휘하십시오!
나는 위의 대답이 "잘못"이라고 생각하지 않지만 건드리지 않은 인증의 넓은 영역이 있습니다(또는 오히려 "사용 가능한 옵션과 거래가 무엇인지"가 아니라 "쿠키 세션을 구현하는 방법"에 중점을 둡니다. -오프".
내가 제안한 수정 사항/답변은 다음과 같습니다.
이렇게 하면 브라우저 자체가 매번 통신을 다시 암호화하므로 "세션"이나 쿠키가 필요하지 않습니다. 가장 "가벼운" 개발 방식입니다.
그러나 공공의 저가 서비스를 제외하고는 이것을 권장하지 않습니다. 이것은 위의 다른 답변 중 일부와 관련된 문제입니다. 서버 측 인증 메커니즘을 다시 구현하지 마십시오. 이 문제는 해결되었으며 대부분의 주요 브라우저에서 지원됩니다. 쿠키를 사용하지 마십시오. 자신의 손으로 만든 데이터베이스에 아무 것도 저장하지 마십시오. 요청이 인증되었는지 여부를 요청당 요청하십시오. 다른 모든 것은 구성 및 타사의 신뢰할 수 있는 소프트웨어에서 지원해야 합니다.
그래서 ...
첫째, 계정의 초기 생성(비밀번호 포함)과 이후의 비밀번호 재확인을 혼동합니다. 내가 Flickr이고 처음으로 사이트를 만드는 경우 새 사용자는 0 값(빈 웹 공간)에 액세스할 수 있습니다. 계정을 만든 사람이 자신의 이름에 대해 거짓말을 하고 있더라도 나는 진정으로 개의치 않습니다. 내가 병원 인트라넷 / 엑스트라 넷의 계정을 생성하고 있다면, 모든 의료 기록의 가치 거짓말, 내가 계정 작성자의 신원 (*)에 대한 관리를 할 수 있도록.
이것은 매우 매우 어려운 부분입니다. 유일한 적절한 솔루션은 신뢰의 웹입니다. 예를 들어 의사로 병원에 합류합니다. 사진, 여권 번호, 공개 키로 어딘가에 호스팅되는 웹 페이지를 만들고 모두 개인 키로 해시합니다. 그런 다음 병원을 방문하면 시스템 관리자가 여권을 보고 사진과 일치하는지 확인한 다음 병원 개인 키로 웹 페이지/사진 해시를 해시합니다. 이제부터 우리는 키와 토큰을 안전하게 교환할 수 있습니다. 병원을 신뢰하는 사람이라면 누구나 할 수 있습니다(비밀 소스 BTW가 있습니다). 시스템 관리자는 RSA 동글 또는 기타 2단계 인증을 제공할 수도 있습니다.
그러나 이것은 많은 번거로움이 있으며 웹 2.0은 아닙니다. 그러나 자체 생성되지 않은 귀중한 정보에 액세스할 수 있는 새 계정을 생성하는 유일한 안전한 방법입니다.
Kerberos 및 SPNEGO(신뢰할 수 있는 타사와의 싱글 사인온 메커니즘)는 기본적으로 사용자가 신뢰할 수 있는 타사에 대해 확인합니다. (NB 이것은 어떤 식 으로든 OAuth를 신뢰할 수 없습니다)
SRP - 신뢰할 수 있는 제3자가 없는 일종의 영리한 암호 인증입니다. 그러나 여기서 우리는 "비용이 더 많이 들더라도 이중 인증을 사용하는 것이 더 안전합니다"의 영역으로 들어가고 있습니다.
SSL 클라이언트 측 - 클라이언트에게 공개 키 인증서를 제공합니다(모든 주요 브라우저에서 지원 - 그러나 클라이언트 시스템 보안에 대한 질문을 제기함).
결국 보안 침해로 인한 비용과 보다 안전한 접근 방식을 구현하는 데 드는 비용의 균형입니다. 언젠가는 적절한 PKI가 널리 수용되어 더 이상 자체 롤링된 인증 양식과 데이터베이스가 없는 것을 보게 될 것입니다. 어느 날...
한 가지 매우 중요한 의견을 추가하고 싶습니다. -
- " 기업의 인트라넷 환경에서" 앞서 말한 모든 사항이 적용되지는 않을 수도 있습니다!
많은 기업이 URL을 통해 구현된 "기업 응용 프로그램"인 "내부 전용" 웹 사이트를 배포합니다. 이 URL은 (아마도 ...) "회사 내부 네트워크" 내에서만 확인할 수 있습니다. (어떤 네트워크가 마법처럼 VPN에 연결된 모든 '로드 워리어'를 포함합니다.)
사용자가 위에서 언급한 네트워크에 충실하게 연결되어 있을 때, 그들의 신원 ("인증") 은 [이미 ...] "결정적으로 알려져 있습니다", ...와 같은 특정 작업을 수행할 수 있는 권한("승인")도 마찬가지입니다. .. "이 웹사이트에 액세스하기 위해."
이 "인증 + 권한 부여" 서비스는 LDAP (Microsoft OpenDirectory) 또는 Kerberos와 같은 여러 다른 기술에서 제공할 수 있습니다.
당신의 관점에서, 당신은 단순히 이것을 알고 있습니다: 합법적으로 당신의 웹사이트에 접속 하는 사람은 누구든지 [마술적으로 포함하는 ...] "토큰"을 동반 해야 합니다. ( 즉 404 Not Found
대한 즉각적인 근거가 되어야 합니다.)
토큰의 가치는 당신에게 의미가 없지만, 필요할 경우 웹사이트가 모든(!) 당신이 가질 수있는 질문. 즉, 당신은 어떤의 자신을 소용이 없습니다 "집에서 성장 논리." 대신, 당신은 당국에 문의하고 암묵적으로 그 판결을 신뢰합니다.
어 ... 그것은 상당히 정신 스위치의 "울리 야생 앤 인터넷."
출처 : http:www.stackoverflow.com/questions/549/the-definitive-guide-to-form-based-website-authentication">