가장 일반적인 웹 보안 취약점 10가지

게시 됨: 2022-03-11

너무 많은 회사에서 웹 보안 모범 사례가 우선 순위가 되는 것은 보안 침해가 발생한 입니다. IT 보안 전문가로 일하면서 나는 웹 개발 보안 문제의 세계가 많은 동료 프로그래머에게 얼마나 모호한지 몇 번이고 다시 보았습니다.

웹 보안 위협에 대한 효과적인 접근 방식은 정의상 사전 예방적이고 방어적이어야 합니다. 이를 위해 이 게시물은 보안 사고방식을 촉발하는 것을 목표로 하며, 독자들에게 건전한 편집증을 주입하기를 바랍니다.

특히, 이 가이드는 완화 방법에 대한 권장 사항을 포함하여 알아야 할 10가지 일반적이고 중요한 웹 보안 함정에 중점을 둡니다. 초점은 전 세계적으로 소프트웨어 보안을 개선하는 것을 목표로 하는 국제 비영리 조직인 OWASP(Open Web Application Security Project)에서 식별한 상위 10개의 웹 취약점에 있습니다.

누구도 직면하고 싶지 않은 몇 가지 일반적인 웹 취약점의 예입니다.

시작하기 전에 사이버 보안 입문서 – 인증 및 권한 부여

다른 프로그래머 및 IT 전문가와 이야기할 때 권한 부여와 인증의 구분에 대해 혼동을 겪는 경우가 많습니다. 그리고 물론 약어 auth 가 두 가지 모두에 자주 사용된다는 사실은 이러한 일반적인 혼란을 악화시키는 데 도움이 됩니다. 이 혼란은 너무 흔해서 이 게시물에 "Common Web Vulnerability Zero"로 포함되어야 합니다.

계속 진행하기 전에 이 두 용어의 차이점을 명확히 합시다.

  • 인증: 보안 자격 증명(비밀번호, 보안 질문에 대한 답변, 지문 스캔 등)을 올바르게 제공했기 때문에 사람이 특정 사용자인지(또는 최소한 그렇게 보이는지) 확인합니다.
  • 권한 부여: 특정 사용자에게 특정 리소스에 대한 액세스 권한이 있는지 또는 특정 작업을 수행할 수 있는 권한이 부여되었는지 확인합니다.

달리 말하면 인증 은 엔터티가 누구인지 아는 것이고 권한 부여 는 주어진 엔터티가 무엇을 할 수 있는지 아는 것입니다. 이를 염두에 두고 상위 10가지 인터넷 보안 문제에 대해 알아보겠습니다.

일반적인 웹 보안 실수 #1: 주입 결함

주입 결함은 신뢰할 수 없는 입력을 필터링하는 전형적인 실패로 인해 발생합니다. 필터링되지 않은 데이터를 SQL 서버(SQL 주입), 브라우저(XSS – 나중에 이에 대해 설명함), LDAP 서버(LDAP 주입) 또는 다른 곳으로 전달할 때 발생할 수 있습니다. 여기서 문제는 공격자가 이러한 엔터티에 명령을 주입하여 데이터 손실 및 클라이언트 브라우저 하이재킹을 초래할 수 있다는 것입니다.

애플리케이션이 신뢰할 수 없는 출처로부터 수신하는 모든 것은 가급적 화이트리스트에 따라 필터링해야 합니다 . 블랙리스트를 사용해서는 안 됩니다. 블랙리스트를 바로 잡는 것은 매우 어렵고 일반적으로 우회하기 쉽기 때문입니다. 바이러스 백신 소프트웨어 제품은 일반적으로 실패한 블랙리스트의 뛰어난 예를 제공합니다. 패턴 일치가 작동하지 않습니다.

