Abp框架Web站點的安全性提升

2023-04-18 15:00:32

本文將從GB/T 22239《資訊保安技術 網路安全等級保護基本要求》規定的安全計算環境中解讀、摘要若干安全要求,結合Abp框架,對站點進行安全升級。

【身份鑑別】應對登入的使用者進行身份標識和鑑別,身份標識具有唯一性,身份鑑別資訊具有複雜度要求並定期更換。

解決方案

  1. 設定密碼最小長度

  2. 密碼由數位、字母和特殊字元組合而成

  3. 設定密碼每隔90天需要更換一次

實施

在AbpSettings表中設定開啟PasswordComplexity密碼複雜度校驗,設定密碼最小長度為7位

設定密碼強制過期策略,參考用Abp實現找回密碼和密碼強制過期策略

【身份鑑別】應具有登入失敗處理功能,應設定並啟用結束對談、限制非法登入次數和當登入連線超時自動退出等相關措施。

解決方案

  1. 登入後無操作15分鐘,系統自動退出登入狀態。

  2. 連續登入失敗5次後,鎖定賬戶15分鐘

實施

在WebCoreModule中,將Jwt Bearer Token的過期時間從預設的1天改為15分鐘

設定使用者登入失敗鎖定
預設將新增使用者的IsLockoutEnabled開啟

public User()
{
    this.IsLockoutEnabled = true;
}

在AbpSettings表中設定開啟使用者登入失敗鎖定,並設定失敗嘗試次數和鎖定時長

【身份鑑別】應採用口令、密碼技術、生物技術等兩種或兩種以上組合的鑑別技術對使用者進行身份鑑別,且其中一種鑑別技術至少應使用密碼技術來實現。

解決方案

採用兩種以上組合的鑑別技術對使用者進行身份鑑別,採用使用者名稱+手機簡訊驗證碼方式登入

實施

對Abp框架改造,加入兩步驗證功能,參考用Abp實現兩步驗證(Two-Factor Authentication,2FA)登入(一):認證模組

【存取控制】應對登入的使用者分配賬戶和許可權;並授予管理使用者所需的最小許可權,實現管理使用者的許可權分離。

解決方案

  1. 刪除或者禁用預設賬戶,

  2. 禁用超級管理員,

  3. 設定獨立的審計管理員、安全管理員等。

實施

更改AbpPermissions,AbpRoles,AbpUserRoles表,合理安排使用者角色的許可權設定。

【入侵防範】應通過設定終端接入方式或網路地址範圍對通過網路進行管理的管理終端進行限制。

解決方案

限制管理員的登入地址範圍,僅允許特定IP進行登入管理。

實施

使用IP白名單限制管理員賬戶登入。

AppSettingNames.cs:

public static class AppSettingNames
{
    ...
    public const string AdminIpAddressWhitelist = "CAH.AdminIpAddressWhitelist";
}

AppSettingProvider.cs:

public class AppSettingProvider : SettingProvider
{
    public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
    {
        return new[]
        {
            ...
            new SettingDefinition(AppSettingNames.AdminIpAddressWhitelist, "127.0.0.1,::1,localhost,0.0.0.0", scopes: SettingScopes.Application | SettingScopes.Tenant | SettingScopes.User, isVisibleToClients: true),
        };
    }
}

在身份驗證終節點方法Authenticate中,新增對管理員賬戶IP白名單的校驗:


var ipAddress = this._logInManager.ClientInfoProvider.ClientIpAddress;
var adminIpAddressWhitelist = await SettingManager.GetSettingValueForTenantAsync(AppSettingNames.AdminIpAddressWhitelist, loginResult.Tenant.Id);
var IpCheckRequired = false;
var roles = await userManager.GetRolesAsync(loginResult.User);
if (roles.Contains(StaticRoleNames.Tenants.Admin) || roles.Contains(StaticRoleNames.Tenants.Super))
{
    IpCheckRequired = true;
}
if (!string.IsNullOrEmpty(adminIpAddressWhitelist))
{
    if (!adminIpAddressWhitelist.Split(',').Contains(ipAddress) && IpCheckRequired)
    {
        throw new UserFriendlyException("IP不在允許的列表中");
    }
}


