내용으로 건너뛰기
ASP.NET 에서 안전한 응용 프로그램을 작성하기 위한 10가지 팁

ASP.NET 에서 안전한 응용 프로그램을 작성하기 위한 10가지 팁

보안은 모든 응용 프로그램의 가장 중요한 측면 중 하나이며, 특히 ASP.NET 응용 프로그램에서 보안에 대해 이야기 할 때 개발에만 국한되지 않습니다.

10min read

보안은 모든 응용 프로그램의 가장 중요한 측면 중 하나이며, 특히 ASP.NET 응용 프로그램에서 보안에 대해 이야기 할 때 개발에만 국한되지 않습니다.

보안 앱에는 구성, 프레임워크, 웹 서버, 데이터베이스 서버 등에 여러 계층의 보안이 포함됩니다. 이 게시물에서는 ASP.NET 에서 보안 애플리케이션을 작성하기 위한 상위 9가지 팁을 살펴보겠습니다.

1. Cross Site Scripting (XSS)

이 취약점을 통해 공격자는 데이터를 입력하는 동안 일부 악성 코드를 주입할 수 있습니다. JavaScript 코드, VB 스크립트 또는 기타 스크립트 코드일 수 있습니다. 기본적으로 ASP.NET MVC는 입력의 유효성을 검사하고 스크립트의 경우 서버 오류를 발생시킵니다. 스크립트를 입력 양식에 넣었다고 가정 해보십시오.

 registration form

위의 페이지를 제출하면 다음과 같은 오류가 발생합니다.

위의 페이지를 제출하면 오류가 발생합니다.

기본적으로 Razor 뷰 엔진은 XSS 공격으로부터 보호합니다. 그러나 입력 컨트롤에서 html 태그를 허용해야 할 수도 있는 특정 시나리오(블로깅, 소셜 애플리케이션 등)가 있습니다. 이를 위해 ValidateInput 필터를 false로 추가하는 옵션이 있습니다.

[HttpPost]
[ValidateInput(false)]
public async Task < ActionResult > Register(RegisterViewModel model) {
    if (ModelState.IsValid) {
        //  Etc.
    }
}

그러나 여기서는 완전한 요청을 검증하지 않기 때문에 이것은 매우 위험합니다. 모델에 20 개의 속성이 있다고 가정하면 모두 유효성 검사에서 면제되지만 하나 또는 몇 개의 컨트롤에서만 html을 허용해야 할 수도 있습니다.

이 시나리오에서는 이 ValidateInput을 사용하는 대신 특정 ViewModel의 속성에 AllowHTML 속성을 다음과 같이 배치해야 합니다.

public class RegisterViewModel {
    [Required]
    [AllowHtml]
    [Display(Name = "User Name")]
    public string Name {
        get;
        set;
    }
...
}

이제 이름에만 태그를 사용할 수 있습니다.

2. 교차 사이트 자원 위조(CSRF)

CSRF(원 클릭 공격이라고도 함)는 사용자가 인증된 신뢰할 수 있는 웹 사이트에서 무단 명령이 실행되는 악성 공격 유형입니다. 실제 시나리오에서 사용자가 Windows / 쿠키 기반 인증을 사용하여 응용 프로그램에 로그인했다고 가정 해보십시오. 이제 사용자는 로그아웃하지 않고 악성 사이트를 방문하여 버튼을 클릭합니다. 외부 웹사이트는 귀하의 웹사이트를 통해 비윤리적인 작업을 수행하기 위한 요청을 시작합니다. 요청이 인증되었기 때문에 유효한 요청으로 간주됩니다.

CSRF 공격을 방지하기 위해 MVC는 AntiForgeryToken 메커니즘을 제공합니다. 이를 위해 AntiForgeryToken 도우미를 다음과 같이 사용해야 합니다.

@Html.AntiForgeryToken()

토큰을 검증하려면 다음과 같이 액션에 Antiforgerytoken 필터를 배치해야 합니다.

[ValidateAntiForgeryToken]
public async Task < ActionResult > Register(RegisterViewModel model) {
    if (ModelState.IsValid) {
        // etc.
    }
    return View(model);
}

응답으로 두 개의 토큰을 생성하며, 하나는 쿠키로 설정되고 다른 하나는 숨겨진 필드에 다음과 같이 설정됩니다.

<form action="/Account/Register" class="form-horizontal" method="post" role="form">
<input name="__RequestVerificationToken" type="hidden" value="Qorw9RPABdHoRC7AojnSnQYYuGZP5iPF63UFVSw_[…]" />

양식을 제출하는 동안 두 토큰(쿠키 및 숨겨진 필드)이 모두 서버로 전송됩니다. 둘 다 서버에서 유효성이 검사되며, 둘 중 하나가 없거나 변조된 경우 요청이 허용되지 않습니다.

3. Handling Errors Properly

오류는 발생하기 마련이며 사용자에게 도달하는 방법을 찾습니다. 그러나 제대로 처리하지 않으면 오류로 인해 내부 정보가 외부로 유출되어 응용 프로그램에 위협이 될 수 있습니다. 다음 YSOD는 처리되지 않은 예외가 발생할 때 일반적입니다.

