다음을 통해 공유


보안 고려 사항(Entity Framework)

이 문서에서는 Entity Framework 애플리케이션의 개발, 배포 및 실행과 관련된 보안 고려 사항에 대해 설명합니다. 또한 보안 .NET Framework 애플리케이션을 만들기 위한 권장 사항도 따라야 합니다. 자세한 내용은 보안 개요를 참조하세요.

일반 보안 고려 사항

다음 보안 고려 사항은 Entity Framework를 사용하는 모든 애플리케이션에 적용됩니다.

신뢰할 수 있는 데이터 소스 공급자만 사용

데이터 소스와 통신하려면 공급자는 다음을 수행해야 합니다.

  • Entity Framework에서 연결 문자열을 받습니다.
  • 명령 트리를 데이터 소스의 기본 쿼리 언어로 변환합니다.
  • 결과 집합을 어셈블하여 반환합니다.

로그온 작업 중에 사용자 암호를 기반으로 하는 정보가 기본 데이터 소스의 네트워크 라이브러리를 통해 서버로 전달됩니다. 악의적인 공급자가 사용자 자격 증명을 도용하거나, 악성 쿼리를 생성하거나, 결과 집합을 조작할 수 있습니다.

연결을 암호화하여 중요한 데이터 보호

Entity Framework에서는 데이터 암호화를 직접 처리하지 않습니다. 사용자가 공용 네트워크를 통해 데이터에 액세스하는 경우 애플리케이션에서 데이터 소스에 대해 암호화된 연결을 설정하여 보안을 강화해야 합니다. 자세한 내용은 데이터 소스의 보안 관련 설명서를 참조하세요.

연결 문자열 보호

애플리케이션 보안의 가장 중요한 목표 중 하나는 데이터 소스에 대한 액세스를 보호하는 것입니다. 연결 문자열을 안전하게 보호하지 않거나 잘못 생성하면 이로 인해 보안상 취약한 부분이 생길 수 있습니다. 연결 정보를 일반 텍스트로 저장하거나 메모리에 유지하면 전체 시스템을 손상시킬 위험이 있습니다. 다음은 연결 문자열을 보호하기 위한 권장 방법입니다.

  • Azure SQL에 연결할 때 Azure 리소스에 대한 관리 ID를 사용합니다.

    자세한 내용은 Azure 리소스에 대한 관리 ID를 참조하세요.

  • 온-프레미스 SQL Server 데이터 소스에 Windows 인증을 사용합니다.

    Windows 인증을 사용하여 SQL Server 데이터 소스에 연결하면 연결 문자열에 로그온 및 암호 정보가 포함되지 않습니다.

  • 보호되는 구성을 사용하여 구성 파일 섹션을 암호화합니다.

    ASP.NET에서는 구성 파일에서 중요한 정보를 암호화할 수 있도록 보호되는 구성이라는 기능을 제공합니다. 보호되는 구성은 원래 ASP.NET용으로 디자인된 것이지만 Windows 애플리케이션의 구성 파일 섹션을 암호화하는 데도 사용할 수 있습니다.

  • 보안 구성 파일에 연결 문자열을 저장합니다.

    연결 문자열을 소스 코드에 포함하면 안 됩니다. 연결 문자열을 구성 파일에 저장할 수 있으며, 그러면 연결 문자열을 애플리케이션 코드에 포함할 필요가 없습니다. 기본적으로 엔터티 데이터 모델 마법사는 연결 문자열을 애플리케이션 구성 파일에 저장합니다. 무단 액세스를 방지하려면 이 파일을 보호해야 합니다.

  • 동적으로 연결을 만들 때는 연결 문자열 작성기를 사용합니다.

    런타임에 연결 문자열을 생성해야 하는 경우 EntityConnectionStringBuilder 클래스를 사용합니다. 이 문자열 작성기 클래스는 잘못된 입력 정보의 유효성을 검사하고 이스케이프하여 연결 문자열 삽입 공격을 방지합니다. 또한 적절한 문자열 작성기 클래스를 사용하여 Entity Framework 연결 문자열의 일부인 데이터 소스 연결 문자열을 생성합니다. ADO.NET 공급자용 연결 문자열 작성기에 대한 자세한 내용은 연결 문자열 작성기를 참조하세요.

자세한 내용은 연결 정보 보호를 참조하세요.