예방: 좋은 소식은 주입으로부터 보호하는 것이 "단순히" 입력을 적절하게 필터링하고 입력을 신뢰할 수 있는지 여부를 생각하는 문제라는 것입니다. 그러나 나쁜 소식은 의심할 여지 없이 신뢰할 수 있는 경우가 아니면 모든 입력을 적절하게 필터링해야 한다는 것입니다(그러나 여기서 "절대 절대 말하지 말라"는 말이 마음에 들게 함).

예를 들어 1,000개의 입력이 있는 시스템에서 999개의 입력을 성공적으로 필터링하는 것만으로는 충분하지 않습니다. 이렇게 해도 시스템을 중단시키기 위해 아킬레스가 치유될 수 있는 필드가 하나 남아 있기 때문입니다. 그리고 SQL 쿼리 결과를 다른 쿼리에 넣는 것이 좋은 생각이라고 생각할 수도 있습니다. 데이터베이스가 신뢰할 수 있기 때문입니다. 그러나 경계가 신뢰할 수 없는 경우 입력은 악의적인 사용자로부터 간접적으로 옵니다. 관심이 있는 경우 이를 2차 SQL 주입이라고 합니다.

필터링은 (암호화폐처럼) 제대로 하기가 꽤 어렵기 때문에 내가 일반적으로 조언하는 것은 프레임워크의 필터링 기능에 의존하는 것입니다. 프레임워크를 사용하지 않는 경우 서버 보안 컨텍스트에서 프레임워크를 사용하지 않는 것이 정말 의미가 있는지 심각하게 생각해야 합니다. 99%는 그렇지 않습니다.

일반적인 웹 보안 실수 #2: 깨진 인증

이는 인증 실패 중에 발생할 수 있는 여러 문제의 모음이지만 모두 동일한 근본 원인에서 비롯된 것은 아닙니다.

누군가가 2014년에도 여전히 자신의 인증 코드를 실행하기를 원한다고 가정하면(무슨 생각을 하고 있나요??), 저는 이에 반대합니다. 바로잡기가 매우 어렵고 몇 가지만 언급하면 ​​무수히 많은 가능한 함정이 있습니다.

  1. URL에는 세션 ID가 포함될 수 있으며 참조 헤더에서 다른 사람에게 누출될 수 있습니다.
  2. 암호는 저장 또는 전송 시 암호화되지 않을 수 있습니다.
  3. 세션 ID는 예측할 수 있으므로 액세스 권한을 얻는 것이 간단합니다.
  4. 세션 고정이 가능할 수 있습니다.
  5. 세션 하이재킹이 가능하거나 시간 초과가 올바르게 구현되지 않았거나 HTTP(SSL 보안 없음)를 사용하는 등…

예방: 이 웹 보안 취약점을 피하는 가장 간단한 방법은 프레임워크를 사용하는 것입니다. 이것을 올바르게 구현할 수도 있지만 전자가 훨씬 쉽습니다. 자신만의 코드를 만들고 싶다면 극도로 편집증적인 태도를 취하고 함정이 무엇인지 스스로 교육하십시오. 꽤 있습니다.

일반적인 웹 보안 실수 #3: XSS(교차 사이트 스크립팅)

