خانه/ امنیت/ Permissions

GRANT، REVOKE و DENY: سه فعل مجوزدهی

متوسط ۱۳ دقیقه مطالعه

مجوزها در SQL Server با سه دستور کنترل می‌شوند:

  • GRANT — اجازه‌ی انجام یک عمل را می‌دهد.
  • REVOKE — یک اجازه‌ی داده‌شده را پس می‌گیرد (به حالت خنثی/نامشخص برمی‌گرداند — نه اجازه، نه منع صریح).
  • DENY — صریحاً و با قدرت بیشتر، یک عمل را ممنوع می‌کند.
sql
GRANT SELECT, INSERT ON Students TO ali_app;
REVOKE INSERT ON Students FROM ali_app;
DENY DELETE ON Students TO ali_app;

سلسله‌مراتب: از سرور تا یک ستون خاص

مجوزها می‌توانند در چند سطح مختلف تعریف شوند — از کلی‌ترین تا جزئی‌ترین:

سرور
مثلاً sysadmin
پایگاه‌داده
مثلاً db_owner
Schema
مثلاً dbo
شیء (جدول/ویو)
مثلاً Students
ستون
مثلاً فقط city

مجوز در سطح بالاتر (مثلاً کل پایگاه‌داده) به‌طور خودکار به سطوح پایین‌تر ارث می‌رسد، مگر این‌که در سطح پایین‌تر صراحتاً محدودتر شده باشد.

قانون طلایی: DENY همیشه برنده می‌شود

اگر یک User از طریق چند نقش مختلف، هم GRANT و هم DENY برای یک عمل مشخص دریافت کرده باشد (مثلاً یک نقش اجازه‌ی SELECT روی جدولی می‌دهد، اما نقش دیگر همان User صریحاً همان SELECT را DENY کرده)، DENY همیشه برنده است — مهم نیست از چند نقش دیگر GRANT گرفته باشد. این طراحی عمدی است: برای مسدودکردن قطعی یک دسترسی حساس (مثلاً یک ستون حاوی حقوق کارکنان)، کافی‌ست یک بار DENY بزنی و مطمئن باشی هیچ نقش دیگری نمی‌تواند دورش بزند.

اصل حداقل دسترسی (Principle of Least Privilege)

قانون طلایی امنیت پایگاه‌داده: به هر User یا نقش، فقط حداقل مجوزی را بده که برای انجام کارش لازم دارد — نه بیشتر. اگر برنامه‌ای فقط باید داده بخواند، به آن db_datawriter یا db_owner نده. این اصل، حتی اگر یک حمله (مثل تزریق SQL که در درس بعدی می‌بینیم) موفق شود، دامنه‌ی خسارت را به‌شدت محدود می‌کند.

DENY روی ستون: پنهان‌کردن اطلاعات حساس

می‌توان فقط یک ستون را برای یک User ممنوع کرد، در حالی که بقیه‌ی ستون‌ها در دسترس‌اند:

sql
GRANT SELECT ON dbo.Employees TO ali_app;
DENY  SELECT ON dbo.Employees(Salary) TO ali_app;

حالا SELECT * برای ali_app خطا می‌دهد، چون * ستون ممنوع را هم شامل می‌شود؛ اما SELECT FullName, Department موفق است.

بررسی مجوزها بدون حدس زدن

به‌جای فرض‌کردن، مجوز مؤثر را بپرس:

sql
-- آیا کاربر فعلی روی این جدول SELECT دارد؟ (۱ = بله، ۰ = خیر)
SELECT HAS_PERMS_BY_NAME('dbo.Employees', 'OBJECT', 'SELECT');

-- تست با هویت یک User دیگر
EXECUTE AS USER = 'ali_app';
  SELECT * FROM dbo.Employees;
REVERT;

مجوز روی Schema

اگر جدول‌های یک گروه در یک Schema باشند، به‌جای تک‌تک جدول‌ها یک بار روی Schema مجوز بده؛ جدول‌های جدیدی که بعداً در آن Schema ساخته شوند هم خودکار پوشش داده می‌شوند:

sql
GRANT SELECT ON SCHEMA::Reports TO ReportReaders;
مثال‌های کامل‌تر (از جمله تفاوت REVOKE و DENY وقتی کاربر عضو یک Role است) را در مقاله‌ی دستور DENY در SQL Server ببین.

جمع‌بندی این درس

  • GRANT اجازه می‌دهد، REVOKE اجازه‌ی قبلی را خنثی می‌کند، DENY صریحاً منع می‌کند.
  • مجوزها سلسله‌مراتبی‌اند: از سرور تا پایگاه‌داده تا Schema تا شیء و حتی تک‌تک ستون.
  • DENY همیشه بر هر GRANTی، از هر نقشی، غلبه می‌کند.
  • اصل حداقل دسترسی، مهم‌ترین اصل عملی امنیت پایگاه‌داده است.

در آخرین درس این فصل، سراغ تزریق SQL (SQL Injection) می‌رویم — تنها درسی در این فصل که می‌توانیم واقعاً و به‌صورت زنده در همین Playground نشانش دهیم.

تمرین‌های خودآزمایی

اول خودت جواب بده، بعد پاسخ را باز کن و مقایسه کن.

۱تفاوت REVOKE و DENY چیست؟نمایش پاسخ
پاسخ

REVOKE مجوزِ صادرشده (Grant یا Deny) را برمی‌دارد و وضعیت را به «بدون مجوز» برمی‌گرداند؛ DENY صراحتاً ممنوع می‌کند و بر GRANT غلبه دارد.

۲به ali_app اجازه‌ی SELECT روی students بده، ولی DELETE را ممنوع کن.نمایش پاسخ
پاسخ
GRANT SELECT ON dbo.students TO ali_app;
DENY  DELETE ON dbo.students TO ali_app;