데이터 액세스 보안

업데이트: 2007년 11월

대부분의 ASP.NET 웹 응용 프로그램에는 데이터 액세스가 포함됩니다. 여러 응용 프로그램에서는 데이터를 수집하여 데이터베이스나 파일에 저장하며, 저장되는 데이터는 주로 사용자로부터 제공되는 정보를 기반으로 합니다. 기본 데이터의 출처를 신뢰할 수 없는 경우가 있고, 정보는 영구적인 형식으로 저장되며, 권한이 없는 사용자가 데이터 소스에 직접 액세스하지 못하도록 확인해야 하므로, 데이터 액세스와 관련된 보안 문제에 대해 특별한 주의를 기울여야 합니다. 이 항목에서는 사용자의 ASP.NET 웹 응용 프로그램에서 데이터 액세스에 대한 보안을 향상시킬 수 있는 최선의 구현 방법에 대해 설명합니다.

다음과 같은 코딩 및 구성에 대한 최선의 구현 방법으로 응용 프로그램의 보안을 향상시킬 수 있지만, Microsoft Windows 및 IIS(인터넷 정보 서비스)에 대한 최신 보안 업데이트 뿐만 아니라 Microsoft SQL Server나 다른 데이터 소스 소프트웨어에 대한 모든 보안 업데이트를 사용하여 웹 서버를 최신 상태로 계속 유지하는 것도 중요합니다.

보안 코드 작성 및 응용 프로그램 보안을 위한 최선의 구현 방법에 대해서는 Michael Howard 및 David LeBlanc가 공동으로 저술한 책인 "Writing Secure Code" 또는 Microsoft Patterns and Practices 웹 사이트에서 제공하는 지침을 참조하십시오.

데이터 소스에 대한 액세스 보안

다음 단원에서는 데이터 액세스의 서로 다른 측면을 보안하는 데 도움이 되는 정보를 제공합니다.

연결 문자열

데이터베이스에 연결하려면 연결 문자열이 필요합니다. 연결 문자열에는 중요한 데이터가 포함될 수 있으므로 다음 지침을 따라야 합니다.

통합 보안을 사용하여 SQL Server에 연결

가능하면 명시적인 사용자 이름과 암호를 사용하는 대신 통합 보안을 사용하여 SQL Server 인스턴스에 연결하십시오. 이렇게 하면 연결 문자열이 손상되고 사용자 ID와 암호가 노출될 가능성이 낮아집니다.

ASP.NET을 실행 중인 프로세스 ID(예: 응용 프로그램 풀)가 기본 프로세스 계정인지 아니면 제한된 사용자 계정인지 확인하는 것이 좋습니다. 자세한 내용은 ASP.NET 가장을 참조하십시오.

여러 웹 사이트에서 서로 다른 SQL Server 데이터베이스에 연결된 경우에는 통합 보안을 사용하지 않는 것이 좋을 수 있습니다. 예를 들어 웹 호스팅 사이트에서 각 고객에게는 일반적으로 서로 다른 SQL Server 데이터베이스가 할당되지만 모든 사용자는 익명 사용자 계정으로 웹 서버를 사용합니다. 이러한 경우에는 SQL Server의 인스턴스로 연결하려면 명시적 자격 증명을 사용해야 합니다. 자격 증명은 이 항목의 연결 문자열에서 설명한 것과 같이 안전한 방식으로 저장되어야 합니다.

SQL Server 데이터베이스 권한

응용 프로그램에서 사용되는 SQL Server 데이터베이스에 연결할 때 필요한 사용자 ID에는 최소 권한을 할당하는 것이 좋습니다.

SQL 작업 제한

데이터 바인딩된 컨트롤에서는 데이터 테이블 레코드의 선택, 삽입, 삭제 및 업데이트와 같은 다양한 데이터 작업을 지원합니다. 데이터 컨트롤은 페이지나 사용자 응용 프로그램에 필요한 최소한의 기능만 수행하도록 구성하는 것이 좋습니다. 예를 들어 컨트롤에서 삭제 작업이 허용되지 않는 경우 데이터 소스 컨트롤에 삭제 쿼리를 포함하지 않도록 하며 컨트롤에서 삭제를 사용하지 않도록 하십시오.

SQL Server Express Edition

