SQL Academy · درس

تدقيق الوصول

تتبّع من يمكنه رؤية كل شيء

الدرس 4 من 413 خطوة

تدقيق الوصول درس مجاني في SQL Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Academy 4 دروس في المجموع.

لماذا ندقّق في الوصول

تُعد معرفة من وصل إلى أي بيانات ومتى حجر أساس في أمان قواعد البيانات. إذ ينشئ التدقيق سجلًا موثوقًا للأحداث، ما يتيح لك اكتشاف الوصول غير المصرّح به، والتحقيق في الحوادث، وتلبية متطلبات الامتثال مثل GDPR وHIPAA وSOC 2.

ستتعلّم في هذا الدرس كيفية تصميم جداول التدقيق، والتقاط أحداث الوصول تلقائيًا باستخدام المشغّلات، واستخدام ميزات التسجيل المضمّنة في PostgreSQL، والاستعلام عن سجل التدقيق للإجابة عن السؤال: من يمكنه رؤية ماذا؟

تصميم جدول سجل التدقيق

الخطوة الأولى هي إنشاء جدول مخصص يسجل كل حدث مهم. ويخزّن سجل التدقيق الجيد اسم الجدول، ونوع العملية، والقيم القديمة والجديدة، والمستخدم الذي نفّذ الإجراء، والطابع الزمني الدقيق.

ينشئ المثال أدناه جدول audit_log عامًا باستخدام أعمدة JSONB لتخزين لقطات الصفوف، وهو مرن بما يكفي للتعامل مع أي جدول من دون تغييرات في المخطط.

CREATE TABLE audit_log (
  id          BIGSERIAL PRIMARY KEY,
  event_time  TIMESTAMPTZ NOT NULL DEFAULT now(),
  db_user     TEXT NOT NULL DEFAULT current_user,
  app_user    TEXT,
  table_name  TEXT NOT NULL,
  operation   TEXT NOT NULL CHECK (operation IN ('INSERT','UPDATE','DELETE','SELECT')),
  row_id      BIGINT,
  old_data    JSONB,
  new_data    JSONB
);

تسجيل المستخدم الحالي

توفر PostgreSQL عدة دوال مضمّنة لتحديد الجهة التي تنفّذ الاستعلام. تُعيد current_user اسم الدور الفعّال بعد أي SET ROLE، بينما تُعيد session_user دائمًا دور تسجيل الدخول الأصلي، بصرف النظر عن تبديل الأدوار.

في التطبيقات التي تستخدم دور قاعدة بيانات مشتركًا واحدًا، لكنها تمرّر مستخدمًا على مستوى التطبيق عبر SET LOCAL app.current_user، يمكنك قراءة هذا الإعداد باستخدام current_setting().

-- Who is the database user right now?
SELECT current_user,
       session_user;

-- Read an application-level user injected by the app layer
SELECT current_setting('app.current_user', true) AS app_user;

كتابة دالة مشغّل للتدقيق

تُعد دالة المشغّل الطريقة الأكثر موثوقية لالتقاط أحداث تغييرات البيانات، لأنها تُستدعى تلقائيًا، ولا يمكن لأي كود في التطبيق تجاوزها. تسجّل الدالة أدناه كل عمليات INSERT وUPDATE وDELETE على أي جدول تُربط به، مع تخزين قيم الصفوف القديمة والجديدة بصيغة JSONB.

لاحظ استخدام TG_TABLE_NAME، أي الجدول الذي شغّل المشغّل، واستخدام row_to_json() لتحويل قيم الصفوف إلى صيغة قابلة للتخزين.

CREATE OR REPLACE FUNCTION fn_audit_changes()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
  INSERT INTO audit_log (
    db_user,
    app_user,
    table_name,
    operation,
    row_id,
    old_data,
    new_data
  ) VALUES (
    current_user,
    current_setting('app.current_user', true),
    TG_TABLE_NAME,
    TG_OP,
    COALESCE(NEW.id, OLD.id),
    CASE WHEN TG_OP = 'INSERT' THEN NULL ELSE row_to_json(OLD)::JSONB END,
    CASE WHEN TG_OP = 'DELETE' THEN NULL ELSE row_to_json(NEW)::JSONB END
  );
  RETURN NULL;
END;
$$;

إرفاق المشغّل بجدول

بعد إنشاء دالة المشغّل، يمكنك إرفاقها بكل جدول تريد تدقيقه باستخدام عبارة CREATE TRIGGER. ويضمن استخدام AFTER كتابة البيانات فعليًا قبل إنشاء إدخال السجل. وتستدعي عبارة FOR EACH ROW المشغّل مرة واحدة لكل صف تم تعديله.