EntityConnection을 신뢰할 수 없는 사용자에게 노출하지 않음

EntityConnection 개체는 기본 연결의 연결 문자열을 노출합니다. EntityConnection 개체에 액세스할 수 있는 사용자는 기본 연결의 ConnectionState도 변경할 수 있습니다. EntityConnection 클래스는 스레드로부터 안전하지 않습니다.

연결을 보안 컨텍스트 외부로 전달하지 않음

연결이 설정된 후 보안 컨텍스트 외부로 해당 연결을 전달하면 안 됩니다. 예를 들어, 연결을 열 수 있는 권한이 있는 스레드에서 연결을 전역 위치에 저장하면 안 됩니다. 전역 위치에서 연결을 사용할 수 있으면 다른 악성 스레드에서 명시적으로 해당 권한이 부여되지 않아도 열린 연결을 사용할 수 있습니다.

메모리 덤프에서 로그온 정보와 암호를 볼 수도 있음

데이터 소스 로그온 및 암호 정보를 연결 문자열로 제공하는 경우 이 정보는 가비지 컬렉션에서 리소스를 다시 사용할 때까지 메모리에 유지됩니다. 따라서 암호 문자열이 언제 메모리에서 제거되는지 확인할 수 없습니다. 애플리케이션이 충돌할 경우 메모리 덤프 파일에 중요한 보안 정보가 포함될 수 있으며, 애플리케이션을 실행하는 사용자와 컴퓨터에 대한 관리자 액세스 권한을 가진 모든 사용자가 메모리 덤프 파일을 볼 수 있습니다. Microsoft SQL Server 연결에 Windows 인증을 사용합니다.

데이터 소스에서 필요한 권한만 사용자에게 부여함

데이터 소스 관리자는 필요한 권한만 사용자에게 부여해야 합니다. Entity SQL에서 데이터를 수정하는 DML 문(예: INSERT, UPDATE 또는 DELETE)을 지원하지 않는 경우에도 사용자가 데이터 소스에 대한 연결에 액세스할 수 있습니다. 악의적인 사용자는 이 연결을 사용하여 데이터 소스의 기본 언어로 DML 문을 실행할 수 있습니다.

최소 권한으로 애플리케이션 실행

관리되는 애플리케이션이 완전 신뢰 권한으로 실행될 수 있도록 하면 .NET Framework에서 애플리케이션의 컴퓨터 액세스를 제한하지 않습니다. 이로 인해 애플리케이션에서 전체 시스템을 손상시키는 보안상 취약한 부분이 생길 수 있습니다. .NET Framework에서 코드 액세스 보안 및 다른 보안 메커니즘을 사용하려면 부분 신뢰 권한 및 애플리케이션 작동에 필요한 최소 권한 집합으로 애플리케이션을 실행해야 합니다. 다음 코드 액세스 권한은 Entity Framework 애플리케이션에 필요한 최소 권한입니다.

자세한 내용은 Code Access Security and ADO.NET을 참조하세요.

신뢰할 수 없는 애플리케이션을 설치하지 않음

Entity Framework에서는 보안 권한을 적용하지 않으며, 신뢰 여부에 관계없이 프로세스의 모든 사용자 제공 데이터 개체 코드를 호출합니다. 클라이언트 인증 및 권한 부여가 데이터 스토리지 및 해당 애플리케이션에서 수행되는지 확인합니다.

모든 구성 파일에 대한 액세스 제한

관리자는 enterprisesec.config, security.config, machine.conf 및 애플리케이션 구성 파일인 <application>.exe.config를 비롯하여 애플리케이션 구성을 지정하는 모든 파일에 대한 쓰기 권한을 제한해야 합니다.

공급자 고정 이름은 app.config에서 수정할 수 있습니다. 클라이언트 애플리케이션은 강력한 이름을 사용하여 표준 공급자 팩터리 모델을 통해 기본 공급자에 액세스해야 합니다.

모델 및 매핑 파일에 대한 권한 제한

관리자는 모델 및 매핑 파일(.edmx, .csdl, .ssdl 및 .msl)에 대한 쓰기 권한을 모델 또는 매핑을 수정하는 사용자로만 제한해야 합니다. Entity Framework는 런타임 시 이러한 파일에 대해 읽기 액세스 권한만 있으면 됩니다. 또한 관리자는 엔터티 데이터 모델 도구로 생성된 개체 계층 및 미리 컴파일된 뷰 소스 코드 파일에 대한 액세스를 제한해야 합니다.