프로세스에서 SQL Server Express Edition 데이터베이스(.mdf 파일)에 연결하는 경우 해당 프로세스에 관리 권한이 있어야 합니다. 그러므로 일반적으로 프로덕션 웹 사이트에서는 SQL Server Express Edition 데이터베이스를 사용하지 않는 것이 좋습니다. ASP.NET 프로세스는 관리 권한으로 실행되지 않으며, 실행되어서도 안 됩니다. 따라서 SQL Server Express Edition 데이터베이스는 다음과 같은 경우에만 사용하십시오.

  • 웹 응용 프로그램을 개발하는 동안 테스트 데이터베이스로 사용합니다. 응용 프로그램을 배포할 준비가 되면 SQL Server Express Edition에서 SQL Server의 프로덕션 인스턴스로 데이터베이스를 전송할 수 있습니다.

  • 가장을 사용할 수 있는 웹 사이트를 실행 중이고 가장된 사용자의 권한을 제어할 수 있는 경우에 사용합니다. 실제로 이러한 전략은 공용 웹 사이트가 아닌 LAN에서 응용 프로그램을 실행하는 경우에만 실용적입니다.

  • App_Data 폴더의 내용은 직접 HTTP 요청으로 반환되지 않으므로 사이트의 App_Data 폴더에 .mdf 파일을 저장합니다. 또한 사이트의 Web.config 파일에서 다음 요소를 사용하여 IIS의 ASP.NET 및 ASP.NET의 HttpForbiddenHandler 처리기에 .mdf 확장명을 매핑해야 합니다.

    <httpHandlers>
      <add verb="*" path="*.mdf" type="System.Web.HttpForbiddenHandler" />
    </httpHandlers>
    

    파일 이름 확장명을 IIS의 ASP.NET에 매핑하는 방법에 대한 자세한 내용은 방법: HTTP 처리기 등록을 참조하십시오.

Microsoft Access 데이터베이스

Microsoft Access 데이터베이스(.mdb 파일)의 보안 기능은 SQL Server 데이터베이스보다 적습니다. Access 데이터베이스는 프로덕션 웹 사이트에 권장되지 않습니다. 하지만 웹 응용 프로그램의 일부로 .mdb 파일을 사용해야 하는 경우에는 다음 지침을 따르십시오.

  • App_Data 폴더의 내용은 직접 HTTP 요청으로 반환되지 않으므로 사이트의 App_Data 폴더에 .mdb 파일을 저장합니다. 또한 사이트의 Web.config 파일에서 다음 요소를 사용하여 IIS의 ASP.NET 및 ASP.NET의 HttpForbiddenHandler 처리기에 .mdb 확장명을 매핑해야 합니다.

    <httpHandlers>
      <add verb="*" path="*.mdb" type="System.Web.HttpForbiddenHandler" />
    </httpHandlers>
    

    파일 이름 확장명을 IIS의 ASP.NET에 매핑하는 방법에 대한 자세한 내용은 방법: HTTP 처리기 등록을 참조하십시오.

  • .mdb 파일에서 읽기 및 쓰기를 수행할 사용자 계정에 적합한 권한을 추가합니다. 웹 사이트에서 익명 액세스가 지원되는 경우 이 계정은 일반적으로 로컬 ASPNET 사용자 계정이나 NETWORK SERVICE 계정입니다. Access에서는 잠금을 지원하기 위해 .ldb 파일을 만들어야 하므로 사용자 계정에는 .mdb 파일이 포함된 폴더에 대한 쓰기 권한이 있어야 합니다.

  • 데이터베이스가 암호로 보호되는 경우, AccessDataSource 컨트롤은 자격 증명 전달을 지원하지 않으므로 AccessDataSource 컨트롤을 사용하여 데이터베이스에 대한 연결을 설정하지 마십시오. 대신 ODBC 공급자에서 SqlDataSource 컨트롤을 사용하여 연결 문자열의 자격 증명을 전달하십시오. 연결 문자열은 이 항목의 연결 문자열에서 설명한 것과 같이 보호되어야 합니다.

XML 파일

XML 파일에 데이터를 저장할 경우 폴더의 내용이 HTTP 요청에 대한 응답으로 직접 반환되지 않도록 웹 사이트의 App_Data 폴더에 XML 파일을 두어야 합니다.

악의적인 사용자 입력으로부터 보호

응용 프로그램에서 사용자 입력을 받는 경우, 응용 프로그램을 손상시킬 수 있는 악의적인 내용이 입력에 포함되지 않도록 해야 합니다. 악의적인 사용자 입력은 다음과 같은 공격을 시작하는 데 사용될 수 있습니다.

  • 스크립트 삽입   스크립트 삽입 공격은 다른 사용자가 실행하도록 만들려는 의도로 실행 스크립트를 사용자의 응용 프로그램으로 보냅니다. 일반적인 스크립트 삽입 공격에서는 데이터베이스에 스크립트를 저장하는 페이지로 스크립트를 보냅니다. 그런 다음 데이터를 보는 다른 사용자가 우연히 코드를 실행하도록 합니다.

  • SQL 삽입   SQL 삽입 공격은 응용 프로그램에 작성되어 있는 명령 대신(또는 명령과 함께) 실행할 SQL 명령을 만들어서 데이터베이스(및 데이터베이스가 실행되는 컴퓨터)를 손상시킵니다.

일반 지침