이것은 상당히 널리 퍼진 입력 삭제 실패입니다(기본적으로 일반적인 실수 #1의 특별한 경우). 공격자는 입력 시 웹 애플리케이션 JavaScript 태그를 제공합니다. 이 입력이 삭제되지 않은 상태로 사용자에게 반환되면 사용자의 브라우저가 이를 실행합니다. 링크를 만들고 사용자가 클릭하도록 설득하는 것처럼 간단할 수도 있고 훨씬 더 불길한 것일 수도 있습니다. 페이지 로드 시 스크립트가 실행되고 예를 들어 공격자에게 쿠키를 게시하는 데 사용할 수 있습니다.

예방: 간단한 웹 보안 솔루션이 있습니다. HTML 태그를 클라이언트에 반환하지 마십시오. 여기에는 공격자가 일반 HTML 콘텐츠(예: 이미지 또는 보이지 않는 시끄러운 플래시 플레이어)를 삽입하는 유사한 공격인 HTML 삽입을 방어할 수 있다는 추가 이점이 있습니다. 일반적으로 해결 방법은 모든 HTML 엔터티를 변환하는 것이므로 <script>&lt;script&gt; . 자주 사용되는 다른 정화 방법은 <> 에 정규식을 사용하여 HTML 태그를 제거하기 위해 정규식을 사용하는 것이지만, 많은 브라우저에서 심하게 손상된 HTML을 제대로 해석하므로 이는 위험합니다. 모든 문자를 이스케이프된 문자로 변환하는 것이 좋습니다.

관련: 9가지 필수 시스템 보안 인터뷰 질문

일반적인 웹 보안 실수 #4: 안전하지 않은 직접 개체 참조

이것은 사용자 입력을 신뢰하고 결과적으로 보안 취약점에 대한 대가를 지불하는 전형적인 사례입니다. 직접 개체 참조는 파일 또는 데이터베이스 키와 같은 내부 개체가 사용자에게 노출됨을 의미합니다. 이것의 문제는 공격자가 이 참조를 제공할 수 있고 권한 부여가 시행되지 않거나 손상되면 공격자가 접근하거나 금지되어야 하는 작업을 수행할 수 있다는 것입니다.

예를 들어, 코드에는 CGI 매개변수를 사용하여 파일 이름을 지정하는(예: download.php?file=something.txt ) 파일을 읽고 사용자가 파일을 다운로드할 수 있도록 하는 download.php 모듈이 있습니다. 실수로 또는 게으름으로 인해 개발자가 코드에서 승인을 생략했습니다. 공격자는 이제 이를 사용하여 PHP를 실행하는 사용자가 액세스할 수 있는 모든 시스템 파일(예: 애플리케이션 코드 자체 또는 백업과 같이 서버에 남아 있는 기타 데이터)을 다운로드할 수 있습니다. 어 오.

또 다른 일반적인 취약성 예는 사용자 입력에 의존하여 재설정할 암호를 결정하는 암호 재설정 기능입니다. 유효한 URL을 클릭한 후 공격자는 URL의 username 필드를 수정하여 "admin"과 같이 말할 수 있습니다.

덧붙여서, 이 두 가지 예는 모두 "야생에서" 자주 나타나는 것을 나 자신이 본 것입니다.

예방: 사용자 권한 부여를 적절하고 일관되게 수행하고 선택 항목을 화이트리스트에 추가합니다. 대부분의 경우 데이터를 내부적으로 저장하고 CGI 매개변수를 통해 클라이언트에서 전달되는 데이터에 의존하지 않으면 전체 문제를 피할 수 있습니다. 대부분의 프레임워크에서 세션 변수는 이러한 목적에 매우 적합합니다.

일반적인 웹 보안 실수 #5: 보안 구성 오류

내 경험에 따르면 잘못 구성된 웹 서버와 응용 프로그램은 제대로 구성된 것보다 훨씬 더 일반적입니다. 아마도 이것은 망할 방법이 부족하지 않기 때문일 것입니다. 몇 가지 예:

  1. 프로덕션에서 디버그를 활성화한 상태에서 애플리케이션을 실행합니다.
  2. 서버에서 디렉토리 목록을 활성화하면 귀중한 정보가 누출됩니다.
  3. 오래된 소프트웨어 실행(WordPress 플러그인, 이전 PhpMyAdmin 생각).
  4. 컴퓨터에서 실행 중인 불필요한 서비스가 있습니다.
  5. 기본 키와 암호를 변경하지 않습니다. (당신이 생각하는 것보다 훨씬 더 자주 발생합니다!)
  6. 스택 추적과 같은 오류 처리 정보를 공격자에게 공개합니다.

예방: 배포 시 테스트를 실행할 수 있는 좋은(가능한 자동화된) "빌드 및 배포" 프로세스를 갖습니다. 가난한 사람의 잘못된 보안 구성 솔루션은 기본 암호 및/또는 개발 항목이 내장된 상태로 코드가 나가는 것을 방지하기 위한 사후 커밋 후크입니다.

일반적인 웹 보안 실수 #6: 민감한 데이터 노출

이 웹 보안 취약점은 암호화 및 리소스 보호에 관한 것입니다. 민감한 데이터는 전송 중 및 저장 중을 포함하여 항상 암호화되어야 합니다. 예외 없음. 신용 카드 정보 및 사용자 비밀번호는 절대 여행하거나 암호화되지 않은 상태로 저장되어서는 안 되며 비밀번호는 항상 해시되어야 합니다. 분명히 암호화/해싱 알고리즘은 약한 알고리즘이 아니어야 합니다. 의심스러운 경우 웹 보안 표준은 AES(256비트 이상) 및 RSA(2048비트 이상)를 권장합니다.

그리고 세션 ID와 민감한 데이터가 URL로 이동하지 않아야 하고 민감한 쿠키에 보안 플래그가 켜져 있어야 한다는 것은 말할 필요도 없지만 이는 매우 중요하며 아무리 강조해도 지나치지 않습니다.

방지:

  • 전송 중: 적절한 인증서 및 PFS(Perfect Forward Secrecy)와 함께 HTTPS를 사용합니다. HTTPS가 아닌 연결을 통해 아무 것도 수락하지 마십시오. 쿠키에 보안 플래그를 설정하십시오.

  • 보관 중: 이것은 더 어렵습니다. 무엇보다 노출을 줄여야 합니다. 민감한 데이터가 필요하지 않은 경우 파쇄하십시오. 가지고 있지 않은 데이터는 도난당할 수 없습니다. PCI 호환을 원하지 않을 수 있으므로 신용 카드 정보를 절대 저장 하지 마십시오. Stripe 또는 Braintree와 같은 지불 프로세서에 가입하십시오. 둘째, 실제로 필요한 민감한 데이터가 있는 경우 암호화하여 저장하고 모든 암호가 해시되었는지 확인하십시오. 해싱의 경우 bcrypt를 사용하는 것이 좋습니다. bcrypt를 사용하지 않는 경우 솔트 및 레인보우 테이블에 대해 교육하십시오.

그리고 명백히 언급할 위험이 있으므로 보호된 데이터 옆에 암호화 키를 저장하지 마십시오 . 그것은 열쇠가 들어있는 자물쇠로 자전거를 보관하는 것과 같습니다. 암호화로 백업을 보호하고 키를 매우 비공개로 유지하십시오. 그리고 물론, 열쇠를 잃어버리지 마세요!

일반적인 웹 보안 실수 #7: 기능 수준 액세스 제어 누락

이것은 단순히 권한 부여 실패입니다. 서버에서 함수를 호출할 때 적절한 권한이 부여되지 않았다는 의미입니다. 많은 경우 개발자는 서버 측에서 UI를 생성했다는 사실에 의존하고 서버에서 제공하지 않는 기능은 클라이언트에서 액세스할 수 없다고 생각합니다. 공격자는 항상 "숨겨진" 기능에 대한 요청을 위조할 수 있고 UI가 이 기능에 쉽게 액세스할 수 있도록 하지 않는다는 사실에 의해 저지되지 않기 때문에 그렇게 간단하지 않습니다. /admin 패널이 있고 사용자가 실제로 관리자인 경우에만 버튼이 UI에 있다고 상상해 보십시오. 인증이 누락된 경우 공격자가 이 기능을 발견하고 오용하는 것을 막을 수 있는 것은 없습니다.

예방: 서버 측에서는 항상 권한 부여를 수행해야 합니다. 예, 항상. 어떤 예외나 취약점도 심각한 문제를 일으키지 않습니다.

일반적인 웹 보안 실수 #8: CSRF(Cross Site Request Forgery)

이것은 브라우저가 다른 당사자에게 속아 권한을 남용하는 혼란스러운 대리 공격의 좋은 예입니다. 예를 들어, 제3자 사이트는 사용자의 브라우저가 공격자를 위해 무언가를 할 수 있는 권한을 오용하도록 만들 수 있습니다.

CSRF의 경우, 제3자 사이트는 귀하의 쿠키/세션과 함께 귀하의 브라우저를 사용하여 대상 사이트(예: 귀하의 은행)에 요청을 발행합니다. 예를 들어 은행 홈페이지의 한 탭에 로그인하고 이 공격에 취약한 경우 다른 탭에서 브라우저가 공격자를 대신하여 자격 증명을 오용하여 혼란스러운 대리인 문제가 발생할 수 있습니다. 대리인은 공격자가 지시한 작업을 수행하기 위해 권한(세션 쿠키)을 오용하는 브라우저입니다.

다음 예를 고려하십시오.

공격자 Alice는 Todd의 돈 중 일부를 그녀에게 이체하여 대상 Todd의 지갑을 가볍게 하려고 합니다. Todd의 은행은 CSRF에 취약합니다. 돈을 보내려면 Todd가 다음 URL에 액세스해야 합니다.

http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243

이 URL이 열리면 Todd에게 성공 페이지가 표시되고 전송이 완료됩니다. Alice는 또한 Todd가 자신이 관리하는 blog.aliceisawesome.com에서 다음 스니펫을 배치하는 사이트를 자주 방문한다는 것을 알고 있습니다.

<img src=http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243 width=0 height=0 />

Alice의 웹사이트를 방문하면 Todd의 브라우저는 Alice가 이미지에 연결되어 있다고 생각하고 자동으로 HTTP GET 요청을 보내 사진을 가져오지만 이는 실제로 Todd의 은행에 Alice에게 1500달러를 이체하도록 지시합니다.

덧붙여서, 이 예는 CSRF 취약점을 보여주는 것 외에도 심각한 취약점인 멱등성 HTTP GET 요청으로 서버 상태를 변경하는 방법도 보여줍니다. HTTP GET 요청은 액세스되는 리소스를 변경할 수 없음을 의미하는 멱등성(안전) 이어야 합니다 . 서버 상태를 변경하기 위해 절대로 멱등성 메서드를 사용하지 마십시오.

재미있는 사실: CSRF는 계열사가 더 현명해질 때까지 과거에 사람들이 쿠키를 채우는 데 사용했던 방법이기도 합니다.

예방: 타사 사이트에서 액세스할 수 없는 숨겨진 양식 필드에 비밀 토큰을 저장합니다. 물론 항상 이 숨겨진 필드를 확인해야 합니다. 일부 사이트는 민감한 설정(예: 비밀번호 알림 이메일)을 수정할 때도 비밀번호를 요구하지만, 이는 사용자가 포기한 세션(예: 인터넷 카페)의 오용을 방지하기 위한 것입니다.

일반적인 웹 보안 실수 #9: 알려진 취약점이 있는 구성 요소 사용

제목이 모든 것을 말해줍니다. 나는 이것을 다시 유지 관리/배포 문제로 분류합니다. 새 코드를 통합하기 전에 조사를 수행하고 감사를 수행할 수 있습니다. GitHub 또는 일부 포럼에서 임의의 사람에게서 얻은 코드를 사용하면 매우 편리할 수 있지만 심각한 웹 보안 취약성의 위험이 없는 것은 아닙니다.

예를 들어 사이트가 소유된 경우(즉, 외부인이 시스템에 대한 관리 액세스 권한을 얻은 경우)는 프로그래머가 멍청해서가 아니라 타사 소프트웨어가 프로덕션에서 수년간 패치되지 않은 상태로 남아 있었기 때문입니다. 이것은 예를 들어 WordPress 플러그인에서 항상 발생합니다. 그들이 당신의 숨겨진 phpmyadmin 설치를 찾지 못할 것이라고 생각한다면, 내가 당신에게 dirbuster를 소개하겠습니다.

여기서 교훈은 응용 프로그램이 배포될 때 소프트웨어 개발이 끝나지 않는다는 것입니다. 특히 타사 또는 오픈 소스 구성 요소가 포함된 경우 이를 유지 관리하고 최신 상태로 유지하는 방법에 대한 문서, 테스트 및 계획이 있어야 합니다.

방지:

  • 주의하십시오. 그러한 구성 요소를 사용할 때 분명히 주의를 기울이는 것 외에 복사-붙여넣기 코더가 되지 마십시오. 소프트웨어에 삽입하려는 코드 조각을 주의 깊게 검사하십시오. 복구할 수 없을 정도로 손상되었을 수 있습니다(또는 경우에 따라 의도적으로 악의적인 웹 보안 공격이 이러한 방식으로 무의식적으로 초대되는 경우가 있음).

  • 최신 정보를 유지하세요. 신뢰할 수 있는 모든 항목의 최신 버전을 사용하고 있는지 확인하고 정기적으로 업데이트할 계획을 세우십시오. 최소한 제품과 관련된 새로운 보안 취약점에 대한 뉴스레터를 구독하십시오.

일반적인 웹 보안 실수 #10: 검증되지 않은 리디렉션 및 전달

이것은 다시 한번 입력 필터링 문제입니다. 대상 사이트에 URL을 GET 매개변수로 사용하는 redirect.php 모듈이 있다고 가정합니다. 매개변수를 조작하면 브라우저를 malwareinstall.com 으로 리디렉션하는 URL이 targetsite.com 에 생성될 수 있습니다. 사용자가 링크를 볼 때 사용자는 신뢰할 수 있고 클릭하기에 안전한 targetsite.com/blahblahblah 를 보게 됩니다. 이것이 실제로 악성코드 드롭(또는 다른 악성) 페이지로 전송될 것이라는 사실을 그들은 거의 알지 못합니다. 또는 공격자가 브라우저를 targetsite.com/deleteprofile?confirm=1 로 리디렉션할 수 있습니다.

HTTP 헤더에 정제되지 않은 사용자 정의 입력을 채우는 것은 헤더 주입으로 이어질 수 있다는 점을 언급할 가치가 있습니다.

예방: 옵션에는 다음이 포함됩니다.

  • 리디렉션을 전혀 수행하지 마십시오(거의 필요하지 않음).
  • 리디렉션할 유효한 위치의 정적 목록이 있어야 합니다.
  • 사용자 정의 매개변수를 화이트리스트에 추가하지만 이는 까다로울 수 있습니다.

발문

이 게시물로 여러분의 두뇌를 간지럽히고 편집증과 웹사이트 보안 취약성 인식에 대한 건전한 복용량을 소개할 수 있기를 바랍니다.

여기서 핵심은 오래된 소프트웨어 관행이 이유가 있고 예전에 버퍼 오버플로에 적용되었던 것이 오늘날에도 여전히 Python의 절인 문자열에 적용된다는 것입니다. 보안 프로토콜은 모든 프로그래머가 열망해야 하는 (더 많은) 올바른 프로그램을 작성하는 데 도움이 됩니다.

이 지식을 책임감 있게 사용하고 허가 없이 페이지를 테스트하지 마십시오!

더 자세한 정보와 더 구체적인 서버 측 공격에 대해서는 https://www.owasp.org/index.php/Category:Attack을 참조하십시오.

이 게시물과 완화 조언에 대한 피드백을 환영하고 감사합니다. 특히 DDoS(분산 서비스 거부) 및 구식(웹 아님) IT 보안 취약점 문제에 대한 향후 관련 게시물이 계획되어 있습니다. 어떤 종류의 웹 보호에 대해 작성해야 하는지에 대한 특정 요청이 있는 경우 언제든지 [email protected]으로 직접 연락하십시오.

여기 웹사이트 보안이 있습니다! 건배.

관련된:
  • JSON 웹 토큰 튜토리얼: Laravel 및 AngularJS의 예
  • 성능 및 효율성: HTTP/3 작업