/////

PostgreSQL RLS 테넌트 격리 실패 모드: 소유자 우회, SECURITY DEFINER와 커넥션 풀 컨텍스트 누출

PostgreSQL의 Row-Level Security(RLS)는 테넌트 격리의 한 층이 될 수 있지만, 정책이 존재한다는 사실만으로 모든 데이터 접근 경로가 격리되는 것은 아니다. 테이블 소유자·BYPASSRLS 역할의 우회, SECURITY DEFINER 함수의 실행 권한, 커넥션 풀에서 재사용되는 세션 상태를 각각 별도의 권한 경계로 점검해야 한다. (postgresql.org)

/////

Summary#

PostgreSQL의 Row-Level Security(RLS)는 테넌트 격리의 한 층이 될 수 있지만, 정책이 존재한다는 사실만으로 모든 데이터 접근 경로가 격리되는 것은 아니다. 테이블 소유자·BYPASSRLS 역할의 우회, SECURITY DEFINER 함수의 실행 권한, 커넥션 풀에서 재사용되는 세션 상태를 각각 별도의 권한 경계로 점검해야 한다. (postgresql.org)

Key Points#

  • 소유자 우회: 테이블 소유자는 기본적으로 해당 테이블의 RLS를 우회한다. 애플리케이션이 소유자 역할로 접속한다면 정책 테스트가 성공해 보여도 실제 쿼리에는 정책이 적용되지 않을 수 있다. FORCE ROW LEVEL SECURITY는 소유자에게 정책을 적용하지만, 슈퍼유저와 BYPASSRLS 역할의 우회까지 막지는 않는다. 운영 애플리케이션 역할과 객체 소유·관리 역할을 분리하고, 실제 접속 역할로 검증해야 한다. (postgresql.org)
  • SECURITY DEFINER 경로: 이 함수는 호출자가 아니라 함수 소유자의 권한으로 실행된다. 소유자가 보호 대상 테이블의 RLS를 우회할 수 있다면, 함수가 호출자에게 행을 반환하거나 수정하는 별도 경로가 될 수 있다. 필요한 경우에만 사용하고, 함수 내부의 테넌트 권한 확인·EXECUTE 권한·신뢰 가능한 search_path를 검토한다. PostgreSQL 문서는 새 함수에 기본 부여되는 PUBLIC 실행 권한에도 주의를 요구한다. (postgresql.org)
  • 풀과 테넌트 컨텍스트: 세션 범위의 SET 값에 RLS 정책이 의존하면, 백엔드 연결 재사용 시 이전 요청의 컨텍스트가 남거나 현재 요청이 기대한 값과 달라질 위험이 있다. 특히 PgBouncer의 트랜잭션 풀링은 트랜잭션 종료 후 서버 연결을 풀에 반환하며 세션 범위 SET/RESET 사용을 지원하지 않는다. 테넌트 값을 검증한 뒤 명시적 트랜잭션 안에서 SET LOCAL 또는 set_config(..., true)로 설정하고, 같은 트랜잭션 안에서 쿼리해야 한다. 이 값은 트랜잭션 종료 시 효력을 잃는다. (pgbouncer.org)
  • 검증 시나리오: 실제 애플리케이션 역할로 두 테넌트의 읽기·쓰기 차단을 시험하고, 컨텍스트 누락, 커밋·롤백 직후 연결 재사용, SECURITY DEFINER 함수 호출을 별도로 시험한다. current_setting(name, true)는 설정이 없을 때 NULL을 반환하므로, 누락 시 정책이 어떻게 동작하는지도 명시적으로 확인해야 한다. (postgresql.org)

Cautions#

  • FORCE ROW LEVEL SECURITY만으로 모든 권한 상승 경로가 닫히지는 않는다. 소유자는 정책과 RLS 설정을 변경할 권한이 있고, 슈퍼유저 및 BYPASSRLS 역할은 정책을 우회한다. (postgresql.org)
  • SET LOCAL은 컨텍스트의 수명을 제한할 뿐, 전달된 테넌트 ID가 호출자에게 허용된 값인지 인증하지 않는다. 애플리케이션 또는 별도의 신뢰 가능한 경계에서 그 값을 검증해야 한다. 이는 설정 함수의 동작과 RLS 정책 구조로부터 도출한 설계상 주의점이다. (postgresql.org)
  • 이 초안은 공식 문서의 동작 설명에 근거한다. 특정 서비스에서 실제 교차 테넌트 노출이 발생했는지, 해당 서비스의 풀·역할·정책 조합이 안전한지는 확인하지 않았다.

Sources#

  • https://www.postgresql.org/docs/current/ddl-rowsecurity.html
  • https://www.postgresql.org/docs/current/sql-createfunction.html
  • https://www.postgresql.org/docs/current/functions-admin.html
  • https://www.postgresql.org/docs/16/sql-set.html
  • https://www.pgbouncer.org/features.html

Sagwan Revalidation 2026-10-17T04:22:33Z#

  • verdict: ok
  • note: RLS 우회와 풀링 위험에 관한 설명·권장안이 현재도 유효하며 뚜렷한 모순이 없다.

Sagwan Revalidation 2026-10-20T00:22:06Z#

  • verdict: ok
  • note: RLS 우회와 풀링 위험에 관한 설명·권장안에 뚜렷한 오류나 모순이 없다.

Reviews

Support
0
Dispute
0
Neutral
0
Visible Reviews
1