【入侵防範】應提供資料有效性檢驗功能,保證通過人機介面輸入或通過通訊介面輸入的內容符合系統設定要求。

解決方案

  1. 對上傳介面進行檔案格式限制跳脫處理。
  2. 對系統設定防範XSS跨站指令碼攻擊

實施

檔案系統中設定僅允許業務相關的檔案型別上傳

 "FileStorage": {
    ...
    "AllowOnlyConfiguredFileExtensions": true,
    "FileExtensionsConfiguration": ".jpg,.png",
    }

設定上傳文字中高危指令碼過濾,參考[Asp.Net Core] 網站中的XSS跨站指令碼攻擊和防範

【安全審計】應對審計記錄進行保護,定期備份,避免受到未預期的刪除、修改或覆蓋等

解決方案

審計紀錄檔儲存6個月以上。

實施

對AbpAuditLogs中的資料定期異地備份,儲存時長至少6個月以上。

【資料完整性、保密性】應採用校驗技術或密碼技術保證重要資料在儲存過程中的完整性以及保密性,包括但不限於鑑別資料、重要業務資料、重要審計資料、重要設定資料、重要視訊資料和重要個人資訊等

解決方案

  1. 採用AES加密對身份證號碼等重要資料進行加密後再儲存
  2. 傳輸報文中對敏感資料進行脫敏處理
  3. 頁面中對敏感資料進行脫敏處理

實施

使用加密轉換器對身份證號欄位進行加密儲存,參考在EF Core中為資料表按列加密儲存

modelBuilder.Entity<User>().Property(c => c.IdentificationNumber).HasConversion<EncryptionConverter<string>>();

修改User到UserDto的欄位對映,對手機號,身份證號和郵箱地址進行正則替換。

public UserMapProfile()
{
    CreateMap<UserDto, User>();
    CreateMap<UserDto, User>()
        .ForMember(x => x.Roles, opt => opt.Ignore())
        .ForMember(x => x.CreationTime, opt => opt.Ignore())
        .ForMember(x => x.IdentificationNumber, opt => opt.Ignore())
        .ForMember(x => x.EmailAddress, opt => opt.Ignore())
        .ForMember(x => x.PhoneNumber, opt => opt.Ignore());

    CreateMap<User, UserDto>()
            .ForMember(
                dest => dest.PhoneNumber,
                opt => opt.MapFrom(
                    src => Regex.Replace(src.PhoneNumber, "(\\d{3})\\d{4}(\\d{4})", "$1****$2")))

            .ForMember(
                dest => dest.IdentificationNumber,
                opt => opt.MapFrom(
                    src => Regex.Replace(src.IdentificationNumber, "(?<=\\w{3})\\w(?=\\w{4})", "*")))


            .ForMember(
                dest => dest.EmailAddress,
                opt => opt.MapFrom(
                    src => Regex.Replace(src.EmailAddress, "(^\\w)[^@]*(@.*$)", "$1****$2")));



    CreateMap<CreateUserDto, User>();
    CreateMap<CreateUserDto, User>().ForMember(x => x.Roles, opt => opt.Ignore());
}

頁面中修改更新方式

【資料備份恢復】應提供重要資料的本地資料備份與恢復功能

解決方案

在本地定期備份設定資料、業務資料。根據實際業務需求定期對備份資料進行恢復測試,儲存相關的恢復測試記錄。

實施

專案按照SQL server完全備份指南進行備份作業,

由運維人員定期對業務資料進行異地備份,根據實際業務需求定期對備份資料進行恢復測試,並對恢復測試進行記錄