본문 바로가기
Database/Oracle

[ORACLE] TABLE_PRIVILEGES 완전 정복 : 실무 중심 GRANT/REVOKE 점검 쿼리 보안 모범 사례

by Papa Martino V 2025. 10. 9.
728x90

TABLE_PRIVILEGES
[ORACLE] TABLE_PRIVILEGES

이 글은 Oracle의 테이블 객체 권한(Table Object Privileges)을 실무 관점에서 깊이 있게 정리합니다. 권한의 의미와 부작용, 안전한 부여/회수 패턴, 그리고 DBA_TAB_PRIVS·ALL_TAB_PRIVS·USER_TAB_PRIVS 계열 뷰를 활용한 점검 쿼리까지 한 번에 확인할 수 있습니다. Oracle 공식 문서를 교차 확인하여 최신 동작을 반영했습니다. 

1) 왜 지금 TABLE_PRIVILEGES를 점검해야 할까?

  • 보안·감사 요구 강화: 최소권한 원칙을 위반한 광범위 GRANT는 곧바로 리스크로 이어집니다.
  • 운영 안정성: 불필요한 WITH GRANT OPTION은 권한 전염(chain grant)을 유발하여 회수(REVOKE)를 복잡하게 만듭니다.
  • 버전 변화: 12c부터 도입된 READ 권한은 SELECT와 행 잠금 동작이 달라 미묘한 트러블을 줄여줍니다.

2) Oracle 테이블 객체 권한의 전체 그림

Oracle의 객체 권한은 테이블·뷰 등 스키마 오브젝트 단위로 부여되는 권한입니다. 테이블에 적용되는 대표 권한은 다음과 같습니다. 

권한 설명 (핵심 동작) 비고/주의
SELECT 데이터 조회 허용 (SELECT ... FOR UPDATE로 행 잠금 가능) 광범위 부여 시 데이터 유출 위험
READ 읽기 전용 조회, SELECT ... FOR UPDATE처럼 행 잠금을 허용하지 않음 12c+에서 보안 친화적 대안으로 권장
INSERT 행 추가 허용 대량 적재 작업 시 주의
UPDATE 행 변경 허용 (열 단위 제한 가능) 민감 컬럼은 컬럼 단위 GRANT 권장
DELETE 행 삭제 허용 외래키/감사 정책과 충돌 가능
REFERENCES 외래키 참조 허용 (컬럼 단위 가능) 스키마 설계 시 필수 권한
ALTER 테이블 구조 변경 허용 운영 환경에서는 극히 제한
INDEX 다른 사용자 테이블에 인덱스 생성 허용 성능·스토리지 영향 고려

권한 부여는 GRANT 문으로 수행하며, 사용자·롤·PUBLIC을 지정할 수 있습니다. (운영에서는 PUBLIC 대상 부여 지양)

3) 점검에 쓰는 핵심 사전 뷰(Grants Inventory)

  • DBA_TAB_PRIVS: 데이터베이스 전체 객체 권한 그랜트 현황
  • ALL_TAB_PRIVS: 현재 세션 관점에서 접근 가능한 객체 권한
  • USER_TAB_PRIVS / USER_TAB_PRIVS_MADE: 내게 부여/내가 부여한 권한 추적

각 뷰의 정의는 다음 공식 문서를 참고하세요. 

설명 주요 컬럼(예) 활용 포인트
DBA_TAB_PRIVS DB 전체 객체 권한 GRANTEE, OWNER, TABLE_NAME, PRIVILEGE, GRANTABLE 광범위 권한 스캔, 보안 감리
ALL_TAB_PRIVS 세션이 볼 수 있는 권한 위와 유사 문제 재현/개발자 셀프 점검
USER_TAB_PRIVS 내게 관련된 권한(소유/부여/수혜) 위와 유사 개인 스키마 방어 점검
USER_TAB_PRIVS_MADE 내가 부여한 권한 목록 GRANTEE, TABLE_NAME, PRIVILEGE, GRANTABLE 권한 회수 플랜 작성

4) 안전한 GRANT 패턴 (실무 레시피)

4.1 최소권한 + 롤 기반 부여

-- 1) 역할(ROLE) 정의
CREATE ROLE r_sales_ro;

-- 2) 필요한 읽기 권한만 롤에 부여 (READ 권한 사용 예)
GRANT READ ON sales.order TO r_sales_ro;

-- 3) 사용자에게 롤 부여
GRANT r_sales_ro TO app_user1;

포인트: 객체별 직접 부여 대신 롤을 매개로 하면 회수와 감사를 단순화할 수 있습니다. READ는 SELECT 대비 행 잠금 제한으로 안전성이 높습니다. 

4.2 컬럼 단위 UPDATE/REFERENCES로 민감 컬럼 격리

-- 주소/연락처 컬럼만 수정 허용
GRANT UPDATE (address, phone) ON hr.employees TO helpdesk;

-- 급여 컬럼은 별도 롤/담당자에게만
-- GRANT UPDATE (salary) ON hr.employees TO payroll_role;

4.3 외래키 설계를 위한 REFERENCES

-- 다른 스키마의 키 컬럼을 참조하려면 REFERENCES 필요
GRANT REFERENCES (customer_id) ON crm.customers TO sales_schema;

4.4 WITH GRANT OPTION은 예외적으로만