يُطبَّق المشغّل هنا على جدول patients افتراضي، ويسجّل كل عمليات INSERT وUPDATE وDELETE تلقائيًا.

CREATE TRIGGER trg_audit_patients
AFTER INSERT OR UPDATE OR DELETE
ON patients
FOR EACH ROW
EXECUTE FUNCTION fn_audit_changes();

تدقيق استعلامات SELECT

لا تلتقط مشغّلات تغييرات البيانات سوى عمليات الكتابة. ولتدقيق الوصول إلى البيانات للقراءة، تحتاج إلى نهج مختلف. يتمثل أحد الخيارات في استخدام مشغّل على مستوى العبارة من نوع AFTER SELECT، وهو مدعوم في PostgreSQL 14+ ضمن سياقات معينة. أما النمط الأكثر شيوعًا فهو تسجيل عمليات القراءة صراحةً داخل دالة أو view يغلّف الجدول الحساس.

يغلّف المثال أدناه جدولًا حساسًا داخل دالة تسجّل كل عملية قراءة قبل إعادة النتائج.

CREATE OR REPLACE FUNCTION get_patient_record(p_id INT)
RETURNS SETOF patients
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
BEGIN
  -- Log the read access
  INSERT INTO audit_log (db_user, app_user, table_name, operation, row_id)
  VALUES (
    current_user,
    current_setting('app.current_user', true),
    'patients',
    'SELECT',
    p_id
  );

  RETURN QUERY
  SELECT * FROM patients WHERE id = p_id;
END;
$$;

التسجيل المضمّن في PostgreSQL

يوفر ملف postgresql.conf في PostgreSQL إمكانات قوية للتسجيل من جهة الخادم، ولا يتطلب أي كود من التطبيق. ويؤدي ضبط log_min_duration_statement إلى تسجيل أي استعلام يتجاوز حدًا زمنيًا معينًا. كما يسجّل ضبط log_connections وlog_disconnections عمليات تسجيل الدخول والخروج.

يستخدم الاستعلام أدناه عرض النظام pg_stat_activity لرؤية الجلسات النشطة حاليًا، وهو شكل خفيف من مراقبة الوصول المباشرة.

-- See who is currently connected and what they are running
SELECT pid,
       usename        AS db_user,
       application_name,
       client_addr,
       state,
       query_start,
       LEFT(query, 80) AS current_query
FROM   pg_stat_activity
WHERE  datname = current_database()
ORDER  BY query_start DESC;

الاستعلام في سجل التدقيق

لا تكون قيمة سجل التدقيق كبيرة إلا إذا أمكن الاستعلام عنه بفعالية. تشمل الأسئلة الشائعة: أي مستخدم وصل إلى سجل ما مؤخرًا، وما الذي تغيّر في صف بمرور الوقت، وكم عدد عمليات قراءة البيانات الحساسة التي حدثت خلال آخر 24 ساعة.

يعثر الاستعلام أدناه على جميع المستخدمين الذين وصلوا إلى سجل مريض محدد، ويرتب النتائج بدءًا من الأحدث.

SELECT event_time,
       db_user,
       app_user,
       operation,
       old_data,
       new_data
FROM   audit_log
WHERE  table_name = 'patients'
  AND  row_id = 42
ORDER  BY event_time DESC
LIMIT  20;

اكتشاف أنماط الوصول المشبوهة

بعد جمع بيانات التدقيق، يمكن كتابة استعلامات ترصد الحالات الشاذة. فعلى سبيل المثال، قد يشير مستخدم يقرأ فجأة عددًا من الصفوف يفوق المعتاد بكثير، أو سجل حساس جرى الوصول إليه عدة مرات خلال فترة قصيرة، إلى محاولة لاستخراج البيانات.

يحصي الاستعلام أدناه أحداث SELECT لكل مستخدم للتطبيق خلال الساعة الأخيرة، ويسلط الضوء على كل من قرأ أكثر من 100 صف.

SELECT app_user,
       COUNT(*) AS records_accessed
FROM   audit_log
WHERE  operation = 'SELECT'
  AND  event_time >= now() - INTERVAL '1 hour'
GROUP  BY app_user
HAVING COUNT(*) > 100
ORDER  BY records_accessed DESC;

حماية سجل التدقيق نفسه