모든 사용자 입력에 대해 다음 지침을 따르십시오.

  • 가능하면 사용자 입력을 허용 가능한 값으로 제한하는 유효성 검사 컨트롤을 사용하십시오.

  • 서버 코드를 실행하기 전에 IsValid 속성의 값이 true인지 항상 확인해야 합니다. 값이 false이면 하나 이상의 유효성 검사 컨트롤에서 유효성 검사에 실패했음을 나타냅니다.

  • 브라우저에서 클라이언트측 유효성 검사를 수행하는 경우라도 항상 서버측 유효성 검사를 수행하여 사용자가 클라이언트측 유효성 검사를 건너뛰지 못하도록 해야 합니다. 이 방법은 CustomValidator 컨트롤의 경우에 특히 중요합니다. 클라이언트측 유효성 검사 논리만 사용하지 마십시오.

  • 응용 프로그램의 비즈니스 계층에서 항상 사용자 입력에 대한 유효성을 다시 검사하십시오. 안전한 데이터를 제공하기 위한 방법으로 호출 프로세스에만 의존하지 마십시오. 예를 들어 ObjectDataSource 컨트롤을 사용하는 경우 데이터 업데이트를 수행하는 개체에 중복되는 유효성 검사 및 인코딩을 추가하십시오.

스크립트 삽입

스크립트 삽입 공격을 피하려면 다음 지침을 따르십시오.

  • HTML을 해당 텍스트 표현으로 바꾸고(예: <b>를 &ltb&gt;로 변환) 태그가 브라우저에서 실행되지 않도록 방지하는 HtmlEncode 메서드로 사용자 입력을 인코딩합니다.

  • 사용자 입력을 쿼리로 전달하기 위해 매개 변수 개체를 사용할 때, 데이터 소스 컨트롤의 쿼리 전 이벤트 처리기를 추가하고 이러한 이벤트에서 인코딩을 수행합니다. 예를 들어 쿼리를 실행하기 전에 SqlDataSource 컨트롤의 Inserting 이벤트를 처리하고 이벤트에서 매개 변수 값을 인코딩합니다.

  • 바인딩된 필드에 GridView 컨트롤을 사용하는 경우 BoundField 개체의 HtmlEncode 속성을 true로 설정합니다. 이렇게 하면 행이 편집 모드일 때 GridView 컨트롤에서 사용자 입력을 인코딩합니다.

  • 편집 모드로 둘 수 있는 컨트롤의 경우에는 템플릿을 사용하는 것이 좋습니다. 예를 들어 GridView, DetailsView, FormView, DataListLogin 컨트롤은 편집 가능한 텍스트 상자를 표시할 수 있습니다. 하지만 GridView 컨트롤을 제외한 나머지 컨트롤에서는 사용자 입력에 대한 유효성 검사나 HTML 인코딩이 자동으로 수행되지 않습니다(이전 내용 참조). 따라서 이러한 컨트롤에 대해서는 템플릿을 만들고 해당 템플릿에 TextBox 컨트롤과 같은 입력 컨트롤을 포함한 다음 유효성 검사 컨트롤을 추가하는 것이 좋습니다. 또한 컨트롤의 값을 추출할 때에도 인코딩을 수행해야 합니다.

SQL 삽입

SQL 삽입 공격을 피하려면 다음 지침을 따르십시오.

  • 특히 사용자의 입력이 포함된 문자열과 같은 문자열을 함께 연결하여 SQL 명령을 만들지 마십시오. 대신 매개 변수가 있는 쿼리나 저장 프로시저를 사용하십시오.

  • 매개 변수가 있는 쿼리를 만드는 경우에는 매개 변수 개체를 사용하여 해당 매개 변수에 대한 값을 설정하십시오. 자세한 내용은 SqlDataSource 컨트롤에 매개 변수 사용데이터 소스 컨트롤에 매개 변수 사용을 참조하십시오.

뷰 상태 데이터 암호화

GridView 컨트롤과 같은 데이터 바인딩된 컨트롤에서는 중요한 정보를 계속 유지해야 하는 경우가 있습니다. 예를 들어 GridView 컨트롤은 정보가 표시되지 않더라도 DataKeys 속성에 키 목록을 유지 관리할 수 있습니다. 라운드트립 사이에 컨트롤은 정보를 뷰 상태에 저장합니다.

뷰 상태 정보는 인코딩되어 페이지의 내용과 함께 저장되며 디코딩되어 원하지 않는 소스에 노출될 수 있습니다. 뷰 상태에 중요한 정보를 저장해야 하는 경우에는 페이지에서 뷰 상태 데이터를 암호화하도록 요청할 수 있습니다. 데이터를 암호화하려면 페이지의 ViewStateEncryptionMode 속성을 true로 설정합니다.

캐싱

클라이언트 가장이 설정되어 있고 클라이언트 ID에 따라 데이터 소스의 결과를 검색하는 경우, Cache 개체에 중요한 정보를 저장하지 않는 것이 좋습니다. 캐싱이 설정되면 단일 사용자에 대해 캐시된 데이터를 모든 사용자가 볼 수 있으며 원하지 않는 소스에 중요한 정보가 노출될 수 있습니다. identity 구성 요소의 impersonate 특성이 true로 설정되고 웹 서버에서 응용 프로그램에 대해 익명 ID를 사용할 수 없는 경우 클라이언트 가장이 사용됩니다.

참고 항목

개념

표준 컨트롤 보안

기타 리소스

ASP.NET 웹 사이트 보안