그러나 내부 코드, 물리적 파일 구조, 스택 추적, ASP.NET 및 .NET 프레임워크 버전 등 외부 세계에 얼마나 많은 정보를 표시하는지 확인하십시오.

한 가지 빠른 수정은 customErrors 모드를 다음과 같이 설정하는 것입니다.

<customErrors mode="On"></customErrors> 

이렇게 하면 각 오류가 발생할 경우 ASP.NET 기본 오류 페이지가 표시됩니다. 더 나은 방법으로 처리하려면 사용자 지정 오류 모드 RemoteOnly를 사용하고 오류 발생 시 표시되는 공통 오류 페이지를 사용하십시오.

<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/Error.aspx" />

여기에서는 오류가 발생한 경우 자체 오류 페이지를 표시합니다.

4. SQL 주입

SQL 삽입은 잘 알려진 보안 취약점이지만 여전히 많은 응용 프로그램에서 제대로 처리되지 않습니다. SQL 인젝션을 통해 해커는 기존 데이터를 변조하거나 트랜잭션을 수정하거나 데이터 또는 데이터베이스를 삭제할 수 있으며, 이는 비즈니스에 큰 손실이 될 수 있습니다.

이 기술을 사용하여 해커는 입력을 통해 일부 악성 SQL 명령을 주입합니다. 이러한 명령은 서버에서 실행 중인 SQL 문을 변경할 수 있는 권한이 있습니다.  응용 프로그램에서 사용자를 인증한다고 가정하면 클래스에 쿼리를 다음과 같이 작성했습니다.

"select * from Users where UserName='"+txtUserName.Text+"'and Password='"+txtPwd.Text+"' ";

이제 사용자는 사용자 이름에 다음 값을 입력합니다.

이제 쿼리가 서버에서 다음과 같이 생성됩니다.

select * from Users where UserName='’ or 1=1 --' and Password='"+txtPwd.Text+"' ";

이렇게 하면 항상 항목이 반환되고 사용자가 응용 프로그램에 들어갈 수 있습니다.

이를 처리하는 가장 좋은 방법은 값을 매개 변수로 전달하거나 최소한 매개 변수를 다음과 같이 사용하는 SQL 저장 프로 시저를 사용하는 것입니다.

"select * from Users where UserName= @username and Password=@password”

5. Click-Jacking

Click-Jacking은 일반적으로 무시되는 또 다른 주요 취약점입니다. 이 경우 공격자는 불투명 계층을 사용하여 사용자가 최상위 페이지를 클릭하려고 하는 동안 다른 페이지(예: 은행 웹 사이트의 송금 버튼)에 있는 버튼이나 링크를 클릭하도록 속입니다.

이 문제를 방지하려면 iframe에서 다른 도메인의 웹 사이트가 열리지 않도록 허용해서는 안 됩니다. 이를 위해 응답 헤더 X-FRAME-OPTIONS를 deny 또는 sameorigin으로 추가해야 합니다. ASP.NET 에서는 Global.asax에서 다음과 같이 설정할 수 있습니다.

void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("X-FRAME-OPTIONS ", "DENY");
}

응용 프로그램에서 보낸 모든 응답에 헤더를 추가합니다.

IIS를 사용하여 동일한 헤더를 추가할 수도 있습니다. IIS에서 원하는 웹 사이트로 이동하여 HTTP 헤더 탭으로 이동하여 설명된 대로 X-FRAME-OPTIONS 헤더가 있는 사용자 지정 헤더를 추가합니다. 적용하려면 IIS를 다시 시작해야 합니다.

6. 응용 프로그램 구조/디렉토리 목록 숨기기

응용 프로그램의 폴더 구조를 최종 사용자와 공유하시겠습니까?  아니요! 오른쪽? 예를 들어 보겠습니다. IIS ASP.NET 웹 양식 기본 응용 프로그램을 배포했기 때문에 URL에 액세스하면 다음과 같이 표시됩니다.

IIS에 배포 된 ASP.NET 웹 양식 기본 응용 프로그램이므로 URL에 액세스 할 때

계정에서 사용할 수 있는 모든 파일과 폴더가 표시됩니다. 이 정보는 공개적으로 사용할 수 있는 경우 응용 프로그램에 잠재적인 위협이 될 수 있습니다.

IIS에서 디렉터리 검색을 사용하지 않도록 설정해야 합니다. 비활성화되면 다음이 표시됩니다.

IIS에서 디렉터리 검색을 사용하지 않도록 설정해야 합니다. 비활성화된 경우

403(사용할 수 없음)을 반환하지만 사용자에게 이 폴더를 사용할 수 있음을 알려주기 때문에 여전히 몇 가지 취약점이 남아 있습니다. 사용할 수 없는 디렉토리에 액세스하려고 하면 404가 반환됩니다.

이를 위해 자체 사용자 지정 http 핸들러를 작성하고 누군가가 폴더에 액세스하려고 할 때마다 항상 404를 반환하도록 구성할 수 있습니다.

7. Encrypt Sensitive Information in Web.config

많은 경우 Web.config에 중요한 정보, 가장 일반적으로 연결 문자열을 입력합니다.