لا يمكن الوثوق بسجل تدقيق قابل للتعديل. ينبغي تأمينه بحيث لا يتمكن المستخدمون العاديون وأدوار التطبيق من حذف الصفوف أو تحديثها. ويتمثل النهج الأكثر أمانًا في منح دور التطبيق صلاحية INSERT فقط، وقصر صلاحية SELECT على دور مخصص للتدقيق.

يمكن أيضًا فرض عدم قابلية التغيير باستخدام مشغّل يرفع استثناءً إذا حاول أي شخص تحديث صف من صفوف التدقيق أو حذفه.

-- Only the app role may insert; nobody may update or delete
REVOKE ALL     ON audit_log FROM PUBLIC;
GRANT  INSERT  ON audit_log TO app_role;
GRANT  SELECT  ON audit_log TO auditor_role;

-- Trigger to block any tampering
CREATE OR REPLACE FUNCTION fn_protect_audit()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
  RAISE EXCEPTION 'audit_log rows are immutable';
  RETURN NULL;
END;
$$;

CREATE TRIGGER trg_protect_audit
BEFORE UPDATE OR DELETE ON audit_log
FOR EACH ROW EXECUTE FUNCTION fn_protect_audit();

تدقيق قرارات سياسة RLS

عند تفعيل أمان الصفوف، يخفي PostgreSQL الصفوف بصمت بدلًا من رفع أخطاء. وهذا يجعل من الصعب معرفة ما إذا كان المستخدم قد حاول قراءة صف لم يكن مسموحًا له برؤيته. ويتمثل أحد الأساليب في إضافة سياسة متساهلة تُدرج دائمًا سجل تدقيق قبل أن تعمل السياسة التقييدية على تصفية الصفوف.

يوضح الاستعلام أدناه كيفية فحص سياسات RLS الموجودة على جدول والأدوار التي تنطبق عليها.

-- View all RLS policies on the patients table
SELECT polname       AS policy_name,
       polcmd        AS command,
       polroles::TEXT AS applies_to,
       polqual::TEXT  AS using_expression,
       polwithcheck::TEXT AS with_check_expression
FROM   pg_policy
WHERE  polrelid = 'patients'::REGCLASS
ORDER  BY polname;

اختبار المعرفة

اختبروا مدى فهمكم لتدقيق الوصول في SQL.

مراجعة الدرس

استكشفتم في هذا الدرس كيفية إنشاء نظام متكامل لتدقيق الوصول في PostgreSQL:

  • جدول سجل التدقيق — جدول قائم على JSONB يلتقط من نفّذ الإجراء، وما الإجراء الذي نفّذه، ومتى نفّذه.
  • دالة المشغّل — تسجل تلقائيًا أحداث INSERT وUPDATE وDELETE لأي جدول مرفق، باستخدام TG_TABLE_NAME وrow_to_json() وcurrent_user.
  • تدقيق عمليات القراءة — تغليف الجداول الحساسة داخل دوال تسجل أحداث SELECT قبل إرجاع البيانات.
  • المراقبة المضمنة — يعرض pg_stat_activity الجلسات النشطة، بينما يسجل التسجيل من جانب الخادم الاستعلامات دون إجراء تغييرات على التعليمات البرمجية.
  • اكتشاف الحالات الشاذة — يمكن للاستعلامات التجميعية على سجل التدقيق رصد الأحجام غير المعتادة من عمليات الوصول.
  • عدم القابلية للتغيير — إلغاء UPDATE وDELETE من جدول التدقيق وإضافة مشغّل حاجب لمنع العبث.

يمثل مسار التدقيق المصمم جيدًا أداتكم الأكثر موثوقية للإجابة عن سؤال من وصل إلى ماذا، ويشكل العمود الفقري لأي تحقيق متعلق بالامتثال أو الأمان.

البدء مجانًا

تعلم SQL مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
46
الدروس
183

الأسئلة الشائعة

هل درس «تدقيق الوصول» مجاني؟

نعم — نص درس «تدقيق الوصول» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Academy، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Academy 4 دروس في المجموع.

ماذا ستتعلم في «تدقيق الوصول»؟

تتبّع من يمكنه رؤية كل شيء تتمرن على SQL Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ SQL Academy؟

لا تُشترط خبرة سابقة. SQL Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «تدقيق الوصول»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس SQL Academy هذا؟

نعم. كل درس في SQL Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الأدوار والامتيازات
  2. سياسات الأمان على مستوى الصفوف
  3. الأذونات على مستوى الأعمدة
  4. تدقيق الوصول
← العودة إلى SQL Academy