ניהול אבטחת מידע באפליקציה באמצעות תצוגות מאובטחות עם פרמטרים ב-AlloyDB Omni

בוחרים גרסת תיעוד:

אתם יכולים להשתמש בתצוגות מאובטחות עם פרמטרים ב-AlloyDB Omni כדי להגביל את הגישה לנתונים על סמך פרמטרים עם שם שספציפיים לאפליקציה, כמו פרטי הכניסה של המשתמש באפליקציה. תצוגות מאובטחות עם פרמטרים משפרות את האבטחה ואת בקרת הגישה על ידי הרחבת הפונקציונליות של תצוגות PostgreSQL. בנוסף, התצוגות האלה מצמצמות את הסיכונים בהרצת שאילתות לא מהימנות מאפליקציות, כי הן אוכפות באופן אוטומטי הגבלות על כל שאילתה שמופעלת.

מידע נוסף זמין במאמרים סקירה כללית על תצוגות מאובטחות עם פרמטרים ואבטחה ושליטה בגישה לנתוני אפליקציות באמצעות תצוגות מאובטחות עם פרמטרים.

לפני שמתחילים

התמיכה בתצוגות עם פרמטרים ב-AlloyDB AI ניתנת באמצעות parameterized_views, שהוא תוסף של AlloyDB ל-PostgreSQL.

ההנחה בדף הזה היא שהתקנתם את AlloyDB Omni. הוראות להתקנת AlloyDB Omni ב-Linux

לפני שמשתמשים בתצוגות מאובטחות עם פרמטרים, צריך לבצע את הפעולות הבאות פעם אחת בסביבת Linux. אפשר להחיל כל הגדרה באמצעות ALTER SYSTEM או לערוך ישירות את postgresql.conf.

  1. מוסיפים את parameterized_views אל shared_preload_libraries.
  2. מפעילים את התכונה על ידי הגדרת parameterized_views.enabled=on.
  3. מפעילים מחדש את שרת PostgreSQL כדי שהשינויים ייכנסו לתוקף.

    -- See the current shared_preload_libraries
    SHOW shared_preload_libraries;
    ALTER SYSTEM SET shared_preload_libraries="...,parameterized_views";
    ALTER SYSTEM SET parameterized_views.enabled=on;
    
  4. כדי ליצור את התוסף parameterized_views בכל מסד נתונים שבו רוצים ליצור תצוגה עם פרמטרים, צריך להשתמש ב-psql:

    -- Requires parameterized_views.enabled set to true
    CREATE EXTENSION parameterized_views;
    

    כשיוצרים את התוסף, המערכת יוצרת גם סכימה בשם parameterized_views, כדי שממשקי ה-API ייכללו במרחב השמות של הסכימה הזו, וכדי שלא יהיה קונפליקט בין ממשקי ה-API לבין ממשקי API קיימים.

יצירת תצוגה מאובטחת עם פרמטרים

כדי ליצור תצוגה מאובטחת עם פרמטרים, פועלים לפי השלבים הבאים:

  1. מריצים את פקודת ה-DDL‏ CREATE VIEW, כמו בדוגמה הבאה:

    CREATE VIEW secure_checked_items WITH (security_barrier) AS
    SELECT bag_id, timestamp, location
    FROM checked_items t
    WHERE customer_id = $@app_end_userid;
    

    בדוגמה הקודמת, התצוגה המאובטחת עם הפרמטרים מאפשרת גישה לשלוש עמודות מטבלה בשם checked_items. התצוגה המקדימה מגבילה את התוצאות לשורות שבהן הערך של checked_items.customer_id תואם לפרמטר נדרש. משתמשים במאפיינים הבאים:

    • יוצרים את התצוגה באמצעות האפשרות security_barrier.
    • כדי להגביל את המשתמשים באפליקציה כך שהם יוכלו לראות רק את השורות שיש להם הרשאה לגשת אליהן, מוסיפים את הפרמטרים הנדרשים בהגדרת התצוגה באמצעות התחביר $@PARAMETER_NAME. תרחיש נפוץ הוא בדיקת הערך של עמודה בסעיף WHERE באמצעות COLUMN = $@PARAMETER_NAME.
    • ‫$@PARAMETER_NAME מציין פרמטר של תצוגה עם שם. הערך שלו מסופק כשמשתמשים ב-API של execute_parameterized_query. הדרישות לגבי פרמטרים של תצוגה בעלת שם:
      • פרמטרים של תצוגה עם שם חייבים להתחיל באות (a-z).
      • אפשר להשתמש באותיות עם סימנים דיאקריטיים ובאותיות לא לטיניות, וגם בקו תחתון (_).
      • התווים הבאים יכולים להיות אותיות, קווים תחתונים או ספרות (0-9).
      • פרמטרים של תצוגה עם שם לא יכולים להכיל את התו $.
      • הפרמטרים של תצוגות מפורטות הם תלויי אותיות רישיות. לדוגמה, $@PARAMETER_NAME יפורש באופן שונה מ-$@parameter_name.
  2. נותנים את ההרשאה SELECT בתצוגה לכל משתמש במסד הנתונים שמורשה להריץ שאילתות בתצוגה.

  3. צריך להעניק את ההרשאה USAGE בסכימה שמכילה את הטבלאות שמוגדרות בתצוגה לכל משתמש במסד הנתונים שמורשה לשלוח שאילתות לתצוגה.

