KIỂM SOÁT TRUY CẬP DỮ LIỆU NHẠY CẢM VÀ PHÁT HIỆN HÀNH VI BẤT THƯỜNG TRÊN ORACLE DATABASE VÀ MICROSOFT SQL SERVER
1. Mục tiêu
- Che dữ liệu nhạy cảm với người dùng bị hạn chế bằng Query Rewrite và Redaction.
- Chặn thao tác sửa, xóa dữ liệu nhạy cảm của người không được phép bằng S-TAP TERMINATE và S-GATE.
- Phát hiện hành vi bất thường: dò mật khẩu, dò cấu trúc/SQL injection, trích xuất hàng loạt, truy cập ngoài giờ, leo thang đặc quyền.
2. Nguyên lý hoạt động
Hình 1: Nguyên lý kiểm soát dữ liệu nhạy cảm và phát hiện hành vi bất thường
3. Mô hình triển khai và chuẩn bị
3.1. Thành phần hệ thống
Thành phần | Tên máy / IP | Vai trò |
| Guardium Collector (đồng thời là Central Manager) | <IP_GUARDIUM> | Thực thi policy che, chặn, cảnh báo |
| Oracle Database 19c trên Oracle Linux (service orcl) | oracledb01 / <IP_ORACLE> | CSDL nguồn, S-TAP Linux |
| Microsoft SQL Server trên Windows Server | SQLDB01 / <IP_MSSQL> | CSDL nguồn, S-TAP Windows |
3.2. Tài khoản kiểm thử
Tài khoản | Vai trò | Dùng cho |
| RETAIL / RETAIL_APP | Ứng dụng hợp lệ (thuộc GRP_AUTHORIZED_USERS) | Đối chứng: thấy dữ liệu gốc, không bị chặn |
| INTERN_TEST | Người dùng chỉ được xem dữ liệu đã che | Query Rewrite, Redaction |
| OPS_TEST (tạo mới) | Nhân viên vận hành có quyền DML nhưng không được sửa/xóa dữ liệu khách hàng | Chặn thao tác, các rule phát hiện |
| HACKER_SIM (không tạo) | Tên đăng nhập không tồn tại | Giả lập dò mật khẩu mà không làm khóa tài khoản thật |
3.3. Tạo các group bổ sung
Truy cập Setup → Tools and Views → Group Builder, tạo các group sau (Application type = Public):
Tên group | Group Type | Thành viên |
GRP_MASKED_USERS | USERS | INTERN_TEST |
GRP_WATCHED_USERS | USERS | OPS_TEST |
GRP_DESTRUCTIVE_CMDS | COMMANDS | DELETE, UPDATE, DROP TABLE, TRUNCATE TABLE, ALTER TABLE |
GRP_PRIV_CMDS | COMMANDS | GRANT, REVOKE, CREATE USER, ALTER USER, CREATE LOGIN, ALTER ROLE |
GRP_NIGHT_BATCH_USERS | USERS | GUARDIUM_CLS |
Hình 2: Các group bổ sung trong Group Builder
3.4. Cấu hình S-TAP và Collector
Bước 1: Truy cập Manage → Activity Monitoring → S-TAP Control, chọn từng S-TAP (oracledb01 và SQLDB01), chỉnh các tham số sau rồi nhấn Apply. Guardium đẩy cấu hình xuống và khởi động lại S-TAP.
Tham số | Giá trị | Mục đích |
qrw_installed | 1 | Bật Query Rewrite |
qrw_default_state | 0 | Chỉ viết lại các câu lệnh đến sau câu khớp rule QUERY REWRITE: ATTACH trong cùng phiên |
firewall_installed | 1 | Bật S-GATE; cũng là điều kiện để Redaction hoạt động ổn định trên Windows |
firewall_default_state | 0 | Chỉ các câu lệnh đến sau câu khớp rule S-GATE ATTACH trong cùng phiên mới bị giữ lại chờ phán quyết |
firewall_fail_close | 0 | Collector không phản hồi thì cho câu lệnh đi qua, tránh treo CSDL |
firewall_timeout | 10 | Thời gian chờ phán quyết (giây) |
- Kiểm tra giá trị đã được đẩy xuống guard_tap.ini bằng grep trên oracledb01 và findstr trên SQLDB01. Trên S-TAP Windows, hai tham số Query Rewrite có tên QUERY_REWRITE_INSTALLED và QUERY_REWRITE_DEFAULT_STATE.
Hình 3: Tham số Query Rewrite và Firewall trong guard_tap.ini trên oracledb01 (trên) và SQLDB01 (dưới)
Bước 2: Truy cập Manage → Activity Monitoring → Inspection Engines, bật Inspect Returned Data (bắt buộc để Redaction đọc được dữ liệu trả về) và Log Records Affected (để rule đếm số bản ghi trả về), nhấn Apply. Kiểm tra lại S-TAP Control: cả hai S-TAP vẫn ở trạng thái xanh.
Hình 4: Log Records Affected và Inspect Returned Data được bật trong Inspection Engine Configuration
3.5. Tạo policy POL_PROTECT_SENSITIVE_DATA
Bước 1: Truy cập Protect → Security Policies → Policy Builder for Data, chọn POL_MONITOR_SENSITIVE_DATA và nhấn Clone, đặt tên POL_PROTECT_SENSITIVE_DATA. Policy mới giữ sẵn hai rule ALERT_UNAUTHORIZED_SENSITIVE_ACCESS và LOG_SENSITIVE_ACCESS; policy cũ được giữ nguyên để khôi phục khi cần.Bước 2: Thêm các rule ở các phần sau và sắp xếp access rule theo đúng thứ tự dưới đây.
Bước 3: Sau mỗi phần, cài policy tại Protect → Security Policies → Policy Installation → Install & Override rồi kiểm thử.
Bước 3: Sau mỗi phần, cài policy tại Protect → Security Policies → Policy Installation → Install & Override rồi kiểm thử.
# | Access rule | Hành động | Continue |
| 1 | SGATE_ATTACH_WATCHED | S-GATE ATTACH | Có |
| 2 | QRW_ATTACH_MASKED | QUERY REWRITE: ATTACH | Có |
| 3–4 | QRW_APPLY_MASK_ORA, QRW_APPLY_MASK_MSSQL | QUERY REWRITE: APPLY DEFINITION | Có |
| 5–9 | DET_SQLI_PATTERN, DET_PRIV_ESCALATION, DET_OFF_HOURS_NIGHT, DET_OFF_HOURS_EVENING, DET_MASS_EXTRACTION | ALERT PER MATCH (hai rule ngoài giờ: ALERT ONCE PER SESSION) | Có |
| 10 | BLOCK_DESTRUCTIVE_SGATE | ALERT PER MATCH + S-GATE TERMINATE | Không |
| 11 | BLOCK_DESTRUCTIVE_TERMINATE | ALERT PER MATCH + S-TAP TERMINATE | Không |
| 12 | ALERT_UNAUTHORIZED_SENSITIVE_ACCESS (có sẵn) | ALERT PER MATCH | Có |
| 13 | LOG_SENSITIVE_ACCESS (có sẵn) | LOG FULL DETAILS | Không |
- Rule ATTACH phải đứng đầu để phiên được gắn trạng thái theo dõi trước khi các rule sau ra phán quyết
- Các rule phát hiện đều tích Continue để câu lệnh vẫn đi tiếp tới rule chặn và rule ghi log.
4. Kiểm soát truy cập dữ liệu nhạy cảm
4.1. Che dữ liệu bằng Query Rewrite
Query Rewrite viết lại câu lệnh của INTERN_TEST trước khi tới CSDL, thay các cột nhạy cảm bằng biểu thức che, nên dữ liệu gốc không rời khỏi máy chủ.
Bước 1: Truy cập Protect → Security Policies → Query Rewrite Builder, nhấn New, đặt tên QRWD_MASK_CUSTOMERS_ORA.Bước 2: Nhập câu lệnh mẫu SELECT full_name, phone, cccd, credit_card FROM retail.customers và nhấn Parse.
Bước 3: Chọn từng cột nhạy cảm và khai báo biểu thức thay thế theo bảng dưới, giữ alias trùng tên cột gốc.
Bước 4: Nhấn Save. Ở khung kiểm thử, nhấn Set Up Test để chọn definition, nhập câu lệnh cần thử rồi nhấn Run Test: câu khớp mẫu được viết lại (Changed = YES), câu SELECT * không bị viết lại (Changed = NO).
Bước 5: Tạo QRWD_MASK_CUSTOMERS_MSSQL tương tự với cú pháp T-SQL.Bước 3: Chọn từng cột nhạy cảm và khai báo biểu thức thay thế theo bảng dưới, giữ alias trùng tên cột gốc.
Bước 4: Nhấn Save. Ở khung kiểm thử, nhấn Set Up Test để chọn definition, nhập câu lệnh cần thử rồi nhấn Run Test: câu khớp mẫu được viết lại (Changed = YES), câu SELECT * không bị viết lại (Changed = NO).
Cột | Oracle | SQL Server | Kết quả |
| phone | SUBSTR(phone,1,3) || '****' || SUBSTR(phone,-3) AS phone | LEFT(phone,3) + '****' + RIGHT(phone,3) AS phone | 091****678 |
| cccd | '*********' || SUBSTR(cccd,-3) AS cccd | '*********' + RIGHT(cccd,3) AS cccd | *********234 |
| credit_card | '************' || SUBSTR(credit_card,-4) AS credit_card | '************' + RIGHT(credit_card,4) AS credit_card | ************1111 |
Hình 5: QRWD_MASK_CUSTOMERS_ORA (trên) và QRWD_MASK_CUSTOMERS_MSSQL (dưới) trong Query Rewrite Builder; khung Run Test ở cả hai ảnh là kết quả thử QRWD_MASK_CUSTOMERS_MSSQL
Bước 6: Thêm ba access rule vào policy:
Rule | Điều kiện | Hành động |
| QRW_ATTACH_MASKED | DB User In Group GRP_MASKED_USERS | QUERY REWRITE: ATTACH |
| QRW_APPLY_MASK_ORA | DB User In Group GRP_MASKED_USERS; Server IP = <IP_ORACLE>; Object = %customers; Command = SELECT | QUERY REWRITE: APPLY DEFINITION → QRWD_MASK_CUSTOMERS_ORA |
| QRW_APPLY_MASK_MSSQL | Như trên với Server IP = <IP_MSSQL> | QUERY REWRITE: APPLY DEFINITION → QRWD_MASK_CUSTOMERS_MSSQL |
Hình 6: INTERN_TEST thấy dữ liệu đã che trên Oracle và SQL Server (hai ảnh trên), RETAIL thấy dữ liệu gốc trên Oracle (ảnh dưới)
Đánh giá: Query Rewrite che đúng phone, cccd, credit_card cho INTERN_TEST trên cả Oracle và SQL Server, RETAIL vẫn thấy dữ liệu gốc. Hạn chế: chỉ câu lệnh khớp mẫu mới được viết lại, SELECT * không bị che nên cần thêm Redaction.
4.2. Che dữ liệu trả về bằng Redaction
Redaction che dữ liệu trên kết quả trả về theo mẫu regex, không phụ thuộc tên cột. Lớp này che CCCD và số thẻ trong các trường hợp Query Rewrite bỏ sót: SELECT *, câu JOIN, bảng EMPLOYEES.
Bước 1: Đảm bảo đã bật Inspect Returned Data, Log Records Affected (IBM yêu cầu cả hai cho REDACT) và firewall_installed = 1 (phần Cấu hình S-TAP và Collector), sau đó nhấn Restart Inspection Engines.
Bước 2: Trong POL_PROTECT_SENSITIVE_DATA, nhấn Add Extrusion Rule và tạo sáu rule với DB User In Group GRP_MASKED_USERS, Server IP tương ứng, Data Pattern theo bảng dưới, Action = REDACT, ký tự thay thế *.
Bước 1: Đảm bảo đã bật Inspect Returned Data, Log Records Affected (IBM yêu cầu cả hai cho REDACT) và firewall_installed = 1 (phần Cấu hình S-TAP và Collector), sau đó nhấn Restart Inspection Engines.
Bước 2: Trong POL_PROTECT_SENSITIVE_DATA, nhấn Add Extrusion Rule và tạo sáu rule với DB User In Group GRP_MASKED_USERS, Server IP tương ứng, Data Pattern theo bảng dưới, Action = REDACT, ký tự thay thế *.
Rule | Server IP | Data Pattern | Kết quả |
| REDACT_CARD16_ORA | <IP_ORACLE> | [^0-9]([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])[0-9][0-9][0-9][0-9] | ************1111 |
| REDACT_CARD15_ORA | <IP_ORACLE> | [^0-9]([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])[0-9][0-9][0-9][0-9] | ***********0009 |
| REDACT_CCCD_ORA | <IP_ORACLE> | [^0-9](0[0-9][0-9][0-3][0-9][0-9][0-9][0-9][0-9])[0-9][0-9][0-9] | *********234 |
| REDACT_CARD16_MSSQL | <IP_MSSQL> | <16>([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])[0-9][0-9][0-9][0-9] | ************1111 |
| REDACT_CARD15_MSSQL | <IP_MSSQL> | <15>([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])[0-9][0-9][0-9][0-9] | ***********0009 |
| REDACT_CCCD_MSSQL | <IP_MSSQL> | <12>(0[0-9][0-9][0-3][0-9][0-9][0-9][0-9][0-9])[0-9][0-9][0-9] | *********234 |
- Phần trong ngoặc tròn là phần bị che, phần ngoài ngoặc (4 số cuối của thẻ, 3 số cuối của CCCD) được giữ lại.
- Thẻ trong dữ liệu lab dài 15 hoặc 16 số nên mỗi CSDL cần hai rule thẻ; với thẻ 16 số cả hai rule cùng khớp, phần bị che chồng lên nhau và vẫn giữ 4 số cuối.
- SQL Server: <NN> là độ dài chính xác của giá trị VARCHAR (bắt buộc với cột VARCHAR) nên mỗi mẫu chỉ khớp chuỗi đúng 12, 15 hoặc 16 ký tự.
- Oracle: [^0-9] ở đầu mẫu khớp byte độ dài đứng trước giá trị, nhờ đó mẫu CCCD không khớp vào giữa số thẻ; nếu bỏ ký tự này, một số thẻ trong dữ liệu lab bị che mất một chữ số trong 4 số cuối.
Bước 3: Cài lại policy.
Hình 7: Kết quả Redaction khi INTERN_TEST truy vấn EMPLOYEES và SELECT * trên CUSTOMERS: Oracle (trên), SQL Server (dưới)
Đánh giá: Redaction che đúng CCCD và số thẻ cả với SELECT * và bảng EMPLOYEES trên hai CSDL, vẫn giữ các số cuối. Hạn chế: chỉ che được dữ liệu có mẫu regex, số điện thoại, email và lương vẫn hiển thị nguyên.
4.3. Chặn thao tác phá hoại
Cách 1 – Ngắt phiên bằng S-TAP TERMINATE
Bước 1: Thêm access rule BLOCK_DESTRUCTIVE_TERMINATE: DB User Not In Group GRP_AUTHORIZED_USERS; Object In Group GRP_SENSITIVE_OBJECTS; Command In Group GRP_DESTRUCTIVE_CMDS; Continue = Không.Bước 2: Chạy thử với hành động ALERT PER MATCH (Severity HIGH) bằng câu UPDATE retail.customers SET email = email WHERE customer_id = 1 của OPS_TEST (không làm đổi dữ liệu) để kiểm tra rule bắt đúng câu lệnh trên cả hai CSDL.
Hình 8: Access policy violations khi chạy thử BLOCK_DESTRUCTIVE_TERMINATE chỉ với ALERT PER MATCH
Bước 3: Thêm hành động S-TAP TERMINATE, cài lại policy và cho OPS_TEST chạy UPDATE retail.customers SET email = 'tampered@test.local' WHERE customer_id = 1.
Hình 9: Phiên của OPS_TEST bị S-TAP TERMINATE ngắt sau câu UPDATE: Oracle (trên), SQL Server (dưới)
Đánh giá: S-TAP TERMINATE ngắt phiên của OPS_TEST trên cả hai CSDL nhưng chỉ sau khi câu UPDATE đã chạy: trên SQL Server email đã bị đổi, trên Oracle giao dịch chưa commit nên email giữ nguyên. Cách này không bảo vệ được câu lệnh đầu tiên.
Cách 2 – Chặn trước khi thực thi bằng S-GATE
Với phiên đã attached, S-TAP giữ mỗi câu lệnh lại chờ phán quyết của Collector; phán quyết TERMINATE hủy câu lệnh trước khi tới CSDL.
Bước 1: Thêm access rule SGATE_ATTACH_WATCHED ở vị trí đầu tiên: DB User In Group GRP_WATCHED_USERS; Action = S-GATE ATTACH; Continue = Có.Bước 2: Thêm access rule BLOCK_DESTRUCTIVE_SGATE ngay trước BLOCK_DESTRUCTIVE_TERMINATE: DB User In Group GRP_WATCHED_USERS; Object In Group GRP_SENSITIVE_OBJECTS; Command In Group GRP_DESTRUCTIVE_CMDS; Action = ALERT PER MATCH (HIGH) + S-GATE TERMINATE; Continue = Không.
Hình 10: Thứ tự access rule sau khi thêm SGATE_ATTACH_WATCHED và BLOCK_DESTRUCTIVE_SGATE
Bước 3: Tùy chọn: ở hành động terminate tích Quarantine 10 phút để OPS_TEST không thể kết nối lại ngay sau khi vi phạm.
Bước 4: Cài lại policy và chạy lại đúng câu UPDATE đã dùng ở Cách 1.
Bước 4: Cài lại policy và chạy lại đúng câu UPDATE đã dùng ở Cách 1.
Hình 11: Câu UPDATE của OPS_TEST bị S-GATE chặn, email không đổi: Oracle (trên), SQL Server (dưới)
Đánh giá: S-GATE chặn câu UPDATE của OPS_TEST trước khi tới CSDL, email không đổi trên cả Oracle và SQL Server, khắc phục được điểm yếu của S-TAP TERMINATE. Phiên vẫn bị ngắt khi chặn nên người dùng phải kết nối lại.
5. Phát hiện hành vi bất thường
5.1. Rule phát hiện thời gian thực
Bước 1: Truy cập Setup → Tools and Views → Time Period Builder, tạo hai time period cho rule ngoài giờ, kiểu Repeating block, Weekday From Sunday To Saturday: TP_OFF_HOURS_EVENING (18:00 – 24:00) và TP_OFF_HOURS_NIGHT (00:00 – 07:00).
- Guardium luôn coi Chủ nhật là ngày đầu tuần, nên cả tuần khai báo Sunday – Saturday; khoảng qua nửa đêm phải tách thành hai period.
Bước 2: Thêm các rule sau vào POL_PROTECT_SENSITIVE_DATA (access rule đều tích Continue):
Rule | Loại | Điều kiện | Hành động | Phát hiện |
| DET_BRUTE_FORCE | Exception | Exception Type = LOGIN_FAILED; Client IP = “.”; Min. Ct. = 5; Reset Interval = 5 | ALERT PER MATCH (HIGH) | Dò mật khẩu: 5 lần đăng nhập sai trong 5 phút từ cùng một IP |
| DET_SQL_ERROR_BURST | Exception | Exception Type = SQL_ERROR; DB User = “.”; Min. Ct. = 10; Reset Interval = 5 | ALERT PER MATCH (MED) | Dò cấu trúc CSDL: lỗi SQL dồn dập |
| DET_SQLI_PATTERN | Access | SQL Pattern = [Oo][Rr] +'?[0-9]+'? *= *'?[0-9]+'?|[Uu][Nn][Ii][Oo][Nn] +([Aa][Ll][Ll] +)?[Ss][Ee][Ll][Ee][Cc][Tt] | ALERT PER MATCH (HIGH) | Mẫu SQL injection OR 1=1, UNION SELECT |
| DET_PRIV_ESCALATION | Access | Command In Group GRP_PRIV_CMDS | ALERT PER MATCH (HIGH) | Leo thang đặc quyền, kể cả lần thử bị từ chối |
| DET_OFF_HOURS_EVENING / _NIGHT | Access | Period = TP_OFF_HOURS_EVENING / TP_OFF_HOURS_NIGHT; Object In Group GRP_SENSITIVE_OBJECTS; DB User Not In Group GRP_NIGHT_BATCH_USERS | ALERT ONCE PER SESSION (MED) | Truy cập dữ liệu nhạy cảm ngoài giờ |
| DET_MASS_EXTRACTION | Access | Object In Group GRP_SENSITIVE_OBJECTS; Command = SELECT; Records Affected Threshold = 50 / query | ALERT PER MATCH (HIGH) | Một câu lệnh lấy hơn 50 bản ghi nhạy cảm |
- Nhập dấu chấm (.) vào Client IP/DB User và không chọn group để Guardium đếm riêng theo từng IP hoặc từng user, thay vì gộp chung toàn hệ thống.
- Ngưỡng 50 bản ghi chọn theo dữ liệu lab: bảng CUSTOMERS có 60 dòng, ứng dụng chỉ lấy vài dòng mỗi lần. Chọn đơn vị query để tính theo từng câu lệnh; nếu chọn session, Guardium cộng dồn số bản ghi của cả phiên. Rule này cần Log Records Affected đã bật.
- Để kiểm thử rule ngoài giờ trong giờ hành chính, tạm sửa TP_OFF_HOURS_EVENING bao trùm thời điểm kiểm thử, cài lại policy, sau đó trả về như cũ.
Hình 12: Các rule của POL_PROTECT_SENSITIVE_DATA sau khi thêm rule phát hiện: access rule 1–13 và hai exception rule
Hình 13: Access policy violations ghi nhận cảnh báo của các rule phát hiện trên Oracle và SQL Server
Đánh giá: Các rule phát hiện đều sinh cảnh báo đúng hành vi kiểm thử, kể cả lần OPS_TEST thử GRANT DBA, ALTER ROLE. Một câu lệnh có thể khớp nhiều rule: câu OR 1=1 bị cảnh báo cả SQL injection lẫn trích xuất hàng loạt.