Pretius: strategiczna fuzja jako odpowiedź na współczesne wyzwania
Pretius. Budujemy mądrzej:
strategiczna fuzja jako odpowiedź na współczesne wyzwania

Maskowanie danych w Oracle: ukrywanie informacji przed użytkownikami za pomocą łatwego w obsłudze VPD

Rafał Grzegorczyk

Oracle APEX & PL/SQL Developer

  • 6 kwietnia, 2023

Spis

[Uwaga] Ten artykuł został pierwotnie przygotowany w języku angielskim i został przetłumaczony na język polski.

Niedawno, podczas jednego z moich projektów, musiałem przyznać dostęp do bazy danych konkretnym użytkownikom. Klient chciał, aby widzieli oni wszystkie tabele, ale z wyłączeniem niektórych kolumn zawierających dane wrażliwe, takie jak wynagrodzenie, dochody, faktury, rozliczenia czy adresy klientów – czyli tak zwane „sensitive data”.

Zdecydowałem się użyć do tego Oracle VPD (Virtual Private Database), ponieważ – zgodnie z dokumentacją Oracle – jeśli korzystasz z Oracle Database XE 21c, VPD jest darmowe (w przypadku innych wersji radzę sprawdzić to samodzielnie). W tym artykule pokażę Ci, jak wykorzystać to rozwiązanie do maskowania danych, czyli ukrywania ich przed użytkownikami bazy danych Oracle, a jako bonus – również przed użytkownikami Oracle APEX.

Wymagania wstępne

Oto rzeczy, których będziesz potrzebować, aby odtworzyć przykład pokazany w tym artykule:

  • Baza danych Oracle XE 21c
  • Schemat HR – przechowuje dane wrażliwe
  • Schemat TEST – użytkownik o ograniczonym dostępie
  • Tabela HR.EMPLOYEES z kolumną SALARY

Ekran pokazujący tabelę.

Przyznawanie dostępu do kolumny

Zanim zrobię cokolwiek innego, muszę przyznać użytkownikowi dostęp do tabeli. W moim przypadku użytkownik nazywa się TEST, więc polecenie wygląda następująco:

--connect as HR
GRANT SELECT ON EMPLOYEES TO TEST;

Wynik wygląda tak:

Ekran pokazujący tabelę.

Ograniczanie dostępu do kolumny

Jednak, jak wspomniałem wcześniej, nie chcę, aby użytkownik TEST widział dane z kolumny SALARY. Jak to zrobić? Musisz wykonać kilka prostych kroków.

1. Stwórz funkcję do obsługi polityk VPD.

Pierwszą rzeczą jest stworzenie funkcji, która obsłuży polityki VPD. Musi ona zostać utworzona na schemacie, do którego użytkownik TEST nie ma dostępu (ja używam ADMIN dla Oracle Cloud).

--connect as ADMIN (używam Oracle Cloud)
create or replace function f_vpd_column_masking(
   p_schema varchar2,
   p_obj    varchar2
) return varchar2 as
   l_database_user      varchar2(255) DEFAULT USER;
   l_predicate varchar2(100);
begin
   if l_database_user in ('TEST') then
      l_predicate := '1=2';
   end if;

   return l_predicate;
end f_vpd_column_masking;

2. Stwórz politykę VPD, aby ukryć dane

Następnie musisz utworzyć politykę VPD, która pozwoli na ukrycie danych.

--execute as ADMIN
begin
   dbms_rls.add_policy
        (object_schema         => 'HR',
         object_name           => 'EMPLOYEES',
         policy_name           => 'EMPLOYEES_SELECT',
         function_schema       => 'ADMIN',
         policy_function       => 'f_vpd_column_masking',
         statement_types       => 'SELECT',
         sec_relevant_cols     => 'SALARY',  
         sec_relevant_cols_opt => dbms_rls.ALL_ROWS);
end;
/
--clean up
--EXEC DBMS_RLS.DROP_POLICY('HR','EMPLOYEES','EMPLOYEES_SELECT');

Zapobiegnie to wyświetlaniu danych z kolumny HR.EMPLOYEES.SALARY użytkownikom wymienionym w mojej funkcji.

Teraz odpytajmy tabelę EMPLOYEES jeszcze raz (połącz jako TEST).

Ekran pokazujący tabelę.

Wszystko wydaje się działać zgodnie z planem: użytkownik TEST może odpytywać tabelę EMPLOYEES, ale nie widzi żadnych wynagrodzeń.

Kontrola polityk VPD

Warto zauważyć, że zawsze możesz podejrzeć posiadane polityki VPD, używając prostego zapytania poniżej.

--run as ADMIN (SYS)
select *
  from all_policies
 where object_owner = 'HR';

Ekran pokazujący tabelę.

Wykluczanie użytkowników z polityk VPD

Ale co, jeśli z jakiegoś powodu chcesz, aby polityka VPD nie wpływała na konkretnych użytkowników? Możesz użyć tego zapytania, aby to osiągnąć.