쿼리의 보안 고려 사항

다음 보안 고려 사항은 개념적 모델을 쿼리할 때 적용됩니다. 이러한 고려 사항은 EntityClient를 사용한 Entity SQL 쿼리와 LINQ, Entity SQL 및 쿼리 작성기 메서드를 사용한 개체 쿼리에 적용됩니다.

SQL 삽입 공격 방지

애플리케이션은 사용자나 다른 외부 에이전트로부터 외부 입력을 받아 그에 기반한 동작을 수행하는 경우가 많습니다. 사용자나 외부 에이전트에서 직접 또는 간접적으로 파생되는 모든 입력에는 인증되지 않은 작업을 수행하기 위해 대상 언어의 구문을 사용하는 콘텐츠가 있을 수 있습니다. 대상 언어가 Transact-SQL과 같은 SQL(구조적 쿼리 언어)인 경우 이 조작을 SQL 삽입 공격이라고 합니다. 악의적인 사용자는 쿼리에 직접 명령을 삽입하고 데이터베이스 테이블을 삭제하거나, 서비스 거부를 발생시키거나, 수행되는 작업의 특성을 다른 방식으로 변경할 수 있습니다.

  • Entity SQL 공격:

    쿼리 조건자 및 매개 변수 이름에 사용되는 값에 악성 입력을 제공하여 Entity SQL에서 SQL 삽입 공격이 수행될 수 있습니다. SQL 삽입 공격의 위험을 방지하려면 Entity SQL 명령 텍스트와 함께 사용자 입력을 결합하면 안 됩니다.

    Entity SQL 쿼리는 해당 리터럴이 허용되는 모든 곳에서 매개 변수를 허용합니다. 외부 에이전트에서 쿼리로 직접 리터럴을 삽입하는 대신 매개 변수가 있는 쿼리를 사용해야 합니다. 또한 쿼리 작성기 메서드를 사용하여 Entity SQL을 안전하게 작성해야 합니다.

  • LINQ to Entities 삽입 공격:

    쿼리는 LINQ to Entities에서 작성할 수 있지만 개체 모델 API를 통해 수행됩니다. LINQ to Entities 쿼리는 Entity SQL 쿼리와 달리 문자열 조작이나 연결을 사용하여 작성되지 않으므로 일반적인 SQL 삽입 공격을 쉽게 받지 않습니다.

결과 집합이 너무 커지지 않도록 방지

결과 집합이 매우 크면 클라이언트에서 결과 집합의 크기에 비례하여 리소스를 사용하는 작업을 수행할 경우 클라이언트 시스템이 종료될 수 있습니다. 결과 집합은 다음 조건에서 매우 커질 수 있습니다.

  • 적절한 필터 조건이 포함되지 않은, 큰 데이터베이스에 대한 쿼리
  • 서버에서 Cartesian 조인을 만드는 쿼리
  • 중첩 Entity SQL 쿼리

사용자 입력을 허용하는 경우 해당 입력으로 인해 결과 집합이 시스템에서 처리할 수 있는 것보다 더 커지지 않도록 해야 합니다. LINQ to Entities의 Take 메서드나 Entity SQL의 LIMIT 연산자를 사용하여 결과 집합의 크기를 제한할 수도 있습니다.

신뢰할 수 없는 호출자에 메서드를 노출할 때 IQueryable 결과를 반환하지 않도록 해야 함

다음과 같은 이유로 신뢰할 수 없는 호출자에 노출되는 메서드에서 IQueryable<T> 형식을 반환하지 않도록 해야 합니다.

  • IQueryable<T> 형식을 노출하는 쿼리의 사용자가 보안 데이터를 노출하거나 결과 집합의 크기를 늘리는 메서드를 결과에 대해 호출할 수 있습니다. 예를 들어 다음과 같은 메서드 시그니처가 있다고 가정합니다.

    public IQueryable<Customer> GetCustomer(int customerId)
    

    이 쿼리의 사용자는 반환된 .Include("Orders") 에 대해 IQueryable<Customer> 를 호출하여 쿼리에서 노출하도록 의도되지 않은 데이터를 검색할 수 있습니다. 메서드의 반환 형식을 IEnumerable<T>로 변경하고 .ToList()와 같이 결과를 구체화하는 메서드를 호출하면 이 문제를 방지할 수 있습니다.

  • IQueryable<T> 쿼리는 결과가 반복될 때 실행되므로 IQueryable<T> 형식을 노출하는 쿼리의 사용자가 throw된 예외를 catch할 수 있습니다. 예외에는 사용자에게 허용되지 않는 정보가 포함될 수 있습니다.