연결 문자열의 일부를 암호화하려면 명령 프롬프트에서 프레임워크 폴더(예: C:\Windows\Microsoft.NET\Framework\v4.0.30319 )로 이동하여 다음 명령을 실행해야 합니다.

aspnet_regiis -pef "connectionStrings" path

여기서 path는 Web.config가 있는 폴더의 경로입니다. 명령을 실행하면 다음과 같이 표시됩니다.

path는 Web.config가 있는 폴더의 경로입니다

마찬가지로 <appsettings> 등과 같은 다른 섹션을 암호화할 수 있습니다.

8. Secure Cookies

쿠키는 브라우저가 사용자의 컴퓨터에 저장하는 작은 텍스트로, 웹 서버와 브라우저 사이를 이동합니다. 쿠키는 특정 웹 사이트에 대한 사용자 관련 정보를 저장하는 데 사용됩니다. ASP.NET 에서 세션 ID는 쿠키가 저장되는 가장 일반적인 정보 중 하나입니다.

이 정보는 사용자의 컴퓨터에 일반 텍스트로 저장되므로 공격자에게 쉬운 표적이 될 수 있습니다. 만료 날짜 설정 및 데이터 암호화와 같이 쿠키에 데이터를 저장하지 않기 위해 수행해야 하는 몇 가지 단계가 있습니다. 이 두 단계 외에도 수행해야 할 두 가지 작업이 더 있습니다.

  1. SSL에서만 쿠키 허용
  2. 쿠키를 HTTPOnly로 설정합니다. 이렇게하면 클라이언트 측 스크립트에서 쿠키를 읽을 수 없으므로 세션 또는 양식 인증 토큰이 브라우저에서 읽을 수 없습니다.

Web.config에서 다음과 같이 설정할 수 있습니다.

<httpCookies domain="String" httpOnlyCookies="true "requireSSL="true " />

9. Encrypting View State

뷰 상태는 ASP.NET Web Form에서 Page PostBack 간의 상태를 유지 관리하는 데 사용되는 가장 일반적인 기술 중 하나입니다. 뷰 상태는 id__VIEWSTATE와 함께 페이지의 숨겨진 변수에 저장됩니다. 뷰 소스에서 이를 볼 때 일련의 숫자와 문자가 포함되어 있음을 알 수 있습니다. 암호화되지 않고 base64 형식인지 확인하십시오. 누구나 정보를 읽기 위해 디코딩 할 수 있습니다.

암호화하고 변조 방지를 위한 두 가지 옵션이 있습니다. ViewStateEncryptionMode 속성은 aspx 파일의 페이지 수준에서 설정하거나 응용 프로그램의 모든 페이지에 적용되는 Web.config에서 설정할 수 있습니다. 응답에 넣기 전에 뷰 상태를 암호화합니다. 마찬가지로 다른 속성인 EnableViewStateMac은 페이지 또는 Web.config에서 true로 설정할 수 있습니다. 보기 상태 콘텐츠의 해시를 만들고 숨겨진 필드에 추가합니다. 다음 게시물에서 다시 해시가 생성되고 확인됩니다. 일치하지 않으면 포스트백이 거부되고 오류가 발생합니다.

10. 응답 헤더에서 중요한 정보 제거

다음은 ASP.NET 응용 프로그램 페이지의 응답 헤더입니다.

여기서 우리는 IIS 버전, 구축 된 사이트 및 ASP.NET 버전과 같이 필요하지 않은 최종 사용자에게 너무 많은 정보를 공개하고 있음을 알 수 있습니다. 공격자가 이러한 취약점의 허점을 알고 있다면 취약점을 악용할 수 있습니다. 이 정보는 기본적으로 추가되며 특별히 필요하지 않는 한 제거해야 합니다.

  1. 버전 헤더를 ASP.NET 제거하려면 Web.config에 다음을 추가하기만 하면 됩니다.
<system.web>
  <httpRuntime enableVersionHeader="false" />
</system.web>
  1. MVC 버전을 제거하려면 Global.asax​ ​AppliCation_Start 이벤트로 이동하여 다음 코드를 추가해야 합니다.
MvcHandler.DisableMvcResponseHeader = true;
  1. X-Power-By는 IIS에 의해 추가되며 다음 구성을 추가하여 제거할 수 있습니다
  <system.webServer>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By" />
            </customHeaders>
        </httpProtocol>
  </system.webServer>

결론

이 게시물에서는 보안이 모든 웹 애플리케이션의 핵심이며 제대로 처리하지 않으면 비즈니스에 큰 피해를 줄 수 있다는 점에 대해 논의했습니다. 우리는 ASP.NET 웹 애플리케이션의 가장 일반적인 취약점 중 9가지에 대해 논의했으며 이러한 취약점의 대부분은 일부 구성 변경이나 사소한 코드 변경을 통해 수정할 수 있음을 확인했습니다.

Infragistics ASP.NET 컨트롤이 있는 모든 브라우저에서 사용할 수 있는 모든 기능을 갖춘 비즈니스 앱을 구축하세요! 지금 무료 평가판을 다운로드하세요.

데모 요청