פרטיות נתונים היא הגנה על נתונים כמו פרטים אישיים מזהים (PII) מפני אנשים שלא אמורה להיות להם גישה אליהם. בדף הזה מתוארות כמה גישות לפרטיות נתונים שבהן אתם יכולים להשתמש כדי להגן על הפרטים האישיים המזהים שלכם ב-Cloud SQL.
אתם יכולים להשתמש ב-Cloud SQL כדי לאחסן את הפרטים האישיים המזהים שלכם בצורה מאובטחת. אתם רוצים לוודא שהמידע הזה יעובד עם ההגנה הגבוהה ביותר על הפרטיות, כדי שלא תהיה גישה אליו בטעות. לדוגמה, אם אתם מאחסנים פרטי כרטיסי אשראי או נתוני בריאות במסדי הנתונים שלכם, אתם יכולים להשתמש ב-Cloud SQL כדי להסתיר או להסוות פרטים אישיים מזהים ממשתמשים ללא הרשאות.
כדי לאבטח את הפרטים האישיים המזהים ב-Cloud SQL, כדאי להשתמש באסטרטגיות הבאות:
- אבטחה ברמת העמודה
- גישה מבוססת-תצוגה
- אבטחה ברמת השורה
- הסתרת נתונים ואנונימיזציה של נתונים
- הצפנת נתונים
אבטחה ברמת העמודה
אבטחה ברמת העמודה מאפשרת להגביל את האנשים שיכולים לראות את התוכן בעמודות ספציפיות בטבלאות של מסד הנתונים. הרשאות ברמת העמודה רלוונטיות להצהרות INSERT, UPDATE, SELECT ו-REFERENCES.
לדוגמה, נניח שיש אתר קמעונאי שבו רוצים לנהל את הפרטים האישיים המזהים של שני משתמשים: Jack ו-Alice.
--User: "admin"
CREATE SCHEMA secure_schema;
CREATE TABLE secure_schema.user_details(id bigint, name text, age smallint, email_id text, password text);
--For this example, passwords are stored in plain text for demonstration
--purposes only. In production, never store passwords in plain text.
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,'jack@example.com','testpass');
INSERT INTO secure_schema.user_details VALUES(2,'alice',37,'alice@example.com','testpass');
GRANT USAGE ON SCHEMA secure_schema TO analyst_ro;
--Grant read permissions on specific columns only.
GRANT SELECT (id, name, age) ON secure_schema.user_details TO analyst_ro;
--User: "analyst_ro"
SELECT * FROM secure_schema.user_details;
ERROR: permission denied for table user_details
SELECT name, age, password FROM secure_schema.user_details;
ERROR: permission denied for table user_details
SELECT id, name,age FROM secure_schema.user_details;
id | name | age
----+-------+----
1 | jack | 34
2 | alice | 37
אם תכללו את העמודות המוגבלות בהצהרת SELECT או שתזינו SELECT *, תופיע הודעת שגיאה. Cloud SQL מאבטח את הפרטים האישיים המזהים של ג'ק ואליס בעמודות האלה.
אפשר גם להשתמש בהצהרת GRANT אחת כדי לשלב הרשאות שונות.
GRANT SELECT (id,name,age), UPDATE (name) ON secure_schema.user_details TO analyst_ro;
גישה מבוססת-תצוגה
אפשר גם להשיג אבטחה ברמת העמודה על ידי יצירת תצוגה בטבלה, החרגה או הסתרה של עמודות שרוצים להסתיר ממשתמשים אחרים, ומתן גישה לתצוגה במקום לטבלה.
בדוגמה הבאה מוסבר איך להשתמש בגישה מבוססת-תצוגה באתר הקמעונאי כדי לאבטח את הפרטים האישיים המזהים של ג'ק ואליס:
--User: "admin"
CREATE SCHEMA analyst_ro;
CREATE VIEW analyst_ro.user_details AS SELECT id, name, age FROM secure_schema.user_details;
GRANT USAGE ON SCHEMA analyst_ro TO analyst_ro;
GRANT SELECT ON analyst_ro.user_details TO analyst_ro;
--User: "analyst_ro"
SELECT id,name,age FROM user_details;
id | name | age
----+-------+----
1 | jack | 34
2 | alice | 37
SELECT * FROM user_details;
id | name | age
----+-------+----
1 | jack | 34
2 | alice | 37
בדוגמה הזו, נוצרת סכימה נפרדת לתצוגה כדי שהשם שלה יהיה זהה לשם של הטבלה. בגישה שמבוססת על תצוגות, אפשר להשתמש ב-SELECT *.
אתם יכולים גם ליצור תצוגה ולהסתיר את העמודות של טבלת מסד הנתונים, כדי שמשתמשים ללא הרשאות לא יוכלו לראות את הפרטים האישיים המזהים שמוסתרים.
CREATE OR REPLACE VIEW analyst_ro.user_details AS SELECT id, name, age, 'redacted@example.com' as email_id,'*****'::text as password FROM secure_schema.user_details;
SELECT * FROM user_details;
id | name | age | email_id | password
----+-------+-----+----------------------+---------
1 | jack | 34 | redacted@example.com | *****
2 | alice | 37 | redacted@example.com | *****
אבטחה ברמת השורה
אבטחה ברמת העמודה וגישה מבוססת-תצוגה מאפשרות להסתיר פרטים אישיים מזהים (PII) בעמודות של טבלאות במסד הנתונים ממשתמשים ספציפיים. עם זאת, לפעמים רוצים לסנן את הנתונים האלה ולתת גישה לשורות ספציפיות בטבלה. הטבלה הזו מכילה את הפרטים האישיים המזהים שרק משתמשים מסוימים יכולים לגשת אליהם, על סמך תנאי המשתמשים שעומדים בדרישות. האפשרות הזו נקראת אבטחה ברמת השורה.
אבטחה ברמת השורה שימושית לאפליקציות עם כמה דיירים, שבהן למשתמשים יש הרשאות גישה לקריאה ולכתיבה רק לפרטים האישיים המזהים שלהם. ב-Cloud SQL, לטבלאות יכולות להיות כללי מדיניות אבטחה ברמת השורה שמגבילים, על בסיס כל משתמש, את השורות שהמשתמשים יכולים לראות על ידי יצירת שאילתות, או את השורות שהמשתמשים יכולים להוסיף, לעדכן או למחוק על ידי הפעלת פקודות לשינוי נתונים.
בדוגמה של אתר הקמעונאות, אתם יכולים להטמיע אבטחה ברמת השורה בשביל ג'ק ואליס, כך שכל משתמש יוכל לגשת רק לפרטים האישיים המזהים שלו.
--User: "admin"
--Create and enable a policy for row-level security
CREATE POLICY user_details_rls_pol ON secure_schema.user_details FOR ALL TO PUBLIC USING (name=current_user);
ALTER TABLE secure_schema.user_details ENABLE ROW LEVEL SECURITY;
SELECT * FROM secure_schema.user_details;
id | name | age | email_id | password
----+-------+-----+-------------------+---------
1 | jack | 34 | jack@example.com | testpass
2 | alice | 37 | alice@example.com | testpass
--User: "jack"
SELECT * FROM secure_schema.user_details;
id | name | age | email_id | password
----+------+-----+------------------+---------
1 | jack | 34 | jack@example.com | testpass
--User: "alice"
SELECT * FROM secure_schema.user_details;
id | name | age | email_id | password
----+-------+-----+-------------------+---------
2 | alice | 37 | alice@example.com | testpass
משתמשים שהוקצו לתפקידים עם המאפיין BYPASSRLS יכולים לעקוף את האבטחה ברמת השורה כשהם ניגשים לטבלה. בעלי הטבלה יכולים גם לעקוף את האבטחה ברמת השורה. אם רוצים להחיל אבטחה ברמת השורה על בעלי הטבלה, משתמשים בפקודה ALTER TABLE ... FORCE ROW LEVEL SECURITY.
לפעמים לא רוצים להחיל אבטחה ברמת השורה על שורות בטבלה של מסד נתונים. לדוגמה, אם אתם משתמשים ב-pg_dump כדי לגבות את הטבלה, אתם לא רוצים ששורות יושמטו מהגיבוי. כדי למנוע את זה, צריך להגדיר את פרמטר ההגדרה row_security לערך OFF למשתמש שמבצע את הגיבוי. אם שורות כלשהן מסוננות על סמך אבטחה ברמת השורה, מופיעה הודעת שגיאה.
הסתרת נתונים ואנונימיזציה שלהם
בנוסף להסתרת נתונים באמצעות גישה מבוססת-תצוגה, אתם יכולים להסתיר נתונים באמצעות התוסף postgresql_anonymizer. התוסף הזה מסתיר או מחליף פרטים אישיים מזהים (PII) או נתונים רגישים מבחינה מסחרית ממסד נתונים של PostgreSQL.
לשימוש בתוסף על פני גישה שמבוססת על תצוגה יש את היתרונות הבאים:
יש לכם מגוון פונקציות מיסוך כמו החלפה, אקראיות, זיוף, פסאודונימיזציה, ערבול חלקי, ערבוב, הוספת רעש והכללה.
אתם יכולים ליצור נתונים מוסתרים משמעותיים שאפשר להשתמש בהם לבדיקת פונקציונליות ולעיבוד נתונים.
אתם יכולים להשתמש בשפת הגדרת הנתונים (DDL) של PostgreSQL כדי להצהיר על כללי הסתרה ולציין את אסטרטגיית האנונימיזציה בהגדרת הטבלה.
התקנה והגדרה של התוסף postgresql_anonymizer
כדי להשתמש בתוסף הזה במכונה של Cloud SQL:
עורכים את המכונה ומגדירים את הדגל
cloudsql.enable_anonלערךon. במאמר הגדרת דגלים של מסדי נתונים מוסבר איך מגדירים דגלים ומפורטים הדגלים שנתמכים בתוסף.אם אתם מתכננים להשתמש במסכות דינמיות והטבלאות שאתם רוצים להסתיר לא נמצאות בסכימה
public, צריך להגדיר את הדגלanon.sourceschemaלשם של הסכימה שמכילה את הטבלאות האלה. בדוגמאות שבדף הזה, הדגל מוגדר לערךsecure_schema.כדי ליצור את התוסף במסד הנתונים, מריצים את הפקודה הבאה:
--Connect to the PostgreSQL database CREATE EXTENSION IF NOT EXISTS anon CASCADE; SELECT anon.init();
אחרי שמתקינים ומגדירים את התוסף, משתמשים בו במכונה כדי להטמיע אסטרטגיות אנונימיזציה של מסכה דינמית, מסכה סטטית ודאמפ אנונימי.
מסכה דינמית
אפשר להשתמש במסכות דינמיות כדי להגדיר כללי הסתרה למשתמשים ספציפיים. המשתמשים האלה לא יכולים לראות פרטים אישיים מזהים. במקום זאת, הם רואים נתונים מוסתרים. כל שאר המשתמשים רואים את הנתונים ללא אנונימיזציה. האפשרות הזו שימושית בסביבות ייצור כשלא רוצים לשנות את הפרטים האישיים המזהים, אלא רק להסתיר אותם ממשתמשים מסוימים.
בדוגמה של אתר הקמעונאות, אתם יכולים להטמיע מסכות דינמיות כדי שהאדמין יוכל לראות את כתובות האימייל והסיסמאות של ג'ק ואליס ללא מסכה, אבל האנליסט יוכל לראות רק נתונים עם מסכה.
--Activate the dynamic masking engine
SELECT anon.start_dynamic_masking();
--Declare the masking user and masking rules
--analyst_ro is the masked user with select privileges on the
--user_details table
SECURITY LABEL FOR anon ON ROLE analyst_ro IS 'MASKED';
SECURITY LABEL FOR anon ON COLUMN secure_schema.user_details.email_id IS 'MASKED WITH FUNCTION anon.fake_email()';
SECURITY LABEL FOR anon ON COLUMN secure_schema.user_details.password IS 'MASKED WITH FUNCTION anon.hash(password)';
--Verify that the masked user is configured. The search_path must include
--the mask schema followed by the schema set in the anon.sourceschema flag.
SELECT rolconfig FROM pg_roles WHERE rolname = 'analyst_ro';
rolconfig
--------------------------------------
{"search_path=mask, secure_schema"}
--User: "admin" (can see all unmasked data)
SELECT * FROM secure_schema.user_details;
id | name | age | email_id | password
----+-------+-----+-------------------+---------
1 | jack | 34 | jack@example.com | testpass
2 | alice | 37 | alice@example.com | testpass
--User: "analyst_ro" (open a new connection; note that the "email_id" and
--"password" columns are replaced with masked data)
--Data in the password column is truncated for better formatting.
SELECT * FROM user_details;
id | name | age | email_id | password
----+-------+-----+------------------------+-----------------
1 | jack | 34 | alisontodd@example.com | 13d249f2cb4127b
2 | alice | 37 | amanda35@example.com | 13d249f2cb4127b
--The masked user can't query the source table directly.
SELECT * FROM secure_schema.user_details;
ERROR: permission denied for schema secure_schema
כשמתחילים את ההסתרה הדינמית, התוסף יוצר תצוגה בסכימה mask לכל טבלה בסכימה שמוגדרת על ידי הדגל anon.sourceschema. כשמסמנים תפקיד כ-MASKED, התוסף מבצע את הפעולות הבאות:
- מבטלת את ההרשאות שניתנו ישירות לתפקיד בסכימת המקור.
- נותנת לתפקיד את ההרשאה
USAGEבסכימהmaskואת ההרשאהSELECTבכל תצוגה (view) שבה, כולל תצוגות של טבלאות שהתפקיד לא יכול היה לשלוח אליהן שאילתות לפני כן. - הגדרת
search_pathשל התפקיד לסכימהmask, ואחריה לסכימת המקור.
המשתמש המוסווה רואה נתונים מוסווים רק כשהוא שולח שאילתה לטבלה בלי לציין את שם הסכימה, כך שהשם מתורגם לתצוגה בסכימה mask. שאילתות שמציינות את שם הסכימה, כמו SELECT * FROM secure_schema.user_details, עוקפות את הסכימה mask ונכשלות עם שגיאת הרשאה. ההגדרה search_path חלה כשהמשתמש מתחבר, ולכן משתמשים מוסתרים צריכים לפתוח חיבור חדש אחרי שמתייגים את התפקיד.
מסכה סטטית
אתם יכולים להשתמש במסכות סטטיות כדי להסיר את הפרטים האישיים המזהים בטבלה, בהתאם לקריטריונים שמוגדרים בכללי ההסתרה, ולהחליף את המידע הזה בנתונים מוסתרים. המשתמשים לא יכולים לאחזר את הנתונים ללא אנונימיזציה. האפשרות הזו שימושית בסביבות בדיקה כשרוצים לשנות את הפרטים האישיים המזהים ולא רוצים שמשתמשים יראו את המידע הזה.
בדוגמה של אתר הקמעונאות, אתם יכולים להטמיע מסכות סטטיות כדי שאף משתמש לא יוכל לראות את כתובות האימייל והסיסמאות של ג'ק ואליס בלי מסכה. במקום זאת, הם רואים רק נתונים מוסתרים.
--User: "admin"
SELECT * FROM secure_schema.user_details;
id | name | age | email_id | password
----+-------+-----+-------------------+---------
1 | jack | 34 | jack@example.com | testpass
2 | alice | 37 | alice@example.com | testpass
--Apply earlier defined masking rules to the table permanently.
--Now all users see masked data only.
SELECT anon.anonymize_table('secure_schema.user_details');
anonymize_table
-----------------
t
--User: "analyst_ro"
--Data in the password column is truncated for better formatting.
select * from secure_schema.user_details;
id | name | age | email_id | password
----+-------+-----+---------------------------------+-----------------
1 | jack | 34 | christophercampbell@example.com | 13d249f2cb4127b
2 | alice | 37 | annebenitez@example.com | 13d249f2cb4127b
דאמפ אנונימי
להשתמש ב-dumps אנונימיים כדי לייצא נתונים מוסתרים לקובץ SQL. בדוגמה של אתר הקמעונאות, אתם יכולים ליצור קובץ dump לנתונים המוסתרים שנמצאים בטבלה user_details.
--Launch pg_dump_anon to apply earlier defined masking rules. pg_dump_anon
--reads the source table directly, so connect as a user that has the SELECT
--privilege on the table and that isn't labeled as MASKED.
pg_dump_anon -h HOSTIP -p 5432 -d DATABASE_NAME -U admin --table=secure_schema.user_details --file=user_details_anonymized.sql
הצפנת נתונים
למרות שאפשר להסתיר פרטים אישיים מזהים, המידע נשמר במסד הנתונים כטקסט פשוט. האדמין יכול לראות את המידע הזה.
משתמשים בתוסף pgcrypto כדי להצפין את הפרטים האישיים המזהים לפני שמאחסנים אותם. כך, רק משתמשים שיש להם מפתח הצפנה תקין יכולים לפענח את המידע ולראות אותו כטקסט פשוט.
לתוסף pgcrypto יש כמה פונקציות hash ו-encrypt.
גיבוב (hash)
גיבוב (hash) הוא פונקציה קריפטוגרפית חד-כיוונית שבה המטרה היא רק להצפין את הפרטים האישיים המזהים. הפונקציה הזו שימושית לאחסון סיסמאות בפורמט מגובב (hashed) ולהתאמה בין הסיסמאות שהמשתמשים מזינים לבין הסיסמאות המגובבות. סיסמאות מגובבות אף פעם לא מפוענחות כטקסט פשוט.
בדוגמה של אתר הקמעונאות, אתם יכולים להשתמש בתוסף pgcrypto כדי לגבב את הסיסמה של דני לפני שאתם שומרים אותה בטבלה user_details.
--Hash passwords before storing them in the user_details table.
TRUNCATE TABLE secure_schema.user_details;
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,'jack@example.com',crypt('testpassword', gen_salt('bf')));
--Match the hashed data with user entered password
SELECT id, name FROM secure_schema.user_details WHERE email_id = 'jack@example.com' AND password = crypt('testpassword', password);
id | name
----+-----
1 | jack
הצפנה
משתמשים בפונקציה קריפטוגרפית של הצפנה כדי להצפין פרטים אישיים מזהים באמצעות מפתח. המשתמשים צריכים את המפתח הזה כדי לפענח את המידע לטקסט פשוט. השיטה הזו שימושית לאחסון פרטי כרטיס אשראי ופרטי בנק, כשאפליקציות רוצות לאחזר את הפרטים האישיים המזהים בפורמט קריא.
בדוגמה של אתר הקמעונאות, הסיסמה וכתובת האימייל של דני מוצפנות. משתמשים שיש להם את מפתח ההצפנה יכולים לפענח את המידע הזה ולראות אותו כטקסט פשוט. לכל שאר המשתמשים תוצג הודעת שגיאה.
--"user_acc_key" is the encryption key
TRUNCATE TABLE secure_schema.user_details;
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,pgp_sym_encrypt('jack@example.com','user_acc_key'),pgp_sym_encrypt('testpassword','user_acc_key'));
--User: "admin" (queries without an encryption key)
--Data in the email_id and password columns are truncated for better
--formatting.
SELECT * FROM secure_schema.user_details;
id | name | age | email_id | password
----+------+-----+------------------+--------------------
1 | jack | 34 | \xc30d0407030209 | \xc30d040703028962
--User: "app_user" (queries with a valid encryption key)
SELECT name,pgp_sym_decrypt(email_id::bytea,'user_acc_key'),pgp_sym_decrypt(password::bytea,'user_acc_key') FROM secure_schema.user_details;
name | pgp_sym_decrypt | pgp_sym_decrypt
------+-------------------+----------------
jack | jack@example.com | testpassword
--If a user uses the wrong encryption key, then the following error message appears:
SELECT name,pgp_sym_decrypt(email_id::bytea,'user_bad_key'),
pgp_sym_decrypt(password::bytea,'user_bad_key') FROM secure_schema.user_details;
ERROR: Wrong key or corrupt data
המאמרים הבאים
כדי להגן על פרטים אישיים מזהים מפני גישה לא מורשית, אתם יכולים להשתמש באמצעי הבקרה הנוספים הבאים: