امنیت پیشرفته SQL Server مدیریت رمز عبور با Enforce password policy

افزایش امنیت SQL Server: مدیریت پیشرفته سیاست‌های رمز عبور با Enforce password policy

SQL Server به‌طور پیش‌فرض، مدیریت ورودهای مبتنی بر احراز هویت ویندوز را با رعایت سیاست‌های رمز عبور سیستم عامل انجام می‌دهد. با این حال، برای کاربرانی که از احراز هویت استاندارد SQL Server استفاده می‌کنند، اعمال سیاست‌های پیچیده رمز عبور ممکن است چالش‌برانگیز باشد، مگر اینکه از SQL Server 2012 یا نسخه‌های جدیدتر با گزینه “Enforce password policy” استفاده شود. اما حتی این گزینه نیز تنها بخشی از نیازها را پوشش می‌دهد و نمی‌تواند سیاست‌های سفارشی یا پیچیده‌تر را پیاده‌سازی کند. ابزار EnforcePass راه حلی رایگان و قدرتمند برای این مشکل ارائه می‌دهد.

EnforcePass یک ابزار مبتنی بر SQL Server است که امکان پیاده‌سازی و اعمال سیاست‌های جامع رمز عبور را برای تمامی ورودهای استاندارد SQL Server فراهم می‌کند. این ابزار به شما کمک می‌کند تا امنیت پایگاه داده خود را با فراتر رفتن از محدودیت‌های پیش‌فرض، به میزان قابل توجهی افزایش دهید.

چرا به EnforcePass نیاز دارید؟

در بسیاری از سناریوها، نیاز به سیاست‌های رمز عبور وجود دارد که فراتر از آنچه SQL Server یا حتی سیستم‌عامل ویندوز ارائه می‌دهند، باشد. فرض کنید می‌خواهید:

  • تاریخچه رمز عبور را نگهداری کنید تا کاربران نتوانند رمزهای عبور قبلی خود را مجدداً استفاده کنند.
  • حداقل طول رمز عبور را برای همه کاربران SQL Server تعیین کنید.
  • الزاماتی برای ترکیب رمز عبور (حروف بزرگ، حروف کوچک، اعداد، نمادها) تعیین کنید.
  • از استفاده کلمات رایج یا نام کاربری در رمز عبور جلوگیری کنید.
  • انقضای رمز عبور را مدیریت کرده و کاربران را مجبور به تغییر رمز عبور به صورت دوره‌ای کنید.
  • قفل شدن حساب کاربری را پس از چندین تلاش ناموفق برای ورود، پیاده‌سازی کنید.

EnforcePass تمام این قابلیت‌ها و بیشتر را به شما ارائه می‌دهد و مدیریت امنیت رمز عبور در SQL Server را به سطحی جدید ارتقاء می‌بخشد.

نحوه عملکرد EnforcePass

این ابزار بر اساس مجموعه‌ای از جداول، رویه‌ها، توابع و تریگرها در یک پایگاه داده مجزا (به نام enforcepass) کار می‌کند. این معماری تضمین می‌کند که سیاست‌ها به طور مؤثر و بدون تداخل با پایگاه داده‌های کاربردی شما اعمال شوند.

جداول مورد نیاز

EnforcePass از سه جدول اصلی برای ذخیره‌سازی سیاست‌ها، تاریخچه رمز عبور و اطلاعات ورودهای ناموفق استفاده می‌کند.

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


CREATE DATABASE enforcepass
GO
USE enforcepass
GO

CREATE TABLE [dbo].[PasswordPolicy](
	[LoginName] [sysname] NOT NULL,
	[MinLength] [int] NULL,
	[MinUpperCase] [int] NULL,
	[MinLowerCase] [int] NULL,
	[MinNumeric] [int] NULL,
	[MinSymbol] [int] NULL,
	[NotUserName] [bit] NULL,
	[BlackList] [xml] NULL,
	[HistoryCount] [int] NULL,
	[ExpirationDays] [int] NULL,
	[AllowChangePassword] [bit] NULL,
	[AllowLogin] [bit] NULL,
	[LockoutThreshold] [int] NULL,
	[LockoutDurationMinutes] [int] NULL,
	[LastSetDate] [datetime] NULL,
	[LastChangePasswordDate] [datetime] NULL,
 CONSTRAINT [PK_PasswordPolicy] PRIMARY KEY CLUSTERED 
(
	[LoginName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

CREATE TABLE [dbo].[PasswordHistory](
	[LoginName] [sysname] NOT NULL,
	[PasswordHash] [varbinary](128) NOT NULL,
	[SetDate] [datetime] NOT NULL,
 CONSTRAINT [PK_PasswordHistory] PRIMARY KEY CLUSTERED 
(
	[LoginName] ASC,
	[SetDate] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[FailedLogins](
	[LoginName] [sysname] NOT NULL,
	[FailedCount] [int] NOT NULL,
	[LastFailedLoginDate] [datetime] NULL,
	[LockedOut] [bit] NOT NULL,
	[LockOutDate] [datetime] NULL,
 CONSTRAINT [PK_FailedLogins] PRIMARY KEY CLUSTERED 
(
	[LoginName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
مدیریت سیاست‌ها

Stored Procedure PasswordPolicy_Set به شما امکان می‌دهد تا سیاست‌های رمز عبور را برای یک کاربر خاص تنظیم کنید. این روال پارامترهای مختلفی را برای تعیین حداقل طول، الزامات کاراکتر، تاریخچه، بلک‌لیست و غیره می‌پذیرد.

مثالی از نحوه تنظیم یک سیاست جدید:


USE [enforcepass]
GO

EXEC [dbo].[PasswordPolicy_Set] 
	@LoginName = N'TestUser',
	@MinLength = 8,
	@MinUpperCase = 1,
	@MinLowerCase = 1,
	@MinNumeric = 1,
	@MinSymbol = 1,
	@NotUserName = 1,
	@BlackList = N'password123456',
	@HistoryCount = 5,
	@ExpirationDays = 90,
	@AllowChangePassword = 1,
	@AllowLogin = 1,
	@LockoutThreshold = 5,
	@LockoutDurationMinutes = 30
GO

روال PasswordPolicy_Get اطلاعات سیاست رمز عبور را برای یک LoginName خاص بازمی‌گرداند.

اعمال و اعتبارسنجی رمز عبور

قلب EnforcePass در مجموعه‌ای از توابع و رویه‌هایی است که رمز عبور جدید را در برابر سیاست‌های تعریف شده اعتبارسنجی می‌کنند.

اعتبارسنجی عمومی رمز عبور

روال Password_Validate یک رمز عبور را در برابر تمام سیاست‌های تعریف شده اعتبارسنجی می‌کند و در صورت عدم رعایت هر یک از سیاست‌ها، یک پیام خطا بازمی‌گرداند. این روال برای استفاده در تریگرهای تغییر رمز عبور ایده‌آل است.

این بخش از کد روال Password_Validate را نشان می‌دهد:


CREATE PROCEDURE [dbo].[Password_Validate]
	@LoginName sysname,
	@Password nvarchar(128)
AS
BEGIN
	-- Check policy exists
	IF NOT EXISTS (SELECT 1 FROM dbo.PasswordPolicy WHERE LoginName = @LoginName)
	BEGIN
		-- No policy for this login. Success
		RETURN 0
	END

	-- Get policy
	DECLARE @MinLength int, @MinUpperCase int, @MinLowerCase int, @MinNumeric int, @MinSymbol int, @NotUserName bit, @BlackList xml, @HistoryCount int, @ExpirationDays int, @AllowChangePassword bit, @AllowLogin bit, @LastSetDate datetime
	SELECT @MinLength = MinLength, @MinUpperCase = MinUpperCase, @MinLowerCase = MinLowerCase, @MinNumeric = MinNumeric, @MinSymbol = MinSymbol, @NotUserName = NotUserName, @BlackList = BlackList, @HistoryCount = HistoryCount, @ExpirationDays = ExpirationDays, @AllowChangePassword = AllowChangePassword, @AllowLogin = AllowLogin, @LastSetDate = LastSetDate
	FROM dbo.PasswordPolicy WHERE LoginName = @LoginName

	-- Validate complexity
	EXEC dbo.Password_ValidateComplexity @LoginName = @LoginName, @Password = @Password, @MinLength = @MinLength, @MinUpperCase = @MinUpperCase, @MinLowerCase = @MinLowerCase, @MinNumeric = @MinNumeric, @MinSymbol = @MinSymbol, @NotUserName = @NotUserName, @BlackList = @BlackList

	-- Validate history
	EXEC dbo.Password_ValidateHistory @LoginName = @LoginName, @Password = @Password, @HistoryCount = @HistoryCount

	-- Check if login is allowed
	IF @AllowLogin = 0
	BEGIN
		RAISERROR ('Login is not allowed to login', 16, 1)
		RETURN 1
	END

	RETURN 0
END
GO
اعتبارسنجی پیچیدگی

Password_ValidateComplexity رویه‌ای است که تمام جنبه‌های پیچیدگی رمز عبور (طول، ترکیب کاراکتر، نام کاربری، بلک‌لیست) را بررسی می‌کند. این روال از توابع اسکالر مجزا برای بررسی وجود حروف بزرگ، کوچک، اعداد و نمادها استفاده می‌کند.

این کد روال Password_ValidateComplexity را نشان می‌دهد:


CREATE PROCEDURE [dbo].[Password_ValidateComplexity]
	@LoginName sysname,
	@Password nvarchar(128),
	@MinLength int,
	@MinUpperCase int,
	@MinLowerCase int,
	@MinNumeric int,
	@MinSymbol int,
	@NotUserName bit,
	@BlackList xml
AS
BEGIN
	-- Minimum Length Check
	IF @MinLength IS NOT NULL AND LEN(@Password) < @MinLength
	BEGIN
		RAISERROR ('Password does not meet minimum length policy', 16, 1)
		RETURN 1
	END

	-- Minimum Uppercase Check
	IF @MinUpperCase IS NOT NULL AND dbo.udf_HasUpperCase(@Password) < @MinUpperCase
	BEGIN
		RAISERROR ('Password does not meet minimum uppercase policy', 16, 1)
		RETURN 1
	END

	-- Minimum Lowercase Check
	IF @MinLowerCase IS NOT NULL AND dbo.udf_HasLowerCase(@Password) < @MinLowerCase
	BEGIN
		RAISERROR ('Password does not meet minimum lowercase policy', 16, 1)
		RETURN 1
	END

	-- Minimum Numeric Check
	IF @MinNumeric IS NOT NULL AND dbo.udf_HasNumeric(@Password) < @MinNumeric
	BEGIN
		RAISERROR ('Password does not meet minimum numeric policy', 16, 1)
		RETURN 1
	END

	-- Minimum Symbol Check
	IF @MinSymbol IS NOT NULL AND dbo.udf_HasSymbol(@Password) < @MinSymbol
	BEGIN
		RAISERROR ('Password does not meet minimum symbol policy', 16, 1)
		RETURN 1
	END

	-- Not User Name Check
	IF @NotUserName = 1 AND @LoginName LIKE '%' + @Password + '%'
	BEGIN
		RAISERROR ('Password cannot contain your login name', 16, 1)
		RETURN 1
	END

	-- Black List Check
	IF @BlackList IS NOT NULL AND EXISTS (
		SELECT 1 FROM @BlackList.nodes('/words/word') AS T(C) 
		WHERE LOWER(@Password) LIKE '%' + LOWER(T.C.value('.', 'nvarchar(50)')) + '%'
	)
	BEGIN
		RAISERROR ('Password contains a blacklisted word', 16, 1)
		RETURN 1
	END

	RETURN 0
END
GO
توابع اعتبارسنجی کاراکتر

چندین تابع اسکالر تعریف شده‌اند که تعداد حروف بزرگ، کوچک، اعداد یا نمادها را در یک رشته بازمی‌گردانند. این توابع در Password_ValidateComplexity برای بررسی الزامات ترکیب کاراکترها استفاده می‌شوند.

مثال تابع برای بررسی حروف کوچک:


CREATE FUNCTION [dbo].[udf_HasLowerCase]
(
	@string nvarchar(128)
)
RETURNS int
AS
BEGIN
	DECLARE @len int = LEN(@string)
	DECLARE @i int = 1
	DECLARE @count int = 0

	WHILE @i <= @len
	BEGIN
		IF SUBSTRING(@string, @i, 1) LIKE '[a-z]'
			SET @count = @count + 1
		SET @i = @i + 1
	END

	RETURN @count
END
GO

توابع مشابهی برای حروف بزرگ (udf_HasUpperCase)، اعداد (udf_HasNumeric) و نمادها (udf_HasSymbol) نیز وجود دارند که از منطق مشابهی برای شمارش انواع کاراکترها استفاده می‌کنند.

اعتبارسنجی تاریخچه رمز عبور

Password_ValidateHistory بررسی می‌کند که آیا رمز عبور جدید قبلاً توسط کاربر استفاده شده است یا خیر. این روال از جدول PasswordHistory برای مقایسه هش رمز عبور استفاده می‌کند.


CREATE PROCEDURE [dbo].[Password_ValidateHistory]
	@LoginName sysname,
	@Password nvarchar(128),
	@HistoryCount int
AS
BEGIN
	IF @HistoryCount IS NOT NULL AND @HistoryCount > 0
	BEGIN
		-- Check history for password
		IF EXISTS (
			SELECT 1 FROM dbo.PasswordHistory
			WHERE LoginName = @LoginName AND PasswordHash = HASHBYTES('SHA2_512', @Password)
		)
		BEGIN
			RAISERROR ('Password has been used recently', 16, 1)
			RETURN 1
		END
	END
	RETURN 0
END
GO
مدیریت ورودهای ناموفق

روال Login_Failed برای ثبت تلاش‌های ناموفق برای ورود و قفل کردن حساب کاربری پس از رسیدن به آستانه تعیین شده استفاده می‌شود.


CREATE PROCEDURE [dbo].[Login_Failed]
	@LoginName sysname
AS
BEGIN
	-- Update failed login count
	UPDATE dbo.FailedLogins SET FailedCount = FailedCount + 1, LastFailedLoginDate = GETDATE()
	WHERE LoginName = @LoginName

	IF @@ROWCOUNT = 0
	BEGIN
		INSERT dbo.FailedLogins (LoginName, FailedCount, LastFailedLoginDate, LockedOut)
		VALUES (@LoginName, 1, GETDATE(), 0)
	END

	-- Check if account needs to be locked
	DECLARE @LockoutThreshold int, @LockoutDurationMinutes int
	SELECT @LockoutThreshold = LockoutThreshold, @LockoutDurationMinutes = LockoutDurationMinutes
	FROM dbo.PasswordPolicy WHERE LoginName = @LoginName

	IF @LockoutThreshold IS NOT NULL AND @LockoutDurationMinutes IS NOT NULL
	BEGIN
		IF (SELECT FailedCount FROM dbo.FailedLogins WHERE LoginName = @LoginName) >= @LockoutThreshold
		BEGIN
			UPDATE dbo.FailedLogins SET LockedOut = 1, LockOutDate = GETDATE()
			WHERE LoginName = @LoginName
		END
	END
END
GO
بازنشانی وضعیت قفل

روال Login_ResetLockout حساب کاربری قفل شده را بازنشانی می‌کند.


CREATE PROCEDURE [dbo].[Login_ResetLockout]
	@LoginName sysname
AS
BEGIN
	UPDATE dbo.FailedLogins SET FailedCount = 0, LockedOut = 0, LockOutDate = NULL
	WHERE LoginName = @LoginName
END
GO
تریگرها: اعمال سیاست‌ها در زمان واقعی

تریگرها کلید اعمال خودکار سیاست‌های EnforcePass هستند. دو تریگر اصلی وجود دارد:

تریگر Logon (trg_Logon_EnforcePass)

این تریگر در سطح سرور (ALL SERVER) فعال می‌شود و ورودهای استاندارد SQL Server را رهگیری می‌کند. این تریگر وظایف زیر را انجام می‌دهد:

  • بررسی می‌کند که آیا کاربر قفل شده است.
  • بررسی می‌کند که آیا رمز عبور منقضی شده است.
  • در صورت نیاز، تلاش‌های ناموفق برای ورود را ثبت می‌کند.

تریگر logon با استفاده از تابع EVENTDATA() اطلاعات مربوط به رویداد ورود را استخراج می‌کند و سپس سیاست‌های قفل حساب و انقضای رمز عبور را بررسی می‌کند. اگر کاربری قفل شده باشد یا رمز عبور او منقضی شده باشد و قادر به تغییر آن نباشد، ورود او با خطا مواجه خواهد شد.

این کد تریگر Logon را نشان می‌دهد:


CREATE TRIGGER [trg_Logon_EnforcePass]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR LOGON
AS
BEGIN
	DECLARE @LoginName sysname = EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname')
	DECLARE @EventType sysname = EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]', 'sysname')

	-- Skip Windows logins or if no policy for this login
	IF SUSER_SNAME() LIKE '%\\%' OR NOT EXISTS (SELECT 1 FROM enforcepass.dbo.PasswordPolicy WHERE LoginName = @LoginName)
	BEGIN
		RETURN
	END

	-- Check if login is locked out
	IF EXISTS (
		SELECT 1 FROM enforcepass.dbo.FailedLogins fl
		JOIN enforcepass.dbo.PasswordPolicy pp ON fl.LoginName = pp.LoginName
		WHERE fl.LoginName = @LoginName AND fl.LockedOut = 1
			AND (pp.LockoutDurationMinutes IS NULL OR fl.LockOutDate >= DATEADD(MINUTE, -pp.LockoutDurationMinutes, GETDATE()))
	)
	BEGIN
		RAISERROR ('Login is currently locked out.', 16, 1)
		ROLLBACK
		RETURN
	END

	-- Check if password has expired
	DECLARE @ExpirationDays int, @LastSetDate datetime, @AllowChangePassword bit
	SELECT @ExpirationDays = ExpirationDays, @LastSetDate = LastSetDate, @AllowChangePassword = AllowChangePassword
	FROM enforcepass.dbo.PasswordPolicy WHERE LoginName = @LoginName

	IF @ExpirationDays IS NOT NULL AND @LastSetDate IS NOT NULL
	BEGIN
		IF @LastSetDate < DATEADD(DAY, -@ExpirationDays, GETDATE())
		BEGIN
			IF @AllowChangePassword = 0
			BEGIN
				RAISERROR ('Password has expired. Please contact your administrator to reset it.', 16, 1)
				ROLLBACK
				RETURN
			END
			ELSE
			BEGIN
				RAISERROR ('Password has expired. Please change it now.', 16, 1)
				-- Allow login but force change password
			END
		END
	END

	-- Reset failed login count on successful login
	EXEC enforcepass.dbo.Login_ResetLockout @LoginName = @LoginName
END
GO

محاسبه انقضای رمز عبور به سادگی با بررسی اینکه تاریخ آخرین تنظیم رمز عبور قبل از تاریخ فعلی منهای تعداد روزهای انقضا است، انجام می‌شود. این منطق به صورت زیر بیان می‌شود:

(@LastSetDate < DATEADD(DAY, -@ExpirationDays, GETDATE()))

اگر این شرط برقرار باشد، رمز عبور منقضی شده تلقی می‌شود.

تریگر Change Password (trg_ChangePassword_EnforcePass)

این تریگر نیز در سطح سرور (ALL SERVER) تعریف شده و هنگامی که یک کاربر رمز عبور خود را تغییر می‌دهد، فعال می‌شود. وظیفه اصلی آن اعتبارسنجی رمز عبور جدید با استفاده از روال Password_Validate و ثبت آن در جدول تاریخچه است.


CREATE TRIGGER [trg_ChangePassword_EnforcePass]
ON ALL SERVER WITH EXECUTE AS 'sa'
FOR ALTER_LOGIN
AS
BEGIN
	DECLARE @LoginName sysname = EVENTDATA().value('(/EVENT_INSTANCE/LoginName)[1]', 'sysname')
	DECLARE @EventType sysname = EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]', 'sysname')
	DECLARE @SQLCommand nvarchar(max) = EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'nvarchar(max)')
	
	IF @SQLCommand LIKE '%PASSWORD =%'
	BEGIN
		DECLARE @Password nvarchar(128)
		-- Extract password from the command for validation (careful with this in production for logging sensitive data)
		-- Example: ALTER LOGIN [TestUser] WITH PASSWORD = 'NewStrongPassword'
		SET @Password = SUBSTRING(@SQLCommand, CHARINDEX('PASSWORD = ''', @SQLCommand) + LEN('PASSWORD = '''), CHARINDEX('''', @SQLCommand, CHARINDEX('PASSWORD = ''', @SQLCommand) + LEN('PASSWORD = ''')) - (CHARINDEX('PASSWORD = ''', @SQLCommand) + LEN('PASSWORD = ''')))

		-- Validate the new password
		EXEC enforcepass.dbo.Password_Validate @LoginName = @LoginName, @Password = @Password

		-- Store password hash in history
		INSERT enforcepass.dbo.PasswordHistory (LoginName, PasswordHash, SetDate)
		VALUES (@LoginName, HASHBYTES('SHA2_512', @Password), GETDATE())

		-- Update last set date
		UPDATE enforcepass.dbo.PasswordPolicy SET LastSetDate = GETDATE() WHERE LoginName = @LoginName
	END
END
GO

این تریگر رمز عبور جدید را از فرمان ALTER LOGIN استخراج می‌کند (با هشدار در مورد مسائل امنیتی در محیط‌های تولیدی). سپس از Password_Validate برای بررسی انطباق با سیاست‌ها استفاده کرده و در صورت موفقیت‌آمیز بودن، هش رمز عبور را به تاریخچه اضافه می‌کند و تاریخ آخرین تنظیم رمز عبور را به روز می‌کند.

نتیجه‌گیری

ابزار EnforcePass یک راهکار جامع و رایگان برای اعمال سیاست‌های پیچیده و سفارشی رمز عبور در SQL Server است. با استفاده از این ابزار، می‌توانید امنیت ورودهای استاندارد SQL Server خود را به طور قابل توجهی افزایش دهید، که برای محیط‌های نیازمند امنیت بالا حیاتی است. این ابزار به مدیران پایگاه داده امکان می‌دهد تا کنترل بیشتری بر روی رمزهای عبور کاربران داشته باشند و از آسیب‌پذیری‌های ناشی از رمزهای عبور ضعیف یا قدیمی جلوگیری کنند. با پیاده‌سازی EnforcePass، نه تنها به الزامات امنیتی می‌رسید، بلکه با ارائه یک چارچوب قوی، از داده‌های حساس خود محافظت می‌کنید.

 

من علی دستجردی‌ام؛ عاشق کار با دیتا، از SQL Server تا بیگ‌دیتا و هوش مصنوعی. دغدغه‌ام کشف ارزش داده‌ها و به‌اشتراک‌گذاری تجربه‌هاست. ✦ رزومه من: alidastjerdi.com ✦

عضویت
منو باخبر کن!!!
guest
نام
ایمیل

0 دیدگاه
Inline Feedbacks
دیدن تمامی کامنتها

فوتر سایت

ورود به سایت

sqlyar

هنوز عضو نیستید؟

ورود به سایت

هنوز تبت نام نکردید ؟