מידע נוסף זמין במאמר בנושא אבטחה ושליטה בגישה לנתוני אפליקציות באמצעות תצוגות מאובטחות עם פרמטרים.

הגדרת אבטחה לאפליקציה

כדי להגדיר אבטחה לאפליקציות באמצעות תצוגות מאובטחות עם פרמטרים, פועלים לפי השלבים הבאים:

  1. יוצרים את התצוגות המאובטחות עם הפרמטרים כמשתמש עם הרשאת אדמין. המשתמש הזה הוא משתמש במסד הנתונים של AlloyDB Omni שמבצע פעולות אדמין באפליקציה, כולל הגדרת מסד הנתונים וניהול האבטחה.
  2. יוצרים תפקיד חדש במסד הנתונים כדי להריץ שאילתות בתצוגות מאובטחות עם פרמטרים. זהו תפקיד במסד הנתונים של AlloyDB Omni שהאפליקציה משתמשת בו כדי להתחבר למסד הנתונים ולהיכנס אליו, וכדי להריץ שאילתות על תצוגות עם פרמטרים.
  3. נותנים לתפקיד החדש הרשאות לתצוגות המאובטחות, שבדרך כלל כוללות הרשאות SELECT לתצוגות ו-USAGE לסכימות.
  4. להגביל את האובייקטים שהתפקיד הזה יכול לגשת אליהם לסט המינימלי הנדרש של פונקציות ואובייקטים ציבוריים שהאפליקציה צריכה. אל תתנו גישה לסכימות ולטבלאות שלא מוגדרות כציבוריות.
  5. כשמבצעים שאילתה על התצוגות, האפליקציה מספקת את הערכים של פרמטרי התצוגה הנדרשים, שקשורים לזהות המשתמש באפליקציה.

שאילתה של תצוגה מאובטחת עם פרמטרים

כדי לשלוח שאילתה לתצוגה מאובטחת עם פרמטרים, משתמשים באחת מהאפשרויות הבאות שמתאימה ביותר לתרחיש השימוש שלכם:

  • מבוסס-JSON: משתמשים ב-API הזה כדי להריץ את השאילתה בבת אחת ולהחזיר שורות JSON.
  • ‫CURSOR-based: משתמשים ב-API הזה כשיש שאילתות ארוכות יותר או כשיש שאילתות גדולות ורוצים לאחזר את התוצאה בקבוצות. הפונקציה execute_parameterized_query שסופקה על ידי התוסף parameterized_views מקבלת שם של סמן.
  • PREPARE EXECUTE: משמש להצהרות מוכנות שאפשר להריץ כמה פעמים עם ערכי פרמטרים שונים.

כדי לשלוח שאילתה לתצוגות מאובטחות עם פרמטרים, משתמשים בפונקציה execute_parameterized_query() שמסופקת על ידי התוסף parameterized_views.

‫API בפורמט JSON

ל-API הזה יש מגבלות כי הוא מצהיר על סמן לשאילתה הנתונה. לכן, השאילתה צריכה להיות תואמת לסמנים של PostgreSQL. לדוגמה, ה-API של CURSOR לא תומך בהצהרות DO או SHOW.

בנוסף, ה-API הזה לא מגביל את התוצאות לפי גודל או לפי מספר השורות שמוחזרות.