엔터티의 보안 고려 사항

다음 보안 고려 사항은 엔터티 형식을 생성하고 사용할 때 적용됩니다.

애플리케이션 도메인에서 ObjectContext를 공유하지 않음

둘 이상의 애플리케이션 도메인과 ObjectContext를 공유하면 연결 문자열의 정보가 노출될 수 있습니다. 대신, serialized 개체 또는 개체 그래프를 다른 애플리케이션 도메인으로 전송한 다음 해당 애플리케이션 도메인의 ObjectContext에 개체를 연결해야 합니다. 자세한 내용은 개체 직렬화를 참조하세요.

형식 안전성을 위반 방지

형식 안전성을 위반하면 Entity Framework에서 개체의 데이터 무결성을 보장할 수 없습니다. 형식 안전성 위반은 신뢰할 수 없는 애플리케이션이 완전 신뢰 코드 액세스 보안을 사용하여 실행될 수 있도록 하는 경우에 발생할 수 있습니다.

예외 처리

ObjectContext의 메서드 및 속성은 try-catch 블록 내에서 액세스합니다. 예외를 catch하면 처리되지 않은 예외로 인해 ObjectStateManager의 항목이나 테이블 이름 같은 모델 정보가 애플리케이션 사용자에게 노출되는 것을 방지할 수 있습니다.

ASP.NET 애플리케이션의 보안 고려 사항

ASP.NET 애플리케이션에서 경로를 사용할 때 다음을 고려해야 합니다.

호스트에서 경로 검사를 수행하는지 여부 확인

파이프 기호로 묶인 |DataDirectory| 대체 문자열을 사용하면 ADO.NET에서 확인된 경로가 지원되는지 확인합니다. 예를 들어, ".."은 DataDirectory 뒤에 사용할 수 없습니다. 웹 애플리케이션 루트 연산자(~)를 확인하기 위한 동일한 검사는 ASP.NET을 호스트하는 프로세스에서 수행됩니다. IIS는 이 검사를 수행하지만 IIS 이외의 호스트는 확인된 경로가 지원되는지 확인하지 않을 수도 있습니다. Entity Framework 애플리케이션을 배포하는 호스트의 동작을 알고 있어야 합니다.

확인된 경로 이름에 대해 가정하지 않음

루트 연산자(~) 및 DataDirectory 대체 문자열이 확인된 값이 애플리케이션 런타임 동안 일정하게 유지되어야 하는 경우에도 Entity Framework에서는 호스트의 이러한 값 수정을 제한하지 않습니다.

배포 전에 경로 길이 확인

Entity Framework 애플리케이션을 배포하기 전에 루트 연산자(~) 및 DataDirectory 대체 문자열의 값이 운영 체제의 경로 길이 제한을 초과하지 않는지 확인해야 합니다. ADO.NET 데이터 공급자는 경로 길이가 유효한 제한 범위 내에 있는지 확인하지 않습니다.

ADO.NET 메타데이터의 보안 고려 사항

다음 보안 고려 사항은 모델 및 매핑 파일을 생성하고 사용할 때 적용됩니다.

로깅을 통해 중요한 데이터를 노출하지 않음

ADO.NET 메타데이터 서비스 구성 요소는 개인 정보를 기록하지 않습니다. 액세스 제한으로 인해 반환할 수 없는 결과가 있을 경우 데이터베이스 관리 시스템과 파일 시스템에서 중요한 정보가 포함될 수 있는 예외를 발생시키는 대신 0개 결과를 반환해야 합니다.

신뢰할 수 없는 소스의 MetadataWorkspace 개체를 허용하지 않음

애플리케이션에서 신뢰할 수 없는 소스의 MetadataWorkspace 클래스 인스턴스를 허용하면 안 됩니다. 대신, 명시적으로 작업 영역을 생성하고 해당 소스에서 채워야 합니다.

참고 항목