--run as ADMIN or SYS
grant EXEMPT ACCESS POLICY to YOUR_USER;

Ukrywanie danych przed konkretnymi użytkownikami Oracle APEX

Jeden z moich kolegów zapytał mnie, jak chronić dane przed niektórymi użytkownikami APEX. To całkiem proste – wystarczy zaktualizować funkcję polityki VPD.

--connect as ADMIN (as I'm using Oracle Cloud)
create or replace function f_vpd_column_masking(
   p_schema varchar2,
   p_obj    varchar2
) return varchar2 as
   l_database_user      varchar2(255) DEFAULT USER;
   l_predicate varchar2(100);
begin
   if l_database_user in ('TEST') then
      l_predicate := '1=2';
   end if;

/* dodane, aby chronić przed konkretnymi użytkownikami APEX 
Jeśli zalogowany użytkownik APEX to SANDBOX_LTD, zobaczy wartości NULL w kolumnie salary 
*/
   if SYS_CONTEXT('APEX$SESSION', 'APP_USER') = 'SANDBOX_LTD' then
      l_predicate := '1=2';
   end if;
/Modyfikuj dowolnie, np. wyklucz tylko użytkowników niemających określonego schematu autoryzacji lub roli./

return l_predicate;
end f_vpd_column_masking;

Ekran pokazujący tabelę.Ekran pokazujący tabelę.

Teraz użytkownik APEX SANDBOX widzi wszystkie dane w tabeli EMPLOYEES, ale użytkownik SANDBOX_LTD widzi tylko wartości NULL zamiast kwot w kolumnie wynagrodzeń.

Pokazywanie danych wrażliwych użytkownikom APEX z określonymi rolami

Aby pokazać dane wrażliwe użytkownikom APEX z konkretnymi rolami, musisz najpierw stworzyć rolę – na przykład SENSITIVE_DATA – a następnie przypisać ją tylko niektórym użytkownikom.

Ekran pokazujący ustawienia APEX.

Następnie będziesz musiał zaktualizować kod funkcji polityki VPD.

--connect as ADMIN (as I'm using Oracle Cloud)
create or replace function f_vpd_column_masking(
   p_schema varchar2,
   p_obj    varchar2
) return varchar2 as
   l_database_user      varchar2(255) DEFAULT USER;
   l_apex_user APEX_WORKSPACE_APEX_USERS.user_name%TYPE;
   l_predicate varchar2(100);
   l_sensitive_data_access boolean :=false;
begin
    --get apex user
    l_apex_user := SYS_CONTEXT('APEX$SESSION', 'APP_USER');

 --if database user is SANDBOX_LTD or apex user is SANDBOX_LTD then VPD policy hides data
   if l_database_user in ('SANDBOX_LTD') or l_apex_user = 'SANDBOX_LTD' then
      l_predicate := '1=2';
   end if;

    --is user not has role SENSITIVE_DATA then data is hidden
      l_sensitive_data_access := APEX_ACL.HAS_USER_ROLE (
                    p_application_id  => v('APP_ID'),
                    p_user_name       => l_apex_user,
                    p_role_static_id  => 'SENSITIVE_DATA' );

    IF NOT l_sensitive_data_access then
      l_predicate := '1=2';
    END IF;


   return l_predicate;
end f_vpd_column_masking;

Podsumowanie

I to wszystko. Jak widzisz, ukrywanie konkretnych danych przed użytkownikami Oracle DB lub Oracle APEX jest całkiem proste – wystarczy kilka prostych zapytań, aby wykonać zadanie. Jeśli chcesz dowiedzieć się więcej o VPD lub wdrożyć bardziej skomplikowane polityki, sprawdź tę dokumentację dotyczącą kontroli dostępu do danych od Oracle. Jeśli masz jakieś pytania, skontaktuj się ze mną pod adresem rgrzegorczyk@pretius.com. Możesz również sprawdzić moje inne artykuły na blogu Pretius:

  1. What is Liquibase and how to start using it? Automate your database scripts deployment with this Liquibase tutorial
  2. Liquibase for teams: GIT collaboration and easy deployment
  3. Boost the management of your Oracle Database version control changes with Liquibase
  4. Oracle APEX charts: How to make them look better using linear gradients

Szukasz firmy tworzącej oprogramowanie?

Pracuj z zespołem, który pomógł już dziesiątkom rynkowych liderów. Umów spotkanie, by dowiedzieć się:

  • Jak działają nasze produkty
  • Jak możesz oszczędzić czas i pieniądze
  • Czym nasze rozwiązania różnią się od konkurencji

Przebieg kontaktu z Pretius

Dbamy o bezpieczeństwo Twoich danych: Certyfikat ISO

Działamy zgodnie z normą ISO 27001, zapewniając najwyższy poziom bezpieczeństwa Twoich danych.
certified dekra 27001
© 2026 Pretius. All right reserved.