מריצים את הפונקציה execute_parameterized_query(), עם התחביר הבא:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => SQL_QUERY,
    param_names => ARRAY [PARAMETER_NAMES],
    param_values => ARRAY [PARAMETER_VALUES]
)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫SQL_QUERY: שאילתת SQL שהסעיף FROM שלה מתייחס לתצוגות מאובטחות עם פרמטרים.
  • ‫PARAMETER_NAMES: רשימה של שמות פרמטרים שצריך להעביר כמחרוזות.
  • ‫PARAMETER_VALUES: רשימה של ערכי פרמטרים שצריך להעביר.
    • הרשימה הזו צריכה להיות באותו גודל כמו הרשימה param_names, וסדר הערכים צריך להתאים לסדר השמות.
    • הסוג המדויק של הערכים נקבע לפי השאילתה והגדרת התצוגה עם הפרמטרים. המערכת מבצעת המרות של סוגים לפי הצורך, ואם אפשר, בהתאם לערך הפרמטר שצוין. אם יש אי-התאמה בין הסוגים, תופיע שגיאה.

הפונקציה מחזירה טבלה של אובייקטים בפורמט JSON. כל שורה בטבלה שווה לערך ROW_TO_JSON() של שורת התוצאה של השאילתה המקורית.

כדי לשלוח שאילתה לתצוגה מאובטחת שמכילה פרמטרים, אפשר להשתמש בדוגמה הבאה:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => 'SELECT * FROM secure_checked_items',
    param_names => ARRAY ['app_end_userid'],
    param_values => ARRAY ['40']
)

השימוש ב-API הזה מגביל את הגודל של קבוצת התוצאות לפי הגודל בקילובייט (kB) של התוצאות ולפי מספר השורות. כדי להגדיר את המגבלות האלה, אתם יכולים להשתמש ב-parameterized_views.json_results_max_size וב-parameterized_views.json_results_max_rows.

ל-API הזה יש מגבלות כי הוא מצהיר על סמן לשאילתה הנתונה. לכן, השאילתה צריכה להיות תואמת לסמני מיקום (cursors) של PostgreSQL. לדוגמה, ה-API של CURSOR לא תומך בהצהרות DO או SHOW.

בנוסף, ה-API הזה לא מגביל את התוצאות לפי גודל או לפי מספר השורות שמוחזרות.

מריצים את הפונקציה execute_parameterized_query(), עם התחביר הבא:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => SQL_QUERY,
    param_names => ARRAY [PARAMETER_NAMES],
    param_values => ARRAY [PARAMETER_VALUES]
)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫SQL_QUERY: שאילתת SQL שהסעיף FROM שלה מתייחס לתצוגות מאובטחות עם פרמטרים.
  • ‫PARAMETER_NAMES: רשימה של שמות פרמטרים להעברה כמחרוזות.
  • ‫PARAMETER_VALUES: רשימה של ערכי פרמטרים להעברה.
  • הרשימה הזו צריכה להיות באותו גודל כמו הרשימה param_names, וסדר הערכים צריך להתאים לסדר השמות.
  • הסוג המדויק של הערכים נגזר מהשאילתה ומהגדרת התצוגה עם הפרמטרים. המרות של סוגים מתבצעות לפי הצורך, ואם אפשר, בהתאם לערך הפרמטר שצוין. אם יש חוסר התאמה בין הסוגים, נוצרת שגיאה.

הפונקציה מחזירה טבלה של אובייקטים בפורמט JSON. כל שורה בטבלה שווה לערך ROW_TO_JSON() של שורת התוצאה של השאילתה המקורית.

כדי לשלוח שאילתה לתצוגה מאובטחת שמכילה פרמטרים, אפשר להשתמש בדוגמה הבאה:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => 'SELECT * FROM secure_checked_items',
    param_names => ARRAY ['app_end_userid'],
    param_values => ARRAY ['40']
)

השימוש ב-API הזה מגביל את הגודל של קבוצת התוצאות לפי הגודל בקילובייט (kB) של התוצאות ולפי מספר השורות. כדי להגדיר את המגבלות האלה, משתמשים ב-parameterized_views.json_results_max_size וב-parameterized_views.json_results_max_rows.

CURSOR API

ל-API הזה יש מגבלות כי הוא מגדיר סמן לשאילתה הנתונה. לכן, השאילתה צריכה להיות תואמת לסמני מיקום (cursors) של PostgreSQL. לדוגמה, ה-API של CURSOR לא תומך בהצהרות DO או SHOW.

בנוסף, ה-API הזה לא מגביל את התוצאות לפי גודל או לפי מספר השורות שמוחזרות.

מריצים את הפונקציה execute_parameterized_query(), עם התחביר הבא:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => SQL_QUERY,
    param_names => ARRAY [PARAMETER_NAMES],
    param_values => ARRAY [PARAMETER_VALUES]
)

