SQL Server CLR Integration 설정 및 보안 가이드

1. CLR Integration 옵션 켜기

CLR을 사용하기 위해서는 sysadmin 권한이 필요합니다.

EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
GO

서비스 영향

  • SQL Server 서비스 재시작 불필요
    RECONFIGURE 실행 시점에 즉시 적용되므로 프로세스가 재시작되지 않습니다.

  • 세션/트랜잭션 영향 없음
    기존 연결 세션, 실행 중인 쿼리, 트랜잭션에는 영향을 주지 않습니다.
    (옵션 플래그만 켜지는 것이므로 DB 멈춤이나 DDL 락은 발생하지 않음)


2. 주의할 점

CLR 활성화 자체는 위험하지 않지만, 이후 어셈블리 배포 및 실행 과정에서 보안 이슈가 발생할 수 있습니다.

  • Permission Set 차이: SAFE / EXTERNAL_ACCESS / UNSAFE
  • TRUSTWORTHY 옵션 여부
  • 해시 기반 어셈블리 신뢰 등록 필요 (sp_add_trusted_assembly)

운영 서버라면 옵션 켜기는 안전하지만, 실제 어셈블리 배포/실행은 반드시 테스트 후 진행을 권장합니다.


3. TRUSTWORTHY 옵션 관리

  • 기본값은 OFF
  • ON으로 설정하면 DB 전체를 “신뢰” 상태로 두어, 소유자 권한 승계를 통한 보안 리스크가 커집니다.
  • 따라서 TRUSTWORTHY ON은 비권장입니다.

🔗 참고: TRUSTWORTHY Database Property (MS Docs)


4. 어셈블리 해시 기반 신뢰 등록

SQLCLR 어셈블리를 등록할 때는 SHA2-512 해시 기반 화이트리스트 등록을 권장합니다.

-- 1) SHA2_512 해시 계산
DECLARE @bin VARBINARY(MAX);
SELECT @bin = BulkColumn
FROM OPENROWSET(BULK 'C:\sqlclr\SqlFunctionLib.dll', SINGLE_BLOB) x;

DECLARE @hash VARBINARY(64) = HASHBYTES('SHA2_512', @bin);
SELECT @hash AS sha2_512_hash; -- 확인용

-- 2) 신뢰 등록
EXEC sys.sp_add_trusted_assembly
     @hash = @hash,
     @description = N'SqlFunctionLib 2025-08-18';

DLL 존재 여부 확인:

EXEC master.dbo.xp_fileexist 'C:\sqlclr\SqlFunctionLib.dll';

5. Permission Set 비교

🔹 SAFE

  • 제한 범위: SQL Server 내부 리소스만 사용 가능
  • 보안성: 가장 안전
  • 제약: 네트워크/파일 접근 불가 → 외부 API 호출 불가

🔹 EXTERNAL_ACCESS

  • 제한 범위: 파일, 네트워크, 레지스트리 등 접근 가능
  • 보안성: 중간 수준
  • 제약: ThreadPool, HttpClient 등 일부 API는 HostProtectionException 발생

🔹 UNSAFE

  • 제한 범위: Full Trust (모든 .NET 기능 사용 가능)
  • 보안성: 가장 위험 (SQL Server 프로세스 권한 그대로 사용)
  • 장점: 네트워크/멀티스레딩 정상 동작 → 외부 API 비동기 호출 가능

👉 외부 API 호출이 필요한 경우 UNSAFE 권한 필요


6. 배포 절차 예시

-- 기존 객체 제거
DROP PROCEDURE [Http_FireAndForgetPost];
DROP ASSEMBLY [SqlFunctionLib];

-- 새 DLL 해시 계산 및 신뢰 등록
DECLARE @bin VARBINARY(MAX);
SELECT @bin = BulkColumn
FROM OPENROWSET(BULK 'C:\sqlclr\SqlFunctionLib.dll', SINGLE_BLOB) AS x;

DECLARE @hash VARBINARY(64) = HASHBYTES('SHA2_512', @bin);
EXEC sys.sp_add_trusted_assembly
     @hash = @hash,
     @description = N'SqlFunctionLib (POST, yyyy-MM-dd HH:mm)';

-- 어셈블리 로드
USE apt_temp01;
CREATE ASSEMBLY [SqlFunctionLib]
FROM 'C:\sqlclr\SqlFunctionLib.dll'
WITH PERMISSION_SET = UNSAFE;

-- 함수 바인딩
CREATE PROCEDURE dbo.Http_FireAndForgetPost
@url NVARCHAR(2048)
AS EXTERNAL NAME [SqlFunctionLib].[HttpAsync].Http_FireAndForgetPost;

7. 발생 가능한 문제 시나리오

  • 보안 위험: 외부 API 악성 응답 → SQL Server 프로세스 권한으로 실행됨
  • 무한 루프/Deadlock 위험: 잘못된 코드 배포 시 DB 서버 전체 영향
  • 방어 방법:
    • DLL 해시 기반 등록(sp_add_trusted_assembly)
    • DLL 배포 경로 및 변경 관리 철저
    • 트리거 내부에서는 반드시 Fire-and-Forget 패턴 사용

8. Fire-and-Forget 패턴

  • 트리거 실행 시 즉시 반환
  • 비동기 ThreadPool에서 외부 API 호출
  • DB 트랜잭션 지연 최소화 → 안정적인 이벤트 처리 가능

✍️ 정리:

  • CLR 옵션 켜기 자체는 안전
  • 실제 DLL 배포는 UNSAFE 필요 → 반드시 신뢰된 DLL만 등록
  • 운영 환경에서는 해시 기반 등록 + Fire-and-Forget 패턴을 조합해야 안전합니다.