Oracle Label Security (OLS) 基於 BLP 模型擴展,支援多層級安全標籤。用戶標籤包含 MAX_LEVEL、MIN_LEVEL、DEF_LEVEL、ROW_LEVEL 四層級,必須滿足約束:MIN ≤ DEF ≤ MAX、MIN ≤ ROW ≤ DEF。本文實測發現:SA_LABEL_ADMIN.ALTER_LABEL 修改標籤值時不檢查用戶標籤約束,導致用戶標籤變為非法狀態,後續操作被阻擋但系統不報錯。
-- 1. 建立策略與四級標籤 (L1 < L2 < L3 < L4)
EXEC sa_sysdba.create_policy('P1','LABEL_COL');
EXEC sa_components.create_level('P1',10,'L1','L1');
EXEC sa_components.create_level('P1',20,'L2','L2');
EXEC sa_components.create_level('P1',30,'L3','L3');
EXEC sa_components.create_level('P1',40,'L4','L4');
-- 2. 給用戶 SYSMAN 設定合法標籤
EXEC sa_user_admin.set_levels('P1','SYSMAN','L2','L1','L2','L2');
-- MAX=L2, MIN=L1, DEF=L2, ROW=L2 → 滿足 MIN(L1) ≤ DEF(L2) ≤ MAX(L2)
-- 3. 查詢用戶標籤
SELECT user_name, labels FROM dba_sa_user_labels;
-- 顯示:MIN WRITE LABEL = L1, 其他 = L2 ✓
EXEC sa_label_admin.alter_label('P1','L1','L4',TRUE);
-- 執行成功,無錯誤提示
SELECT user_name, labels FROM dba_sa_user_labels;
-- 顯示:
-- MAX READ LABEL=L2, MAX WRITE LABEL=L2,
-- MIN WRITE LABEL=L4, -- 變為 L4!
-- DEFAULT READ LABEL=L2, DEFAULT WRITE LABEL=L2, DEFAULT ROW LABEL=L2
-- 約束檢查:MIN(L4) ≤ DEF(L2) ≤ MAX(L2) → FALSE (L4 > L2)
-- 用戶標籤已非法
INSERT/UPDATE/DELETE → 全部失敗,因標籤比較永遠為假。DBA_SA_USER_LABELS。SA_LABEL_ADMIN.ALTER_LABEL 僅修改標籤定義表 LBACSYS.LABEL$ 中的字串值。LBACSYS.USER_LABELS$ 中引用該標籤的用戶四層級。MIN ≤ DEF ≤ MAX、MIN ≤ ROW ≤ DEF 約束。| 階段 | 動作 |
|---|---|
| 事前預防 | 嚴禁直接使用 ALTER_LABEL 修改已被用戶引用的標籤。需先移除所有用戶對該標籤的引用(SA_USER_ADMIN.SET_LEVELS 設為其他值),再修改標籤,最後恢復用戶設定。 |
| 事中檢測 | 建立排程作業,定期驗證用戶標籤約束:SELECT * FROM dba_sa_user_labels WHERE min_level > def_level OR def_level > max_level OR min_level > row_level OR row_level > def_level; |
| 事後修復 | 發現非法標籤時,以 LBACSYS 身分重新執行 SA_USER_ADMIN.SET_LEVELS 修正四層級至合法範圍。 |
測試版本:Oracle 11.1.0.6.0。此行為在 11gR2、12c、19c 中持續存在(MOS Doc ID 1302456.1 記載為「預期行為」,建議管理員自行維護約束)。
OLS 提供強大的強制存取控制,但 ALTER_LABEL 缺乏級聯約束檢查是一個長期存在的設計缺口。實施 OLS 的組織必須建立「標籤變更管理流程」:凍結標籤值、禁止直接 ALTER、變更走變更請求、自動化約束巡檢,避免靜默失效導致業務中斷。