מחליפים את מה שכתוב בשדות הבאים:

  • ‫SQL_QUERY: שאילתת SQL שהסעיף FROM שלה מתייחס לתצוגות מאובטחות עם פרמטרים.
  • ‫PARAMETER_NAMES: רשימה של שמות פרמטרים שצריך להעביר כמחרוזות.
  • ‫PARAMETER_VALUES: רשימה של ערכי פרמטרים שצריך להעביר.
    • הרשימה הזו צריכה להיות באותו גודל כמו הרשימה param_names, וסדר הערכים צריך להתאים לסדר השמות.
    • הסוג המדויק של הערכים נקבע לפי השאילתה והגדרת התצוגה עם הפרמטרים. המערכת מבצעת המרות של סוגים לפי הצורך, ואם אפשר, בהתאם לערך הפרמטר שצוין. אם יש אי-התאמה בין הסוגים, תופיע שגיאה.

הפונקציה מחזירה טבלה של אובייקטים בפורמט JSON. כל שורה בטבלה שווה לערך ROW_TO_JSON() של שורת התוצאה של השאילתה המקורית.

כדי לשלוח שאילתה לתצוגה מאובטחת שמכילה פרמטרים, אפשר להשתמש בדוגמה הבאה:

SELECT * FROM
parameterized_views.execute_parameterized_query(
    query => 'SELECT * FROM secure_checked_items',
    param_names => ARRAY ['app_end_userid'],
    param_values => ARRAY ['40']
)

השימוש ב-API הזה מגביל את הגודל של קבוצת התוצאות לפי הגודל בקילובייט (kB) של התוצאות ולפי מספר השורות. כדי להגדיר את המגבלות האלה, אתם יכולים להשתמש ב-parameterized_views.json_results_max_size וב-parameterized_views.json_results_max_rows.

הצהרת PREPARE

משתמשים בפקודה PREPARE .. AS RESTRICTED כדי ליצור הצהרה מוכנה שמפנה לתצוגות עם פרמטרים. ההצהרות המוכנות האלה תומכות בפרמטרים של מיקום ומחילות הגבלות שונות כשמבצעים אותן. למידע נוסף, קראו את המאמר בנושא מנגנון אבטחה.

התכונה הזו מרחיבה את הפקודות PREPARE ו-EXECUTE כדי לתמוך בפרמטרים של תצוגות עם שם. כדאי להשתמש בהצהרות מוכנות כדי להימנע מהתקורה של ניתוח, פענוח וכתיבה מחדש בכל פעם שההצהרה מופעלת. כך אפשר לשפר משמעותית את הביצועים, במיוחד בשאילתות מורכבות או כאלה שמופעלות לעיתים קרובות. הצהרה מוכנה היא אובייקט בצד השרת שיכול לשפר את הביצועים על ידי קומפילציה מראש ואחסון של הצהרת SQL עם פרמטרים לביצוע מאוחר יותר.

יש מגבלות על ה-API הזה כי צריך לאפשר את ההצהרה בPREPAREstatement, כלומר רק הצהרות SELECT ו-VALUES נתמכות.

בנוסף, ה-API הזה לא מגביל את התוצאות לפי גודל או מספר השורות שמוחזרות.

כדי ליצור הצהרה מוכנה שמפנה לתצוגות עם פרמטרים, מריצים את הפקודה PREPARE .. AS RESTRICTED:

PREPARE pquery (/POSITIONAL_PARAM_TYPES/)
        AS RESTRICTED query % a query that may refer to parameterized views
EXECUTE pquery (/POSITIONAL_PARAM_VALUES/)
      WITH VIEW PARAMETERS (VIEW_PARAM_NAME1 = VIEW_PARAM_VALUE1[, ...]);

מחליפים את מה שכתוב בשדות הבאים:

  • ‫POSITIONAL_PARAM_TYPES: פרמטר אחד או יותר של מיקום שמשמשים בשאילתה RESTRICTED.
  • ‫POSITIONAL_PARAM_VALUES: הערכים בפועל שמוחלפים בפרמטרים הממוקמים שמוגדרים בהצהרה PREPARE.
  • ‫VIEW_PARAM_NAME: שם הפרמטר שצפוי בתצוגות עם פרמטרים שאליהן מתייחסת השאילתה RESTRICTED.
  • ‫VIEW_PARAM_VALUE: הערכים בפועל שמועברים לפרמטרים viewParamName המתאימים של התצוגות המפורטות עם הפרמטרים.