-- helpdesk가 제3자에게 동일 권한을 재부여할 수 있게 함 (권장 X)
GRANT READ ON hr.tickets TO helpdesk WITH GRANT OPTION;

권한 전파 사슬이 길어지면 회수 난도가 급증합니다. 기본적으로 지양하세요. 

5) REVOKE 전략: 전염 차단과 깨끗한 회수

-- 직접 부여한 권한 회수
REVOKE READ, SELECT ON hr.tickets FROM helpdesk;

-- 롤 해제
REVOKE r_sales_ro FROM app_user1;

팁: 직접 부여한 권한인지, 롤을 통해 들어온 권한인지 먼저 식별하세요. GRANTABLE='YES'가 다단계 전파의 흔적일 수 있습니다. 

6) “지금” 우리 DB는 안전한가? — 즉시 실행 점검 쿼리

6.1 위험 신호: PUBLIC/광역 권한

-- PUBLIC 대상 SELECT/READ/INSERT/UPDATE/DELETE 탐지
SELECT owner, table_name, privilege
FROM   dba_tab_privs
WHERE  grantee = 'PUBLIC'
AND    privilege IN ('SELECT','READ','INSERT','UPDATE','DELETE')
ORDER BY owner, table_name;

6.2 권한 전염 가능성 추적

-- WITH GRANT OPTION 흔적
SELECT grantee, owner, table_name, privilege
FROM   dba_tab_privs
WHERE  grantable = 'YES'
ORDER BY owner, table_name;

6.3 내가(우리 팀이) 부여한 권한 목록

SELECT grantee, table_name, privilege, grantable
FROM   user_tab_privs_made
ORDER BY grantee, table_name;

6.4 개발자 셀프 점검(내가 가진 권한만 보기)

SELECT owner, table_name, privilege
FROM   user_tab_privs
ORDER BY owner, table_name, privilege;

위 뷰들의 의미와 컬럼 사양은 공식 레퍼런스를 참고하세요. 

7) 흔한 오해와 장애 시나리오

  1. SELECT ANY TABLE만 있으면 된다? 이는 시스템 권한으로, 거의 모든 스키마 테이블을 읽게 합니다. 최소권한 원칙에 어긋나며, 객체 권한 설계와 목적이 다릅니다. 매우 제한적으로 사용하세요. 
  2. SELECT와 READ는 같다? READ는 행 잠금이 불가하여 동시성 영향과 보안 측면에서 더 보수적입니다. 레거시 코드에 FOR UPDATE가 있다면 READ만으로는 실패할 수 있습니다. 
  3. 권한은 직접 사용자에게만? 실무에서는 “롤 → 사용자” 경유가 표준입니다. 회수·감사·권한 모델 표준화를 동시에 만족합니다. 

8) 운영 체크리스트 (바로 적용)

  • 인벤토리 작성: DBA_TAB_PRIVS 전수 스캔 → PUBLIC/GRANTABLE 우선 정리
  • 롤 리팩터링: 동일 역할군을 묶어 역할로 표준화, 개인 직접 GRANT 제거
  • 민감 컬럼 분리: UPDATE/REFERENCES는 컬럼 단위로 최소화
  • READ 우선: 단순 조회는 READ로 시작, 필요 시에만 SELECT 부여
  • 권한 전염 차단: WITH GRANT OPTION 금지, 기존 흔적은 REVOKE 플랜 수립
  • 정기 감리 자동화: 위 점검 쿼리를 스케줄링하여 드리프트 감시

9) 꼭 알아둘 문법 스니펫

-- GRANT: 사용자/롤/공용 대상
GRANT READ, SELECT ON hr.employees TO r_hr_reader, dev_user;
-- 컬럼 단위 UPDATE
GRANT UPDATE (email, phone) ON hr.employees TO helpdesk;
-- REFERENCES (외래키 참조)
GRANT REFERENCES (customer_id) ON crm.customers TO sales_schema;
-- REVOKE
REVOKE SELECT, READ ON hr.employees FROM dev_user;
-- 권장하지 않음: WITH GRANT OPTION
GRANT SELECT ON hr.employees TO temp_op WITH GRANT OPTION;

GRANT/REVOKE 구문과 제약사항은 SQL 언어 참조를 확인하세요. 

10) 자주 묻는 질문(FAQ)

Q1. 뷰(View)에도 동일한 권한을 쓰나요?
A. 네. SELECT/READ/INSERT/UPDATE/DELETE 등이 유사하게 적용되지만, 실제 DML 가능 여부는 뷰의 갱신 가능성에 좌우됩니다. (권한 개념은 동일) 

Q2. 오브젝트-타입(OBJECT TABLE)에도 같은가요?
A. 객체 테이블은 관계형 테이블과 동일하게 READ/SELECT/INSERT/UPDATE/DELETE 권한 모델을 따릅니다.

출처(Official & Authoritative)

  1. Oracle Database Security Guide — Object Privileges(23c): 테이블 권한의 분류와 READ/SELECT 차이.
  2. Oracle SQL Language Reference — GRANT 문 (23c): 권한 부여 구문과 PUBLIC 주의.
  3. Oracle Reference — DBA_TAB_PRIVS / ALL_TAB_PRIVS / USER_TAB_PRIVS / USER_TAB_PRIVS_MADE (19c~21c): 권한 인벤토리 뷰 정의.
  4. Oracle Docs — Access Privileges on Object Tables(21c): 객체 테이블 권한 모델.
728x90