כדי לכלול פרמטרים בהצהרה מוכנה, צריך לספק רשימה של סוגי נתונים בהצהרה PREPARE. בהצהרה שאתם מכינים, אתם מתייחסים לפרמטרים לפי מיקום, למשל באמצעות $1 ו-$2.

משתמשים בפקודה EXECUTE .. WITH VIEW PARAMETERS כדי להפעיל הצהרה שהוכנה מראש ונוצרה באמצעות הפקודה PREPARE .. AS RESTRICTED. אם בהצהרת PREPARE שיוצרת את ההצהרה צוינו פרמטרים מיקומיים, צריך להעביר קבוצת פרמטרים תואמת להצהרת EXECUTE. חובה להעביר את כל הפרמטרים של התצוגה עם השם שנדרשים על ידי תצוגות עם פרמטרים בסעיף WITH VIEW PARAMETERS.

בדוגמה הבאה מוצגת שאילתה של תצוגה מאובטחת עם פרמטרים:

PREPARE pquery (timestamp) AS RESTRICTED SELECT * FROM secure_checked_items WHERE timestamp > $1;

EXECUTE pquery (current_date - 1) WITH VIEW PARAMETERS (app_end_userid = 40);
EXECUTE pquery (current_date - 30) WITH VIEW PARAMETERS (app_end_userid = 40);

הגבלות שנאכפות על שאילתות

ברשימה הבאה מפורטות הפעולות המוגבלות לשאילתות שאתם מריצים באמצעות האפשרויות שמתוארות בקטע הרצת שאילתות בתצוגה מאובטחת עם פרמטרים:

  • אסור להפעיל באופן רקורסיבי ממשקי API כלשהם – execute_parameterized_query או באמצעות EXECUTE .. WITH VIEW PARAMETERS – כדי להשתמש רק בערכים שצוינו על ידי האפליקציה. ההגבלה הזו גם מונעת שימוש בשאילתה כדי לעקוף את מעטפת האבטחה של קבוצת ערכי הפרמטרים הנתונה.
  • חלק מהתוספים שמפעילים סשן חדש ברקע אסורים, כולל התוספים dblink, pg_cron ו-pg_background.
  • ברשימה הבאה מפורטים מבני השאילתות המוגבלים שמותרים:

    • מותר להשתמש בדוחות SELECT לקריאה בלבד.
    • מותר להשתמש בהצהרות SHOW, בהצהרות CALL ובהצהרות DO לקריאה בלבד.
    • אסור להשתמש בפקודות DML כמו INSERT, UPDATE ו-DELETE.
    • אסור להשתמש בהצהרות DDL כמו CREATE TABLE ו-ALTER TABLE.
    • סוגים אחרים של הצהרות, כמו LOAD, SET, CLUSTER, LOCK, CHECKPOINT ו-EXPLAIN, אסורים.
  • הצהרות EXPLAIN אסורות כדי למנוע אפשרות של התקפות בערוץ סמוי באמצעות תוכניות לביצוע שאילתה. מידע נוסף זמין במאמר בנושא ערוץ סמוי.

  • תצוגות מאובטחות עם פרמטרים מספקות הגדרות שעוזרות לנהל משאבים שמשמשים את ממשקי ה-API כדי לשלוח שאילתות לתצוגות עם פרמטרים, כמו parameterized_views.statement_timeout. מידע נוסף זמין במאמר דגלים של AlloyDB ל-PostgreSQL.

הצגת רשימה של כל התצוגות שמכילות פרמטרים

משתמשים בתוסף parameterized_views כדי להציג את כל התצוגות עם הפרמטרים במסד הנתונים באמצעות התצוגה all_parameterized_views. הפלט של התצוגה הזו זהה לזה של התצוגה pg_views, אבל ב-all_parameterized_views מופיעות רק תצוגות עם פרמטרים בעלי שם.

כדי להציג רשימה של תצוגות עם פרמטרים, משתמשים בדוגמה הבאה:

postgres=# select * from parameterized_views.all_parameterized_views ;
schemaname |      viewname      | viewowner |                       definition
-----------+--------------------+-----------+---------------------------------------------------------
public     | checked_items_view | postgres  |  SELECT checked_items.bag_id,                          +
           |                    |           |     checked_items."timestamp",                         +
           |                    |           |     checked_items.location                             +
           |                    |           |    FROM checked_items                                  +
           |                    |           |   WHERE (checked_items.customer_id = $@app_end_userid);

כדי להציג תצוגה עם פרמטרים ב-all_parameterized_views, ודאו שהתצוגה עם הפרמטרים מכילה לפחות פרמטר אחד עם שם בהגדרה שלה.

המאמרים הבאים