<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 30, 文章 - 0, 評論 - 9, 引用 - 0
    數(shù)據(jù)加載中……

    構(gòu)建安全的數(shù)據(jù)訪問

    本頁內(nèi)容http://www.microsoft.com/china/technet/security/guidance/secmod87.mspx
    本模塊內(nèi)容 本模塊內(nèi)容
    目標(biāo) 目標(biāo)
    適用范圍 適用范圍
    如何使用本模塊 如何使用本模塊
    威脅與對策 威脅與對策
    設(shè)計(jì)注意事項(xiàng) 設(shè)計(jì)注意事項(xiàng)
    輸入驗(yàn)證 輸入驗(yàn)證
    SQL 注入 SQL 注入
    身份驗(yàn)證 身份驗(yàn)證
    授權(quán) 授權(quán)
    配置管理 配置管理
    敏感數(shù)據(jù) 敏感數(shù)據(jù)
    異常管理 異常管理
    構(gòu)建安全的數(shù)據(jù)訪問組件 構(gòu)建安全的數(shù)據(jù)訪問組件
    代碼訪問安全性注意事項(xiàng) 代碼訪問安全性注意事項(xiàng)
    部署注意事項(xiàng) 部署注意事項(xiàng)
    小結(jié) 小結(jié)
    其他資源 其他資源

    本模塊內(nèi)容

    數(shù)據(jù)訪問是使用幾個(gè)可用的 ADO.NET 數(shù)據(jù)提供程序之一從 ASP.NET Web 應(yīng)用程序訪問數(shù)據(jù)庫的過程。

    此數(shù)據(jù)庫是應(yīng)用程序級攻擊的主要目標(biāo)。應(yīng)用程序級攻擊用于利用數(shù)據(jù)訪問代碼中的漏洞并獲取對數(shù)據(jù)庫未授權(quán)的訪問。如果所有其他攻擊方法都已失效,應(yīng)用程序的前門(即端口 8)將變成攻擊者竊取、操縱和破壞數(shù)據(jù)的可選路徑。

    本模塊說明如何構(gòu)建安全的數(shù)據(jù)訪問代碼,以及如何避免常見的漏洞和缺陷。本模塊提供了一系列對策和防御技術(shù),您可以在自己的數(shù)據(jù)訪問代碼中使用它們來減少與數(shù)據(jù)訪問有關(guān)的主要威脅。

    目標(biāo)

    使用本模塊可以實(shí)現(xiàn):

    ?

    設(shè)計(jì)、構(gòu)建和部署安全的數(shù)據(jù)訪問代碼。

    ?

    使用代碼訪問安全性和基于角色的安全性可以限制未經(jīng)授權(quán)的調(diào)用方或代碼的訪問。

    ?

    安全地驗(yàn)證用戶的身份。

    ?

    防止 SQL 注入攻擊。

    ?

    確保數(shù)據(jù)庫連接字符串的安全。

    ?

    使用加密機(jī)制來保護(hù)存儲(chǔ)在數(shù)據(jù)庫中的數(shù)據(jù)。

    ?

    確保通過網(wǎng)絡(luò)發(fā)送到數(shù)據(jù)庫以及從數(shù)據(jù)庫發(fā)送的數(shù)據(jù)的安全。

    ?

    使用帶有salt 的哈希值將密碼安全地存儲(chǔ)在數(shù)據(jù)庫中。

    ?

    實(shí)現(xiàn)安全的異常處理。

    ?

    了解如何使用代碼訪問安全性,允許中等信任 Web 應(yīng)用程序使用 OLE DB、Oracle 和 ODBC 數(shù)據(jù)提供程序(這些提供程序需要完全信任)。

    ?

    了解應(yīng)使用哪些對策來解決常見的數(shù)據(jù)訪問威脅,包括 SQL 注入、配置數(shù)據(jù)泄露、敏感的應(yīng)用程序數(shù)據(jù)泄露、數(shù)據(jù)庫架構(gòu)和連接詳細(xì)信息的泄露、未授權(quán)的訪問和網(wǎng)絡(luò)竊聽。

    適用范圍

    本模塊適用于下列產(chǎn)品和技術(shù):

    ?

    Microsoft? Windows? 2000 Server 和 Microsoft Windows Server? 2003

    ?

    Microsoft .NET Framework 1.1 和 ASP.NET 1.1

    ?

    Microsoft SQL Server?

    如何使用本模塊

    為了充分理解本模塊內(nèi)容,請先閱讀下列模塊或與本模塊結(jié)合起來閱讀:

    ?

    閱讀模塊 2 威脅與對策這將使您更廣泛深入地了解 Web 應(yīng)用程序所面臨的潛在威脅及其對策。

    ?

    閱讀模塊 4 Web 應(yīng)用程序安全設(shè)計(jì)指南在本模塊中,您將了解構(gòu)建安全解決方案時(shí)所面臨的體系結(jié)構(gòu)和設(shè)計(jì)挑戰(zhàn),以及構(gòu)建準(zhǔn)則。

    ?

    閱讀模塊 18 保證數(shù)據(jù)庫服務(wù)器的安全閱讀模塊 18 可了解如何確保數(shù)據(jù)庫服務(wù)器的安全。

    ?

    閱讀模塊 7 構(gòu)建安全的程序集模塊 7 中構(gòu)建安全程序集和開發(fā)安全托管代碼的準(zhǔn)則和建議同樣應(yīng)該適用于數(shù)據(jù)訪問代碼

    ?

    使用評估模塊。要在產(chǎn)品周期的不同階段檢查數(shù)據(jù)訪問的安全性,請參見下列模塊中的“Web 服務(wù)”部分:模塊 5 安全性體系結(jié)構(gòu)和設(shè)計(jì)審查、模塊 21 代碼審查以及模塊 22 部署審查。

    ?

    使用檢查表。本指南“檢查表”部分中的檢查表:保護(hù)數(shù)據(jù)訪問包括一個(gè)便于參考的檢查表。可以將此基于任務(wù)的檢查表用作本模塊中各個(gè)建議的摘要。

    請注意,在當(dāng)前版本的 .NET Framework (1.1) 中,只有 ADO.NET SQL Server 數(shù)據(jù)訪問提供程序才支持部分信任調(diào)用方,并且可以安全地用在部分信任 Web 應(yīng)用程序中。OLE DB、Oracle 和 ODBC ADO.NET 數(shù)據(jù)提供程序需要完全信任。

    威脅與對策

    要構(gòu)建安全的數(shù)據(jù)訪問代碼,需要了解數(shù)據(jù)訪問代碼中的威脅是什么、常見漏洞是如何產(chǎn)生的以及如何使用適當(dāng)?shù)膶Σ邅斫档惋L(fēng)險(xiǎn)。

    數(shù)據(jù)訪問代碼面臨的主要威脅包括:

    ?

    SQL 注入

    ?

    配置數(shù)據(jù)的泄漏

    ?

    敏感應(yīng)用程序數(shù)據(jù)的泄漏

    ?

    數(shù)據(jù)庫架構(gòu)和連接詳細(xì)信息的泄露

    ?

    未授權(quán)的訪問

    ?

    網(wǎng)絡(luò)竊聽

    圖 14.1 闡明了這些主要威脅。

    數(shù)據(jù)訪問代碼面臨的威脅和攻擊

    圖 14.1
    數(shù)據(jù)訪問代碼面臨的威脅和攻擊

    SQL 注入

    SQL 注入攻擊利用易受攻擊的數(shù)據(jù)訪問代碼,并允許攻擊者在數(shù)據(jù)庫中執(zhí)行任意命令。如果應(yīng)用程序使用數(shù)據(jù)庫中不受限制的帳戶,由于攻擊者可以更自由地執(zhí)行查詢和命令,因此受到的威脅會(huì)更大。

    漏洞

    使數(shù)據(jù)訪問代碼容易受到 SQL 注入攻擊的常見漏洞包括:

    ?

    弱輸入驗(yàn)證

    ?

    在不使用類型安全的參數(shù)時(shí)動(dòng)態(tài)構(gòu)造 SQL 語句

    ?

    使用特權(quán)過高的數(shù)據(jù)庫登錄

    對策

    要應(yīng)對 SQL 注入攻擊,請務(wù)必:

    ?

    限制和凈化輸入數(shù)據(jù)。

    ?

    使用類型安全的 SQL 參數(shù)進(jìn)行數(shù)據(jù)訪問。這些參數(shù)可以與存儲(chǔ)過程一起使用,也可以是動(dòng)態(tài)構(gòu)造的 SQL 命令字符串。參數(shù)執(zhí)行類型和長度檢查,并同時(shí)確保注入數(shù)據(jù)庫中的代碼被視為文本數(shù)據(jù)(而非可執(zhí)行語句)。

    ?

    使用在數(shù)據(jù)庫中具有有限權(quán)限的帳戶。理想情況下,只應(yīng)向數(shù)據(jù)庫中的選定存儲(chǔ)過程授予執(zhí)行權(quán)限,且不提供直接的表格訪問權(quán)限。

    配置數(shù)據(jù)泄露

    數(shù)據(jù)訪問代碼所使用的最敏感的配置數(shù)據(jù)是數(shù)據(jù)庫連接字符串。如果泄漏的連接字符串包括用戶名和密碼,后果將不堪設(shè)想。

    漏洞

    下列漏洞會(huì)增加與泄漏的配置數(shù)據(jù)相關(guān)的安全風(fēng)險(xiǎn):

    ?

    使用 SQL 身份驗(yàn)證,這要求在連接字符串中指定憑據(jù)

    ?

    代碼中嵌入的連接字符串

    ?

    配置文件中的明文連接字符串

    ?

    無法加密連接字符串

    對策

    要防止配置數(shù)據(jù)的泄漏:

    ?

    使用 Windows 身份驗(yàn)證,以便連接字符串中不包含憑據(jù)。

    ?

    加密連接字符串,并限制對已加密數(shù)據(jù)的訪問。

    敏感應(yīng)用程序數(shù)據(jù)的泄漏

    許多應(yīng)用程序都存儲(chǔ)敏感的數(shù)據(jù)(如客戶的信用卡號),一定要保護(hù)此類數(shù)據(jù)的私密性和完整性。

    漏洞

    下列編碼做法可能會(huì)導(dǎo)致泄漏敏感的應(yīng)用程序數(shù)據(jù):

    ?

    存儲(chǔ)沒有加密的數(shù)據(jù)

    ?

    弱授權(quán)

    ?

    弱加密

    對策

    要防止泄漏敏感的應(yīng)用程序數(shù)據(jù):

    ?

    使用強(qiáng)加密機(jī)制來確保數(shù)據(jù)的安全。

    ?

    在執(zhí)行數(shù)據(jù)訪問之前先為每個(gè)調(diào)用方授權(quán),以便用戶只能看到其各自的數(shù)據(jù)。

    數(shù)據(jù)庫架構(gòu)和連接詳細(xì)信息的泄露

    如果您的代碼向客戶端返回異常詳細(xì)信息,惡意用戶可能會(huì)使用這些信息來攻擊服務(wù)器。數(shù)據(jù)訪問代碼中的異常可能會(huì)透露敏感信息,如數(shù)據(jù)庫架構(gòu)詳細(xì)信息、數(shù)據(jù)存儲(chǔ)的特性以及 SQL 代碼片斷。

    漏洞

    下列漏洞可能會(huì)導(dǎo)致信息泄漏:

    ?

    不充分的異常處理

    ?

    薄弱的 ASP.NET 配置(允許未經(jīng)處理的異常詳細(xì)信息返回到客戶端)

    對策

    要防止這種泄漏:

    ?

    捕獲、記錄和處理數(shù)據(jù)訪問代碼中的數(shù)據(jù)訪問異常。

    ?

    向調(diào)用方返回一般的錯(cuò)誤消息。這要求對 Web.config 或 Machine.config 配置文件中的 <customErrors> 元素進(jìn)行適當(dāng)?shù)呐渲谩?/p>

    未授權(quán)的訪問

    在授權(quán)不足的情況下,用戶也許能夠看到另一個(gè)用戶的數(shù)據(jù),并且能夠訪問其他受限制的數(shù)據(jù)。

    漏洞

    下列做法可能會(huì)允許未授權(quán)的訪問:

    ?

    數(shù)據(jù)訪問代碼中缺乏授權(quán),從而提供了不受限制的訪問

    ?

    數(shù)據(jù)庫帳戶的特權(quán)過高

    對策

    要防止未授權(quán)的訪問:

    ?

    按照主體權(quán)限需求為調(diào)用用戶授權(quán)。

    ?

    按照代碼訪問安全權(quán)限需求為調(diào)用代碼授權(quán)。

    ?

    使用受限制的權(quán)限來限制應(yīng)用程序登錄到數(shù)據(jù)庫,并防止直接訪問表格。

    網(wǎng)絡(luò)竊聽

    大多數(shù)應(yīng)用程序的部署體系結(jié)構(gòu)中都包括數(shù)據(jù)訪問代碼與數(shù)據(jù)庫服務(wù)器之間的物理隔離。因此,必須防止竊聽者通過網(wǎng)絡(luò)竊聽敏感數(shù)據(jù)(如應(yīng)用程序特定的數(shù)據(jù)或數(shù)據(jù)庫登錄憑據(jù))。

    漏洞

    下列做法會(huì)增加網(wǎng)絡(luò)竊聽的漏洞:

    ?

    在 SQL 身份驗(yàn)證過程中通過網(wǎng)絡(luò)傳遞的明文憑據(jù)

    ?

    進(jìn)出數(shù)據(jù)庫服務(wù)器的未加密敏感應(yīng)用程序數(shù)據(jù)

    對策

    要限制網(wǎng)絡(luò)竊聽的漏洞:

    ?

    使用 Windows 身份驗(yàn)證來避免通過網(wǎng)絡(luò)發(fā)送憑據(jù)。

    ?

    在數(shù)據(jù)庫服務(wù)器上安裝一個(gè)服務(wù)器證書。這會(huì)導(dǎo)致自動(dòng)加密網(wǎng)絡(luò)上的 SQL 憑據(jù)。

    ?

    在 Web 服務(wù)器和數(shù)據(jù)庫服務(wù)器之間使用 SSL 連接來保護(hù)敏感的應(yīng)用程序數(shù)據(jù)。這需要一個(gè)數(shù)據(jù)庫服務(wù)器證書。

    ?

    在 Web 和數(shù)據(jù)庫服務(wù)器之間使用 IPSec 加密通道。

    設(shè)計(jì)注意事項(xiàng)

    在開始編寫代碼之前,需要在設(shè)計(jì)時(shí)考慮許多重要的問題。主要的注意事項(xiàng)包括:

    ?

    使用 Windows 身份驗(yàn)證。

    ?

    使用最小特權(quán)帳戶。

    ?

    使用存儲(chǔ)過程。

    ?

    保護(hù)所存儲(chǔ)的敏感數(shù)據(jù)。

    ?

    使用單獨(dú)的數(shù)據(jù)訪問程序集。

    使用 Windows 身份驗(yàn)證

    理想情況下,在設(shè)計(jì)中應(yīng)該使用 Windows 身份驗(yàn)證,以增加安全性好處。使用 Windows 身份驗(yàn)證,您不必存儲(chǔ)具有嵌入憑據(jù)的數(shù)據(jù)庫連接字符串,憑據(jù)不通過網(wǎng)絡(luò)傳遞,而且您可以受益于安全帳戶和密碼管理策略。但是,您需要認(rèn)真考慮在使用 Windows 身份驗(yàn)證時(shí),將使用哪個(gè)帳戶連接到 SQL Server。

    有關(guān)詳細(xì)信息,請參閱本模塊后面的身份驗(yàn)證

    使用最小特權(quán)帳戶

    您的應(yīng)用程序應(yīng)該使用在數(shù)據(jù)庫中具有有限權(quán)限的最小特權(quán)帳戶。請確保對應(yīng)用程序的數(shù)據(jù)庫登錄進(jìn)行了適當(dāng)?shù)氖跈?quán)和限制。有關(guān)詳細(xì)信息,請參閱本模塊后面的授權(quán)

    使用最小特權(quán)帳戶可以降低風(fēng)險(xiǎn),并在您的帳戶發(fā)生泄漏或者注入了惡意代碼時(shí)限制潛在的損害。對于 SQL 注入,該命令將在由應(yīng)用程序登錄定義的安全上下文中執(zhí)行,并遵守該登錄在數(shù)據(jù)庫中擁有的相關(guān)權(quán)限。如果您使用特權(quán)過高的帳戶(例如,作為 SQL Server sysadmin 角色的成員)進(jìn)行連接,攻擊者能夠在服務(wù)器上的任何數(shù)據(jù)庫中執(zhí)行任意操作。這包括插入、更新和刪除數(shù)據(jù);刪除表;執(zhí)行操作系統(tǒng)命令。

    要點(diǎn) 不要使用 sa 帳戶或者 SQL Server sysadmin db_owner 角色的任何成員帳戶連接到 SQL Server。

    使用存儲(chǔ)過程

    存儲(chǔ)過程提供性能、維護(hù)和安全性好處。應(yīng)盡可能使用參數(shù)化存儲(chǔ)過程進(jìn)行數(shù)據(jù)訪問。安全性好處包括:

    ?

    可以限制應(yīng)用程序數(shù)據(jù)庫登錄,以便它只具有執(zhí)行指定存儲(chǔ)過程的權(quán)限。沒有必要授予直接的表格訪問權(quán)限。這有助于降低由 SQL 注入攻擊造成的風(fēng)險(xiǎn)。

    ?

    針對傳遞到存儲(chǔ)過程的所有輸入數(shù)據(jù)執(zhí)行長度和類型檢查。同樣,不能將參數(shù)視為可執(zhí)行代碼。這也會(huì)降低 SQL 注入風(fēng)險(xiǎn)。

    如果由于某種原因,您無法使用參數(shù)化存儲(chǔ)過程,但是您需要?jiǎng)討B(tài)構(gòu)造 SQL 語句,請使用類型化參數(shù)和參數(shù)占位符來構(gòu)造這樣的語句,以確保檢查輸入數(shù)據(jù)的長度和類型。

    保護(hù)所存儲(chǔ)的敏感數(shù)據(jù)

    標(biāo)識需要保證私密性和完整性的存儲(chǔ)數(shù)據(jù)。如果您只是為了驗(yàn)證而將密碼存儲(chǔ)到數(shù)據(jù)庫中,請考慮使用單向哈希。如果密碼表發(fā)生泄漏,則不能使用哈希來獲取明文密碼。

    如果您存儲(chǔ)用戶提供的敏感數(shù)據(jù)(如信用卡號),請使用強(qiáng)對稱加密算法(如三重 DES (3DES))來加密數(shù)據(jù)。使用 Win32 數(shù)據(jù)保護(hù) API (DPAPI) 加密 3DES 密鑰,然后將已加密的密鑰存儲(chǔ)在具有受限 ACL 的注冊表項(xiàng)中,只有管理員和應(yīng)用程序進(jìn)程帳戶才能使用該注冊表項(xiàng)。

    為什么不使用 DPAPI?

    盡管建議使用 DPAPI 來加密連接字符串和其他可在計(jì)算機(jī)出現(xiàn)故障時(shí)手動(dòng)恢復(fù)和重新構(gòu)造的機(jī)密(如帳戶憑據(jù)),但仍不太適合存儲(chǔ)信用卡號之類的數(shù)據(jù)。這是由于可恢復(fù)性問題(如果密鑰丟失,則無法恢復(fù)加密數(shù)據(jù))和 Web 場問題。相反,應(yīng)該使用對稱加密算法(如 3DES)并使用 DPAPI 加密密鑰。

    下面概述了造成 DPAPI 不太適合在數(shù)據(jù)庫中存儲(chǔ)敏感數(shù)據(jù)的主要問題:

    ?

    如果 DPAPI 與計(jì)算機(jī)密鑰一起使用,而且您將 CRYPTPROTECT_LOCAL_MACHINE 傳遞到 CryptProtectData CryptUnprotectData 函數(shù),則計(jì)算機(jī)帳戶會(huì)生成加密密鑰。這意味著 Web 場中的每臺服務(wù)器都有一個(gè)不同的密鑰,這會(huì)禁止一臺服務(wù)器訪問由另一臺服務(wù)器加密的數(shù)據(jù)。同樣,如果該 Web 服務(wù)器計(jì)算機(jī)被破壞,則密鑰會(huì)丟失,而且加密的數(shù)據(jù)無法從數(shù)據(jù)庫進(jìn)行恢復(fù)。

    ?

    如果使用計(jì)算機(jī)密鑰方法,則該計(jì)算機(jī)上的任何用戶都可以對數(shù)據(jù)進(jìn)行解密(除非您使用其他加密機(jī)制)。

    ?

    如果您將 DPAPI 與用戶密鑰一起使用,而且您使用的是本地用戶帳戶,就會(huì)為每臺 Web 服務(wù)器上的每個(gè)本地帳戶生成一個(gè)不同的安全標(biāo)識符 (SID) 和一個(gè)不同的密鑰,這會(huì)禁止一臺服務(wù)器訪問由另一臺服務(wù)器加密的數(shù)據(jù)。

    ?

    如果您將 DPAPI 與用戶密鑰一起使用,而且您在 Web 場中的計(jì)算機(jī)之間使用漫游用戶配置文件,則所有數(shù)據(jù)都將共享相同的加密/解密密鑰。但是,如果負(fù)責(zé)漫游用戶配置文件帳戶的域控制器被損害或被破壞,則無法重新創(chuàng)建具有相同 SID 的用戶帳戶,而且不能從數(shù)據(jù)庫中恢復(fù)加密的數(shù)據(jù)。

    另外,對于漫游用戶配置文件,如果某人設(shè)法檢索該數(shù)據(jù),則只要攻擊者能夠在特定的用戶帳戶下運(yùn)行代碼,就可以在網(wǎng)絡(luò)中的任何計(jì)算機(jī)上解密該數(shù)據(jù)。這會(huì)增加潛在攻擊的范圍,因此不建議這樣做。

    使用單獨(dú)的數(shù)據(jù)訪問程序集

    如果您可以進(jìn)行選擇,請避免將數(shù)據(jù)訪問邏輯直接放在 ASP.NET 頁或代碼隱藏文件中。如果將數(shù)據(jù)訪問邏輯放在一個(gè)單獨(dú)的程序集中,并實(shí)現(xiàn)一個(gè)與應(yīng)用程序的業(yè)務(wù)和表示邏輯分開的邏輯數(shù)據(jù)訪問層,就會(huì)帶來安全性、重復(fù)使用和維護(hù)好處。

    從安全的角度看,您可以:

    ?

    對程序集使用強(qiáng)名稱以提供可防篡改功能。

    ?

    使用沙盒技術(shù)來隔離數(shù)據(jù)訪問代碼,如果您的代碼需要支持部分信任調(diào)用方(例如,部分信任 Web 應(yīng)用程序),這一點(diǎn)十分重要。

    ?

    使用那些按照代碼標(biāo)識權(quán)限需求向調(diào)用代碼授權(quán)的數(shù)據(jù)訪問方法和類。

    對于深層防御,請按照業(yè)務(wù)組件中的主體權(quán)限需求來執(zhí)行基于主體的授權(quán),并按照代碼標(biāo)識權(quán)限需求來為調(diào)用數(shù)據(jù)訪問邏輯的代碼授權(quán),如圖 14.2 所示。

    分開表示層、業(yè)務(wù)層和數(shù)據(jù)訪問層

    圖 14.2
    表示層、業(yè)務(wù)層和數(shù)據(jù)訪問層的分離

    有關(guān)數(shù)據(jù)訪問代碼授權(quán)的詳細(xì)信息,請參閱本模塊后面的授權(quán)部分。

    輸入驗(yàn)證

    除了業(yè)務(wù)層需要確保數(shù)據(jù)庫保持?jǐn)?shù)據(jù)的有效性和一致性之外,還必須在將數(shù)據(jù)提交到數(shù)據(jù)庫之前驗(yàn)證數(shù)據(jù),以防 SQL 注入。如果數(shù)據(jù)訪問代碼從當(dāng)前信任邊界內(nèi)部的其他組件接收其輸入內(nèi)容,而且您知道數(shù)據(jù)已經(jīng)過驗(yàn)證(例如,由 ASP.NET 網(wǎng)頁或業(yè)務(wù)組件驗(yàn)證),則數(shù)據(jù)訪問代碼會(huì)忽略廣泛的數(shù)據(jù)驗(yàn)證。但是,請確保在數(shù)據(jù)訪問代碼中使用 SQL 參數(shù),這些參數(shù)驗(yàn)證輸入?yún)?shù)的類型和長度。下一部分將討論 SQL 參數(shù)的用法。

    SQL 注入

    當(dāng)應(yīng)用程序使用輸入內(nèi)容來構(gòu)造動(dòng)態(tài) SQL 語句以訪問數(shù)據(jù)庫時(shí),會(huì)發(fā)生 SQL 注入攻擊。如果代碼使用存儲(chǔ)過程,而這些存儲(chǔ)過程作為包含未篩選的用戶輸入的字符串來傳遞,也會(huì)發(fā)生 SQL 注入攻擊。SQL 注入可能導(dǎo)致攻擊者能夠使用應(yīng)用程序登錄在數(shù)據(jù)庫中執(zhí)行命令。如果應(yīng)用程序使用特權(quán)過高的帳戶連接到數(shù)據(jù)庫,這種問題會(huì)變得很嚴(yán)重。

    注意 傳統(tǒng)的安全措施(如使用 SSL 和 IPSec)不能防止 SQL 注入攻擊。

    防止 SQL 注入

    使用下列對策來防止 SQL 注入攻擊:

    ?

    限制輸入。

    ?

    使用類型安全的 SQL 參數(shù)。

    限制輸入

    驗(yàn)證輸入內(nèi)容的類型、長度、格式和范圍。如果您不希望獲得數(shù)值,則不要接受它們。應(yīng)該考慮輸入內(nèi)容來自何處。如果它來自受信任源,而且您知道已針對該來源執(zhí)行過徹底的輸入驗(yàn)證,則可以選擇在數(shù)據(jù)訪問代碼中忽略數(shù)據(jù)驗(yàn)證。如果數(shù)據(jù)來自不受信任源或者用于深層防御,則數(shù)據(jù)訪問方法和組件應(yīng)該驗(yàn)證輸入。

    使用類型安全的 SQL 參數(shù)

    SQL 中的 Parameters 集合提供類型檢查和長度驗(yàn)證。如果您使用 Parameters 集合,則輸入內(nèi)容將被視為文本值,SQL 不會(huì)將其視為可執(zhí)行代碼。使用 Parameters 集合還有一個(gè)好處,那就是可以強(qiáng)制進(jìn)行類型和長度檢查。超出范圍的值會(huì)觸發(fā)異常。這是深層防御的一個(gè)有力示例。

    要點(diǎn) SSL 不能防止 SQL 注入。對于任何應(yīng)用程序來說,如果它在沒有正確的輸入驗(yàn)證和適當(dāng)?shù)臄?shù)據(jù)訪問技術(shù)的情況下訪問數(shù)據(jù)庫,都很容易受到 SQL 注入攻擊。

    盡可能使用存儲(chǔ)過程,并使用 Parameters 集合來調(diào)用它們。

    結(jié)合使用 Parameters 集合和存儲(chǔ)過程

    下面的代碼片斷闡釋了 Parameters 集合的用法:

    SqlDataAdapter myCommand = new SqlDataAdapter("AuthorLogin", conn);
    myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
    SqlParameter parm = myCommand.SelectCommand.Parameters.Add(
    "@au_id", SqlDbType.VarChar, 11);
    parm.Value = Login.Text;
    

    在本例中,@au_id 參數(shù)被視為文本值,而非可執(zhí)行代碼。另外,還針對參數(shù)進(jìn)行了類型和長度檢查。在上例中,輸入值不能長于 11 個(gè)字符。如果數(shù)據(jù)不遵循由參數(shù)定義的類型或長度,就會(huì)生成異常。

    請注意,使用存儲(chǔ)過程不一定會(huì)防止 SQL 注入。重要的是結(jié)合使用參數(shù)和存儲(chǔ)過程。如果不使用參數(shù),則在存儲(chǔ)過程使用未篩選的輸入內(nèi)容時(shí),它們很容易受到 SQL 注入攻擊。例如,下面的代碼片斷很容易受到攻擊:

    SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure '" + 
    Login.Text + "'", conn);
    

    要點(diǎn) 如果使用存儲(chǔ)過程,請確保同時(shí)使用參數(shù)。

    結(jié)合使用 Parameters 集合和動(dòng)態(tài) SQL

    如果您不能使用存儲(chǔ)過程,仍可以使用參數(shù),如下面的代碼片斷所示:

    SqlDataAdapter myCommand = new SqlDataAdapter(
    "SELECT au_lname, au_fname FROM Authors WHERE au_id = @au_id", conn);
    SqlParameter parm = myCommand.SelectCommand.Parameters.Add("@au_id", 
    SqlDbType.VarChar, 11);
    parm.Value = Login.Text;
    

    使用參數(shù)批處理

    通常會(huì)產(chǎn)生如下誤解:如果將幾個(gè) SQL 語句連接在一起,以便在單個(gè)往返中向服務(wù)器發(fā)送一批語句,則不能使用參數(shù)。但是,如果您能確保參數(shù)名不重復(fù),則可以使用這種技術(shù)。通過在 SQL 文本連接過程中,向每個(gè)參數(shù)名中添加一個(gè)數(shù)字或其他某個(gè)唯一值,可以方便地執(zhí)行此操作。

    使用篩選例程

    用來防止 SQL 注入攻擊的另一種方法是開發(fā)篩選例程,以便向具有特殊 SQL 含義的字符添加轉(zhuǎn)義符,如單撇號字符。下面的代碼片斷闡釋了一個(gè)用來添加轉(zhuǎn)義符的篩選例程:

    private string SafeSqlLiteral(string inputSQL)
    {
    return inputSQL.Replace("'", "''");
    }
    

    這種例程存在著一定的問題,而且您不應(yīng)完全依賴它們,因?yàn)楣粽呖梢允褂?ASCII 十六進(jìn)制字符來回避檢查。但是應(yīng)該篩選輸入內(nèi)容,并將其作為深層防御策略的一部分。

    注意 不要依賴篩選輸入。

    使用 LIKE 子句

    請注意,如果您使用 LIKE 子句,通配符仍需要轉(zhuǎn)義符。下面的代碼片斷闡釋了這種技術(shù):

    s = s.Replace("[", "[[]");
    s = s.Replace("%", "[%]");
    s = s.Replace("_", "[_]");
    

    身份驗(yàn)證

    當(dāng)應(yīng)用程序連接到 SQL Server 數(shù)據(jù)庫時(shí),可以在 Windows 身份驗(yàn)證或 SQL 身份驗(yàn)證之間進(jìn)行選擇。Windows 身份驗(yàn)證更安全。如果必須使用 SQL 身份驗(yàn)證(可能由于必須使用許多不同的帳戶連接到數(shù)據(jù)庫,并且希望避免調(diào)用 LogonUser),請執(zhí)行其他幾個(gè)步驟,以盡可能降低額外的風(fēng)險(xiǎn)。

    注意 如果使用 LogonUser 創(chuàng)建模擬令牌,需要在 Microsoft Windows 2000 上具有功能強(qiáng)大的“作為操作系統(tǒng)的一部分工作”特權(quán),因此應(yīng)避免使用此方法。

    考慮下面的建議:

    ?

    使用 Windows 身份驗(yàn)證。

    ?

    保護(hù) SQL 身份驗(yàn)證的憑據(jù)。

    ?

    使用最小特權(quán)帳戶進(jìn)行連接。

    使用 Windows 身份驗(yàn)證

    Windows 身份驗(yàn)證不通過網(wǎng)絡(luò)發(fā)送憑據(jù)。如果對 Web 應(yīng)用程序使用 Windows 身份驗(yàn)證,請盡可能使用服務(wù)帳戶或進(jìn)程帳戶(如 ASPNET 帳戶)連接到數(shù)據(jù)庫。Windows 和 SQL Server 都必須能夠識別您在數(shù)據(jù)庫服務(wù)器上使用的帳戶。該帳戶必須被授予 SQL Server 登錄權(quán)限,而且需要具有與訪問數(shù)據(jù)庫相關(guān)的登錄權(quán)限。

    在使用 Windows 身份驗(yàn)證時(shí),必須使用受信任連接。下面的代碼片斷顯示了幾個(gè)使用 Windows 身份驗(yàn)證的典型的連接字符串。

    下例使用面向 SQL Server 的 ADO.NET 數(shù)據(jù)提供程序:

    SqlConnection pubsConn = new SqlConnection(
    "server=dbserver; database=pubs; Integrated Security=SSPI;");
    

    下例使用面向 OLE DB 數(shù)據(jù)源的 ADO.NET 數(shù)據(jù)提供程序:

    OleDbConnection pubsConn = new OleDbConnection(
    "Provider=SQLOLEDB; Data Source=dbserver; Integrated Security=SSPI;" +
    "Initial Catalog=northwind");
    

    保護(hù) SQL 身份驗(yàn)證的憑據(jù)

    如果必須使用 SQL 身份驗(yàn)證,請確保憑據(jù)不以明文形式通過網(wǎng)絡(luò)發(fā)送,并確保加密包含憑據(jù)的數(shù)據(jù)庫連接字符串。

    要使 SQL Server 能夠自動(dòng)加密通過網(wǎng)絡(luò)發(fā)送的憑據(jù),請?jiān)跀?shù)據(jù)庫服務(wù)器上安裝服務(wù)器證書。也可以在 Web 服務(wù)器和數(shù)據(jù)庫服務(wù)器之間使用 IPSec 加密通道,來確保進(jìn)出數(shù)據(jù)庫服務(wù)器的所有通信的安全。要確保連接字符串的安全,請使用 DPAPI。有關(guān)詳細(xì)信息,請參閱本模塊后面配置管理部分中的“確保連接字符串的安全”。

    使用最小特權(quán)帳戶進(jìn)行連接

    應(yīng)用程序應(yīng)該通過使用最小特權(quán)帳戶連接到數(shù)據(jù)庫。如果您使用 Windows 身份驗(yàn)證進(jìn)行連接,則從操作系統(tǒng)的角度看,Windows 帳戶應(yīng)該是最小特權(quán)帳戶,而且該帳戶應(yīng)該具有有限的特權(quán)和對 Windows 資源的有限的訪問能力。另外,無論您使用 Windows 身份驗(yàn)證還是 SQL 身份驗(yàn)證,相應(yīng)的 SQL Server 登錄都應(yīng)該受到數(shù)據(jù)庫中的權(quán)限的限制。

    有關(guān)如何創(chuàng)建最小特權(quán)數(shù)據(jù)庫帳戶以及使用 Windows 身份驗(yàn)證將 ASP.NET Web 應(yīng)用程序連接到遠(yuǎn)程數(shù)據(jù)庫的選項(xiàng)的詳細(xì)信息,請參閱模塊 19 確保 ASP.NET 應(yīng)用程序和 Web 服務(wù)的安全中的“數(shù)據(jù)訪問”。

    授權(quán)

    如果用戶能夠檢索和操縱特定的數(shù)據(jù),就會(huì)建立授權(quán)過程。有兩種方法:數(shù)據(jù)訪問代碼可以使用授權(quán)來確定是否執(zhí)行請求的操作,數(shù)據(jù)庫可以通過執(zhí)行授權(quán)來限制應(yīng)用程序所使用的 SQL 登錄的功能。

    在授權(quán)不足的情況下,用戶也許能夠看到另一個(gè)用戶的數(shù)據(jù),未授權(quán)的用戶也許能夠訪問受限制的數(shù)據(jù)。要去除這些威脅:

    ?

    限制未授權(quán)的調(diào)用方。

    ?

    限制未授權(quán)的代碼。

    ?

    限制數(shù)據(jù)庫中的應(yīng)用程序。

    圖 14.3 概述了應(yīng)該使用的授權(quán)點(diǎn)和技術(shù)。

    數(shù)據(jù)訪問授權(quán)、程序集和數(shù)據(jù)庫

    圖 14.3
    數(shù)據(jù)訪問授權(quán)、程序集和數(shù)據(jù)庫

    注意數(shù)據(jù)訪問代碼如何按照權(quán)限需求為調(diào)用用戶或調(diào)用代碼授權(quán)。代碼標(biāo)識需求是 .NET 代碼訪問安全性的一個(gè)特性。

    要為數(shù)據(jù)庫中的應(yīng)用程序授權(quán),請使用只具有執(zhí)行選定存儲(chǔ)過程權(quán)限的最小特權(quán) SQL 服務(wù)器登錄。除非有特殊理由,否則不應(yīng)為應(yīng)用程序授予如下權(quán)限:直接針對任何表執(zhí)行創(chuàng)建、檢索、更新、破壞/刪除 (CRUD) 操作。

    注意 存儲(chǔ)過程在數(shù)據(jù)庫系統(tǒng)的安全上下文中運(yùn)行。盡管您可以通過為應(yīng)用程序分配對特定存儲(chǔ)過程的權(quán)限來限制它的邏輯操作,但不能限制存儲(chǔ)過程所執(zhí)行的操作的結(jié)果。存儲(chǔ)過程是受信任代碼。必須使用數(shù)據(jù)庫權(quán)限來確保存儲(chǔ)過程的接口安全。

    限制未授權(quán)的調(diào)用方

    您的代碼在連接到數(shù)據(jù)庫之前必須基于角色或標(biāo)識為用戶授權(quán)。角色檢查通常用在應(yīng)用程序的業(yè)務(wù)邏輯中,但是,如果您不能清楚地區(qū)分業(yè)務(wù)邏輯和數(shù)據(jù)訪問邏輯,請對數(shù)據(jù)庫訪問方法使用主體權(quán)限需求。

    以下屬性確保只有作為 Manager 角色成員的用戶才能調(diào)用 DisplayCustomerInfo 方法:

    [PrincipalPermissionAttribute(SecurityAction.Demand, Role="Manager")]
    public void DisplayCustomerInfo(int CustId)
    {
    }
    

    如果需要其他授權(quán)粒度,并且需要在數(shù)據(jù)訪問方法內(nèi)部執(zhí)行基于角色的邏輯,請使用命令性主體權(quán)限需求或顯式的角色檢查,如下面的代碼片斷所示:

    using System.Security;
    using System.Security.Permissions;
    
    public void DisplayCustomerInfo(int CustId)
    {
    try
      {
    // 用來驗(yàn)證調(diào)用方是 manager 的命令性主體權(quán)限
    // 角色檢查
    PrincipalPermission principalPerm = new PrincipalPermission(
    null, "Manager");
    // 僅在調(diào)用方是“Manager”角色的成員時(shí)才執(zhí)行
    // 隨后的代碼
      }
    catch( SecurityException ex )
      {
       . . .
      }
    }
    

    下面的代碼片斷使用顯式的程序設(shè)計(jì)角色檢查來確保調(diào)用方是 Manager 角色的成員:

    public void DisplayCustomerInfo(int CustId)
    {
    if(!Thread.CurrentPrincipal.IsInRole("Manager"))
      {
        . . .
      }
    }
    

    限制未授權(quán)的代碼

    通過使用 .NET Framework 代碼訪問安全性(特別是代碼標(biāo)識需求),可以限制能夠訪問數(shù)據(jù)訪問類和方法的程序集。

    例如,如果您只希望由公司或特定開發(fā)組織編寫的代碼能夠使用您的數(shù)據(jù)訪問組件,請使用 StrongNameIdentityPermission ,并要求調(diào)用程序集具有一個(gè)帶有指定公鑰的強(qiáng)名稱,如下面的代碼片斷所示:

    using System.Security.Permissions;
    . . .
    [StrongNameIdentityPermission(SecurityAction.LinkDemand, 
    PublicKey="002...4c6")]
    public void GetCustomerInfo(int CustId)
    {
    }
    

    要提取給定程序集的公鑰的文本表示形式,請使用下面的命令:

    sn -Tp assembly.dll
    

    注意 –Tp 開關(guān)中使用大寫的“T”。

    因?yàn)?Web 應(yīng)用程序的程序集是動(dòng)態(tài)編譯的,所以對于這些程序集不能使用強(qiáng)名稱。這使得很難將數(shù)據(jù)訪問程序集的使用限制在特定的 Web 應(yīng)用程序上。最佳方法是開發(fā)一個(gè)自定義權(quán)限,并要求該權(quán)限來自數(shù)據(jù)訪問組件。完全信任 Web 應(yīng)用程序(或任何完全受信任代碼)可以調(diào)用您的組件。但是,部分信任代碼只有在被授予了自定義權(quán)限之后,才能調(diào)用您的數(shù)據(jù)訪問組件。

    有關(guān)自定義權(quán)限的示例實(shí)現(xiàn),請參閱本指南“如何”部分中的如何:創(chuàng)建自定義加密權(quán)限。

    限制數(shù)據(jù)庫中的應(yīng)用程序

    首選方法是為應(yīng)用程序用來連接到數(shù)據(jù)庫的 Windows 帳戶創(chuàng)建一個(gè) SQL Server 登錄權(quán)限,然后將 SQL Server 登錄映射到數(shù)據(jù)庫中的某個(gè)數(shù)據(jù)庫用戶。將該數(shù)據(jù)庫用戶放在用戶定義的數(shù)據(jù)庫角色中,并授予該角色相應(yīng)的權(quán)限。理想情況下,應(yīng)該只為該角色授予對應(yīng)用程序所使用的存儲(chǔ)過程的執(zhí)行訪問權(quán)限。

    有關(guān)如何配置此方法的詳細(xì)信息,請參閱模塊 19 確保 ASP.NET 應(yīng)用程序和 Web 服務(wù)的安全中的“為 ASP.NET 應(yīng)用程序配置數(shù)據(jù)訪問權(quán)限”。

    配置管理

    數(shù)據(jù)庫連接字符串是針對數(shù)據(jù)訪問代碼主要考慮的配置管理問題。應(yīng)認(rèn)真考慮這些字符串的存儲(chǔ)位置以及如何保護(hù)它們(特別是當(dāng)它們包括憑據(jù)時(shí))。要提高加密管理安全性:

    ?

    使用 Windows 身份驗(yàn)證。

    ?

    確保連接字符串的安全。

    ?

    使用受限制的 ACL 確保 UDL 文件的安全。

    使用 Window 身份驗(yàn)證

    使用 Windows 身份驗(yàn)證時(shí),系統(tǒng)會(huì)為您管理憑據(jù),而且憑據(jù)不會(huì)通過網(wǎng)絡(luò)傳輸。還可以避免將用戶名和密碼嵌入到連接字符串中。

    確保連接字符串的安全

    如果您需要使用 SQL 身份驗(yàn)證,連接字符串中將包含用戶名和密碼。如果攻擊者利用 Web 服務(wù)器上的源代碼泄漏這一漏洞或設(shè)法登錄到該服務(wù)器,則攻擊者可以檢索連接字符串。同樣,能夠合法登錄到該服務(wù)器的任何用戶都可以查看它們。使用加密機(jī)制確保連接字符串的安全。

    加密連接字符串

    使用 DPAPI 加密連接字符串。使用 DPAPI 加密時(shí),由于加密密鑰由平臺進(jìn)行管理,并且綁定到特定的計(jì)算機(jī)或 Windows 用戶帳戶,因此可避免出現(xiàn)加密密鑰管理問題。要使用 DPAPI,必須通過 P/Invoke 調(diào)用 Win32 DPAPI 函數(shù)。

    有關(guān)如何構(gòu)建托管包裝類的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的“How To: Create a DPAPI Library”,其網(wǎng)址為:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/secnetlpMSDN.asp(英文)。

    安全地存儲(chǔ)加密的連接字符串

    加密的連接字符串可以放在注冊表中,也可以放在 Web.config 或 Machine.config 文件中。如果您使用 HKEY_LOCAL_MACHINE 下的注冊表項(xiàng),請將下面的 ACL 應(yīng)用于該項(xiàng):

    管理員:完全控制
    進(jìn)程帳戶:讀取
    

    注意 該進(jìn)程帳戶由運(yùn)行數(shù)據(jù)訪問程序集的進(jìn)程來確定。這通常是 ASP.NET 進(jìn)程,或者當(dāng)您的解決方案使用企業(yè)服務(wù)中間層時(shí),該進(jìn)程是企業(yè)服務(wù)服務(wù)器進(jìn)程。

    還可以考慮使用 HKEY_CURRENT_USER,該注冊表項(xiàng)提供受限制的訪問。有關(guān)詳細(xì)信息,請參閱模塊 7 構(gòu)建安全的程序集中的“注冊表”部分。

    注意 如果您使用 Microsoft Visual Studio? .NET 數(shù)據(jù)庫連接向?qū)ВB接字符串將以明文屬性值形式存儲(chǔ)在 Web 應(yīng)用程序代碼隱藏文件或 Web.config 文件中。這兩種方法都應(yīng)該避免使用。

    為了更容易部署,您可能希望將加密的字符串存儲(chǔ)在 Web.config 中,盡管這可能不如使用受限制的注冊表項(xiàng)安全。在本例中,將使用如下所示的自定義 <appSettings> 名稱-值對:

    <configuration>
    <appSettings>  
    <add key="connectionString" value="AQA..bIE=" />
    </appSettings>
    <system.web>
       ...
    </system.web>
    </configuration>
    

    要從 <appSettings> 元素訪問密碼文本,請使用如下所示的 ConfigurationSettings 類:

    using System.Configuration;
    private static string GetConnectionString()
    {
    return ConfigurationSettings.AppSettings["connectionString"];
    }

    不要將 Persist Security Info 設(shè)置為“True”或“Yes”

    如果在連接字符串中包括 Persist Security Info 屬性,將導(dǎo)致 ConnectionString 屬性在密碼返回給用戶之前,將密碼從連接字符串中去除。在建立與數(shù)據(jù)庫的連接之后,默認(rèn)設(shè)置 false(等同于忽略 Persist Security Info 屬性)會(huì)丟棄該信息。

    使用受限制的 ACL 確保 UDL 文件的安全

    如果您的應(yīng)用程序結(jié)合使用外部通用數(shù)據(jù)鏈接 (UDL) 文件和面向 OLE DB 的 ADO.NET 托管數(shù)據(jù)提供程序,請使用 NTFS 權(quán)限來限制訪問。使用以下受限制的 ACL:

    管理員:完全控制
    進(jìn)程帳戶:讀取
    

    注意 UDL 文件未進(jìn)行加密。一個(gè)更安全的方法是,使用 DPAPI 加密連接字符串,并將其存儲(chǔ)在受限制的注冊表項(xiàng)中。

    敏感數(shù)據(jù)

    許多 Web 應(yīng)用程序都在數(shù)據(jù)庫中以某種形式存儲(chǔ)敏感數(shù)據(jù)。如果攻擊者設(shè)法針對您的數(shù)據(jù)庫執(zhí)行查詢,則務(wù)必要適當(dāng)?shù)丶用芩忻舾袛?shù)據(jù)項(xiàng)(如信用卡號)。

    ?

    加密需要存儲(chǔ)的敏感數(shù)據(jù)。

    ?

    確保網(wǎng)絡(luò)上敏感數(shù)據(jù)的安全。

    ?

    使用帶有salt 的哈希值存儲(chǔ)密碼。

    加密需要存儲(chǔ)的敏感數(shù)據(jù)

    盡可能避免存儲(chǔ)敏感數(shù)據(jù)。如果必須存儲(chǔ)敏感數(shù)據(jù),請對其進(jìn)行加密。

    使用 3DES 加密

    要將敏感數(shù)據(jù)(如信用卡號)存儲(chǔ)在數(shù)據(jù)庫中,請使用強(qiáng)對稱加密算法,如 3DES。

    ?

    在開發(fā)過程中,要啟用 3DES 加密

    1.

    使用 RNGCryptoServiceProvider 類來生成強(qiáng)(192 位,24 字節(jié))加密密鑰。

    2.

    備份加密密鑰,并將備份副本存儲(chǔ)在物理安全的位置。

    3.

    使用 DPAPI 對密鑰進(jìn)行加密,并將其存儲(chǔ)在注冊表項(xiàng)中。使用下面的 ACL 來確保注冊表項(xiàng)的安全:

    管理員:完全控制
    進(jìn)程帳戶(例如,ASPNET):讀取
    ?

    在運(yùn)行時(shí),要將加密數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中

    1.

    獲取要加密的數(shù)據(jù)。

    2.

    從注冊表中檢索經(jīng)過加密的加密密鑰。

    3.

    使用 DPAPI 對加密密鑰進(jìn)行解密。

    4.

    結(jié)合使用 TripleDESCryptoServiceProvider 類和加密密鑰來加密數(shù)據(jù)。

    5.

    將加密數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中。

    ?

    在運(yùn)行時(shí),要對加密的機(jī)密進(jìn)行解密

    1.

    從數(shù)據(jù)庫中檢索加密數(shù)據(jù)。

    2.

    從注冊表中檢索經(jīng)過加密的加密密鑰。

    3.

    使用 DPAPI 對加密密鑰進(jìn)行解密。

    4.

    使用 TripleDESCryptoServiceProvider 類對加密數(shù)據(jù)進(jìn)行解密。

    在此過程中,如果用來對加密密鑰進(jìn)行加密的 DPAPI 帳戶被損壞,則可以從備份位置檢索 3DES 密鑰的備份,并在新帳戶下使用 DPAPI 對該備份進(jìn)行加密。新的加密密鑰可以存儲(chǔ)在注冊表中,數(shù)據(jù)庫中的數(shù)據(jù)仍可以進(jìn)行解密。

    有關(guān)創(chuàng)建托管 DPAPI 庫的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”中“How To”部分中的“How To: Create a DPAPI Library”,其網(wǎng)址為:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/secnetlpMSDN.asp(英文)。

    保護(hù)網(wǎng)絡(luò)上敏感數(shù)據(jù)的安全

    通過網(wǎng)絡(luò)傳入和傳出數(shù)據(jù)庫服務(wù)器的敏感數(shù)據(jù)可能包括應(yīng)用程序特定的數(shù)據(jù)或數(shù)據(jù)庫登錄憑據(jù)。為了確保網(wǎng)絡(luò)上的數(shù)據(jù)的私密性和完整性,可以使用平臺級解決方案(如由安全數(shù)據(jù)中心提供的解決方案,在這種解決方案中,在服務(wù)器之間使用 IPSec 加密的通信通道),也可以對您的應(yīng)用程序進(jìn)行配置,以便與數(shù)據(jù)庫建立 SSL 連接。后一種方法需要在數(shù)據(jù)庫服務(wù)器上安裝服務(wù)器證書。

    有關(guān)使用 SSL 和 IPSec 的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的“How To: Use IPSec to Provide Secure Communication Between Two Servers”和“How To:Use SSL to Secure Communication to SQL Server 2000”,其網(wǎng)址為:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/secnetlpMSDN.asp(英文)

    使用帶有salt 的哈希值存儲(chǔ)密碼

    如果您需要實(shí)現(xiàn)一個(gè)包含用戶名和密碼的用戶存儲(chǔ),請不要以明文或加密格式來存儲(chǔ)密碼。存儲(chǔ)增加了 salt 的不可逆哈希值(而不是存儲(chǔ)密碼)可以降低詞典攻擊的風(fēng)險(xiǎn)。

    注意 salt 值是密碼形式的強(qiáng)隨機(jī)數(shù)字。

    創(chuàng)建 Salt 值

    下面的代碼顯示了如何通過使用隨機(jī)數(shù)字生成功能(此功能由 System.Security.Cryptography 命名空間中的 RNGCryptoServiceProvider 類提供)來生成 salt 值。

    public static string CreateSalt(int size)
    {
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] buff = new byte[size];
    rng.GetBytes(buff);
    return Convert.ToBase64String(buff);
    }

    創(chuàng)建 Hash 值(帶有 Salt)

    下面的代碼片斷顯示了如何從所提供的密碼和 salt 值生成哈希值。

    public static string CreatePasswordHash(string pwd, string salt)
    {
    string saltAndPwd = string.Concat(pwd, salt);
    string hashedPwd = 
    FormsAuthentication.HashPasswordForStoringInConfigFile(
    saltAndPwd, "SHA1");
    return hashedPwd;
    }
    

    詳細(xì)信息

    有關(guān)實(shí)現(xiàn)用戶存儲(chǔ)(使用帶有salt 的哈希值存儲(chǔ)密碼)的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的“How To: Use Forms Authentication with SQL Server 2000”,其網(wǎng)址為:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/secnetlpMSDN.asp(英文)。

    異常管理

    異常條件可能會(huì)由配置錯(cuò)誤、代碼中的錯(cuò)誤或惡意輸入引起。如果沒有正確的異常管理,這些條件可能會(huì)透露有關(guān)數(shù)據(jù)源位置和特性的敏感信息,以及有價(jià)值的連接詳細(xì)信息。下面的建議適用于數(shù)據(jù)訪問代碼:

    ?

    捕獲和記錄 ADO.NET 異常。

    ?

    確保數(shù)據(jù)庫連接總是處于斷開狀態(tài)。

    ?

    在 ASP.NET 應(yīng)用程序中使用一般錯(cuò)誤頁面。

    捕獲和記錄 ADO.NET 異常

    將數(shù)據(jù)訪問代碼放在 try/catch 塊中并處理異常。在編寫 ADO.NET 數(shù)據(jù)訪問代碼時(shí),由 ADO.NET 生成的異常類型取決于數(shù)據(jù)提供程序。例如:

    ?

    SQL Server .NET Framework 數(shù)據(jù)提供程序生成 SqlException

    ?

    OLE DB .NET Framework 數(shù)據(jù)提供程序生成 OleDbException

    ?

    ODBC .NET Framework 數(shù)據(jù)提供程序生成 OdbcException

    捕獲異常

    下面的代碼使用 SQL Server .NET Framework 數(shù)據(jù)提供程序,并顯示應(yīng)該如何捕獲類型為 SqlException 的異常。

    try
    {
    // 數(shù)據(jù)訪問代碼
    }
    catch (SqlException sqlex) // 比較具體
    {
    }
    catch (Exception ex) // 比較一般
    {
    }

    記錄異常

    還應(yīng)該記錄來自 SqlException 類的詳細(xì)信息。此類公開那些包含異常條件詳細(xì)信息的屬性。這些屬性包括 Message 屬性(用來描述錯(cuò)誤)、Number 屬性(用來唯一標(biāo)識錯(cuò)誤類型)以及 State 屬性(其中包含其他信息)。State 屬性通常用來指示特定錯(cuò)誤條件出現(xiàn)的具體位置。例如,如果某個(gè)存儲(chǔ)過程從多個(gè)行中生成同一錯(cuò)誤,則 State 屬性可以指出錯(cuò)誤出現(xiàn)的具體位置。最后,Errors 集合中包含 SqlError 對象,這些對象提供詳細(xì)的 SQL 服務(wù)器錯(cuò)誤信息。

    下面的代碼片斷顯示了如何通過使用 SQL Server .NET Framework 數(shù)據(jù)提供程序來處理 SQL Server 錯(cuò)誤條件:

    using System.Data;
    using System.Data.SqlClient;
    using System.Diagnostics;
    
    // 由數(shù)據(jù)訪問層 (DAL) 組件公開的方法
    public string GetProductName( int ProductID )
    {
    SqlConnection conn = new SqlConnection(
    "server=(local);Integrated Security=SSPI;database=products");
    // 將所有的數(shù)據(jù)訪問代碼包含在 try 塊中
    try
      {
    conn.Open();
    SqlCommand cmd = new SqlCommand("LookupProductName", conn );
    cmd.CommandType = CommandType.StoredProcedure;
    
    cmd.Parameters.Add("@ProductID", ProductID );
    SqlParameter paramPN = 
    cmd.Parameters.Add("@ProductName", SqlDbType.VarChar, 40 );
    paramPN.Direction = ParameterDirection.Output;
    
    cmd.ExecuteNonQuery();
    // 在該方法返回之前先執(zhí)行 finally 代碼
    return paramPN.Value.ToString();  
      }
    catch (SqlException sqlex)
      {
    // 處理數(shù)據(jù)訪問異常條件
    // 記錄具體的異常詳細(xì)信息
    LogException(sqlex);
    // 將當(dāng)前異常包裝在一個(gè)相關(guān)性更強(qiáng)的
    // 外部異常中,并重新引發(fā)新異常
    throw new Exception(
    "Failed to retrieve product details for product ID: " + 
    ProductID.ToString(), sqlex );
      }
    finally
      {
    conn.Close(); // 確保連接處于斷開狀態(tài)
      }
    }
    
    // Helper 例程,該例程將 SqlException 詳細(xì)信息記錄到
    // 應(yīng)用程序事件日志中
    private void LogException( SqlException sqlex )
    {
    EventLog el = new EventLog();
    el.Source = "CustomAppLog";
    string strMessage;
    strMessage = "Exception Number :" + sqlex.Number + 
    "(" + sqlex.Message + ") has occurred";
    el.WriteEntry( strMessage );
    
    foreach (SqlError sqle in sqlex.Errors)
      {
    strMessage = "Message:" + sqle.Message +
    " Number:" + sqle.Number +
    " Procedure:" + sqle.Procedure +
    " Server:" + sqle.Server +
    " Source:" + sqle.Source +
    " State:" + sqle.State +
    " Severity:" + sqle.Class +
    " LineNumber:" + sqle.LineNumber;
    el.WriteEntry( strMessage );
      }
    }

    確保數(shù)據(jù)庫連接總是處于斷開狀態(tài)

    如果發(fā)生異常,一定要斷開數(shù)據(jù)庫連接,并釋放其他所有受限制的資源。使用 finally 塊或 C# using 語句,可以確保無論是否發(fā)生了異常條件,都會(huì)斷開數(shù)據(jù)庫連接。上面的代碼闡釋了 finally 塊的用法。還可以按如下方式使用 C# using 語句:

    using ((SqlConnection conn = new SqlConnection(connString)))
    {
    conn.Open();
    // 在以下情況下將斷開連接:生成異常或者控制流
    // 通常會(huì)離開 using 語句的使用范圍
    }

    在 ASP.NET 應(yīng)用程序中使用一般錯(cuò)誤頁面

    如果您的數(shù)據(jù)訪問代碼由 ASP.NET Web 應(yīng)用程序或 Web 服務(wù)調(diào)用,則應(yīng)該對 <customErrors> 元素進(jìn)行配置,以防異常詳細(xì)信息傳播回到最終用戶。還可以通過使用該元素來指定一般錯(cuò)誤頁面,如下所示。

    <customErrors mode="On" defaultRedirect="YourErrorPage.htm" />
    

    對于生產(chǎn)服務(wù)器設(shè)置 mode="On"。只有在發(fā)布之前開發(fā)和測試軟件時(shí)才使用 mode="Off"。如果不這樣做,將導(dǎo)致向最終用戶返回大量錯(cuò)誤信息(如圖 14.4 中顯示的信息)。這些信息可能包含數(shù)據(jù)庫服務(wù)器的名稱、數(shù)據(jù)庫名稱和連接憑據(jù)。

    詳細(xì)的異常信息會(huì)透露敏感數(shù)據(jù)

    圖 14.4
    詳細(xì)的異常信息會(huì)透露敏感數(shù)據(jù)

    圖 14.4 還顯示了數(shù)據(jù)訪問代碼中接近導(dǎo)致異常的行的大量漏洞。特別是:

    ?

    連接字符串是硬編碼的。

    ?

    特權(quán)極高的 sa 帳戶用于連接到數(shù)據(jù)庫。

    ?

    sa 帳戶有一個(gè)弱密碼。

    ?

    SQL 命令的構(gòu)造容易受到 SQL 注入攻擊;輸入內(nèi)容未進(jìn)行驗(yàn)證,代碼不使用參數(shù)化存儲(chǔ)過程。

    構(gòu)建安全的數(shù)據(jù)訪問組件

    下面的代碼顯示了 CheckProductStockLevel 方法(用來在產(chǎn)品數(shù)據(jù)庫中查詢庫存量)的示例實(shí)現(xiàn),該代碼闡釋了本模塊前面介紹的數(shù)據(jù)訪問代碼的許多重要安全功能。

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text.RegularExpressions;
    using System.Collections.Specialized;
    using Microsoft.Win32;
    using DataProtection;
    
    public static int CheckProductStockLevel(string productCode)
    {
    int quantity = 0;
    // (1) 由 try/catch 塊保護(hù)的代碼
    try
      {
    // (2) 使用正則表達(dá)式驗(yàn)證的輸入內(nèi)容
    //     應(yīng)該從資源程序集中檢索錯(cuò)誤消息,以幫助實(shí)現(xiàn)
    //     本地化。為簡短起見,省略了 Localization(本地化)代碼。
    if (Regex.IsMatch(productCode, "^[A-Za-z0-9]{12}$") == false)
    throw new ArgumentException("Invalid product code" );
    //(3) using 語句確保連接被斷開
    using (SqlConnection conn = new SqlConnection(GetConnectionString()))
        {
    // (4) 使用參數(shù)化存儲(chǔ)過程可以應(yīng)對
    //     SQL 注入攻擊
    SqlCommand cmd = new SqlCommand("spCheckProduct", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    
    // 對參數(shù)的類型進(jìn)行檢查
    SqlParameter parm = 
    cmd.Parameters.Add("@ProductCode", 
    SqlDbType.VarChar,12);
    parm.Value = productCode;
    // 定義輸出參數(shù)
    SqlParameter retparm = cmd.Parameters.Add("@quantity", SqlDbType.Int);
    retparm.Direction = ParameterDirection.Output;
    conn.Open();
    cmd.ExecuteNonQuery();
    quantity = (int)retparm.Value;
        }
      }
    catch (SqlException sqlex)
      {
    // (5) 記錄完整的異常詳細(xì)信息。一般(安全的)錯(cuò)誤消息
    //     基于 SQL 錯(cuò)誤代碼返回調(diào)用方
    //     為清楚起見,省略了日志和錯(cuò)誤標(biāo)識代碼
    throw new Exception("Error Processing Request");
      }
    catch (Exception ex)
      {
    // 記錄完整的異常詳細(xì)信息
    throw new Exception("Error Processing Request");
      }
    return quantity;
    }
    
    // (6) 將加密的數(shù)據(jù)庫連接字符串存保留在注冊表中
    private static string GetConnectionString()
    {
    // 從注冊表中檢索密碼文本;進(jìn)程帳戶必須
    // 由注冊表項(xiàng)的 ACL 授予“讀取”訪問權(quán)限
    string encryptedString = (string)Registry.LocalMachine.OpenSubKey(
    @"Software\OrderProcessing\")
    .GetValue("ConnectionString");
    // 使用托管的 DPAPI helper 庫對該字符串進(jìn)行解密
    DataProtector dp = new DataProtector(DataProtector.Store.USE_MACHINE_STORE);
    byte[] dataToDecrypt = Convert.FromBase64String(encryptedString);
    return Encoding.ASCII.GetString(dp.Decrypt(dataToDecrypt,null));
    }
    

    上面的代碼顯示出下列安全特征(由注釋行中的數(shù)字進(jìn)行標(biāo)識)。

    1.

    數(shù)據(jù)訪問代碼放在 try/catch 塊中。這是防止在出現(xiàn)異常時(shí)將系統(tǒng)級信息返回到調(diào)用方所必需的。調(diào)用 ASP.NET Web 應(yīng)用程序或 Web 服務(wù)會(huì)處理異常,并向客戶端返回適當(dāng)?shù)囊话沐e(cuò)誤消息,但是數(shù)據(jù)訪問代碼不依賴這些消息。

    2.

    使用正則表達(dá)式驗(yàn)證輸入。檢查所提供的產(chǎn)品 ID,以便驗(yàn)證它只包含 A–Z 和 0–9 范圍內(nèi)的字符,而且不超過 12 個(gè)字符。這是旨在防止 SQL 注入攻擊的一組對策中的第一個(gè)。

    3.

    SqlConnection 對象是在 Microsoft Visual C#? using 語句的內(nèi)部創(chuàng)建的。這可確保無論是否發(fā)生了異常,都斷開方法內(nèi)部的連接。這會(huì)降低拒絕服務(wù)攻擊的威脅,該威脅嘗試使用到數(shù)據(jù)庫的所有可用連接。通過使用 finally 塊可以實(shí)現(xiàn)類似的功能。

    4.

    參數(shù)化存儲(chǔ)過程用于數(shù)據(jù)訪問。這是防止 SQL 注入的另一個(gè)對策。

    5.

    不向客戶端返回詳細(xì)的錯(cuò)誤信息。記錄異常詳細(xì)信息,以便幫助診斷問題。

    6.

    加密的數(shù)據(jù)庫連接字符串存儲(chǔ)在注冊表中。存儲(chǔ)數(shù)據(jù)庫連接字符串最安全的方法之一是,使用 DPAPI 加密該字符串,并將加密的密碼文本存儲(chǔ)在具有受限 ACL 的受保護(hù)的注冊表項(xiàng)中。(例如,使用“管理員:完全控制”和“ASP.NET 或企業(yè)服務(wù)進(jìn)程帳戶:讀取”,具體情況取決于由哪個(gè)進(jìn)程托管該組件。)

    注意 該代碼顯示了如何從注冊表檢索連接字符串,然后使用托管的 DPAPI helper 庫對其進(jìn)行解密。此庫在“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的 How To: Create a DPAPI Library (英文)中提供。

    代碼訪問安全性注意事項(xiàng)

    所有的數(shù)據(jù)訪問都遵循代碼訪問安全權(quán)限需求。您所選擇的 ADO.NET 托管數(shù)據(jù)提供程序可以確定精確的要求。下表顯示了對于每個(gè) ADO.NET 數(shù)據(jù)提供程序必須授予數(shù)據(jù)訪問程序集的權(quán)限。

    表 14.1:ADO.NET 數(shù)據(jù)提供程序所需的代碼訪問安全權(quán)限

    ADO.NET 數(shù)據(jù)提供程序 所需的代碼訪問安全權(quán)限

    SQL Server

    SqlClient
    PermissionSupports 部分信任調(diào)用方(包括中等信任 Web 應(yīng)用程序)。

    OLE DB

    OleDbPermission*

    Oracle

    OraclePermission*

    ODBC

    OdbcPermission*

    *撰寫本文時(shí),在 1.0 和 1.1 版本的 .NET Framework上,OLE DB、Oracle 和 ODBC 提供程序只支持完全信任調(diào)用方。要從部分信任 Web 應(yīng)用程序中使用這些提供程序,必須將您的數(shù)據(jù)訪問代碼放在沙盒中,這需要一個(gè)專門的數(shù)據(jù)訪問程序集。有關(guān)顯示如何將數(shù)據(jù)訪問代碼放在沙盒中以及如何從中等信任 Web 應(yīng)用程序中使用 OLE DB 數(shù)據(jù)提供程序的示例,請參閱模塊 9 ASP.NET 代碼訪問安全性。

    如果您使用 ADO.NET SQL Server 數(shù)據(jù)提供程序,您的代碼就必須由代碼訪問安全策略授予 SqlClientPermission。完全和中等信任 Web 應(yīng)用程序具有此權(quán)限。

    代碼能否連接到 SQL Server 由代碼是否被授予了 SqlClientPermission 來確定。還可以使用權(quán)限對數(shù)據(jù)庫連接字符串的使用進(jìn)行限制。例如,可以強(qiáng)制應(yīng)用程序使用集成安全性,或者可以確保在使用 SQL Server 安全性時(shí)不接受空白密碼。如果違反通過 SqlClientPermission 指定的規(guī)則,將會(huì)導(dǎo)致運(yùn)行時(shí)安全異常。

    有關(guān)如何使用 SqlClientPermission 來限制數(shù)據(jù)訪問的詳細(xì)信息,請參閱模塊 8 代碼訪問安全的實(shí)踐中的“數(shù)據(jù)訪問”。

    部署注意事項(xiàng)

    以安全方式設(shè)計(jì)和開發(fā)的數(shù)據(jù)訪問組件如果不以安全的方式進(jìn)行部署,仍然容易受到攻擊。常見的部署做法是使數(shù)據(jù)訪問代碼和數(shù)據(jù)庫駐留在單獨(dú)的服務(wù)器上。這些服務(wù)器通常由內(nèi)部防火墻隔開,這就引進(jìn)了額外的部署注意事項(xiàng)。開發(fā)人員和管理員應(yīng)該了解下列問題:

    ?

    防火墻限制

    ?

    連接字符串管理

    ?

    登錄帳戶配置

    ?

    登錄審核

    ?

    網(wǎng)絡(luò)上的數(shù)據(jù)私密性和完整性

    防火墻限制

    如果您通過防火墻連接到 SQL Server,請配置防火墻、客戶端和服務(wù)器。可通過使用 SQL Server 客戶端網(wǎng)絡(luò)實(shí)用程序來配置客戶端,并使用服務(wù)器網(wǎng)絡(luò)實(shí)用程序配置數(shù)據(jù)庫服務(wù)器。在默認(rèn)情況下,SQL Server 偵聽 TCP 端口 1433,但您可以更改此設(shè)置。必須在防火墻上打開所選端口。

    根據(jù)您所選擇的 SQL Server 身份驗(yàn)證模式以及應(yīng)用程序?qū)Ψ植际绞聞?wù)的使用方式,您可能需要在防火墻上打開幾個(gè)其他端口:

    ?

    如果應(yīng)用程序使用 Windows 身份驗(yàn)證連接到 SQL Server,則必須打開支持 Kerberos 或 NTLM 身份驗(yàn)證所必需的端口。

    對于不使用 Active Directory 的網(wǎng)絡(luò),TCP 端口 139 通常是 Windows 身份驗(yàn)證所必需的。有關(guān)端口要求的詳細(xì)信息,請參閱 TechNet 文章“TCP and UDP Port Assignments”和“Security Considerations for Administrative Authority”,前者的網(wǎng)址為:http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/tcpip/part4/tcpappc.asp(英文),后者的網(wǎng)址為:http://www.microsoft.com/technet/security/bestprac/bpent/sec2/seconaa.asp(英文)

    ?

    如果您的應(yīng)用程序使用分布式事務(wù)(例如,自動(dòng)化 COM+ 事務(wù)),您可能還需要對防火墻進(jìn)行配置,以便允許 DTC 通信在單獨(dú)的 DTC 實(shí)例之間以及 DTC 和資源管理器(如 SQL Server)之間流動(dòng)。

    有關(guān)完整配置的詳細(xì)信息,請參閱模塊 18 保證數(shù)據(jù)庫服務(wù)器的安全中的“端口”部分。

    連接字符串管理

    許多應(yīng)用程序都將連接字符串存儲(chǔ)在代碼中,這主要是為了提高性能。但是,性能優(yōu)勢是可以忽略的,而且使用文件系統(tǒng)緩存有助于確保外部文件中的連接字符串能夠提供相當(dāng)?shù)男阅堋J褂猛獠课募鎯?chǔ)連接字符串對于系統(tǒng)管理極其有益。

    為了增加安全性,建議使用 DPAPI 來加密連接字符串。如果您的連接字符串包含用戶名和密碼,這一點(diǎn)尤為重要。然后,確定在何處存儲(chǔ)加密的字符串。注冊表是安全的存儲(chǔ)位置,特別是在您使用 HKEY_CURRENT_USER 時(shí),因?yàn)橹挥性谙嚓P(guān)用戶帳戶下運(yùn)行的進(jìn)程才能進(jìn)行訪問。為了使部署更加容易,還可以將加密的字符串存儲(chǔ)在 Web.config 文件中。這兩種方法已在本模塊前面的配置管理部分討論過。

    登錄帳戶配置

    一定要讓您的應(yīng)用程序使用最小特權(quán)帳戶來連接到數(shù)據(jù)庫,這是降低 SQL 注入攻擊威脅的主要方法之一。

    作為開發(fā)人員,您必須與數(shù)據(jù)庫管理員進(jìn)行協(xié)商,以確定應(yīng)用程序登錄需要訪問的確切的存儲(chǔ)過程和(可能的)表。在理想情況下,您應(yīng)該只允許應(yīng)用程序登錄對隨應(yīng)用程序一起部署的一組有限的存儲(chǔ)過程具有執(zhí)行權(quán)限。

    應(yīng)該對 SQL 或 Windows 帳戶、或應(yīng)用程序連接到數(shù)據(jù)庫所使用的帳戶使用強(qiáng)密碼。

    有關(guān)針對數(shù)據(jù)庫中的應(yīng)用程序帳戶的建議授權(quán)策略,請參閱本模塊前面的授權(quán)部分。

    登錄審核

    應(yīng)該將 SQL Server 配置為記錄失敗的登錄嘗試和可能成功的登錄嘗試。審核失敗的登錄嘗試有助于檢測到嘗試發(fā)現(xiàn)帳戶密碼的攻擊者。

    有關(guān)如何配置 SQL Server 審核的詳細(xì)信息,請參閱模塊 18 保證數(shù)據(jù)庫服務(wù)器的安全。

    網(wǎng)絡(luò)上的數(shù)據(jù)私密性和完整性

    如果您使用 SQL 身份驗(yàn)證連接到 SQL Server,請確保不通過網(wǎng)絡(luò)暴露登錄憑據(jù)。可以在數(shù)據(jù)庫服務(wù)器上安裝一個(gè)證書(這會(huì)導(dǎo)致 SQL Server 加密憑據(jù)),或者使用數(shù)據(jù)庫的 IPSec 加密通道。

    建議使用數(shù)據(jù)庫的 IPSec 或 SSL 通道來保護(hù)傳入和傳出數(shù)據(jù)庫的敏感的應(yīng)用程序級數(shù)據(jù)。有關(guān)詳細(xì)信息,請參閱模塊 18 保證數(shù)據(jù)庫服務(wù)器的安全。

    小結(jié)

    本模塊顯示了數(shù)據(jù)訪問代碼的幾種主要威脅,并重點(diǎn)介紹了常見的漏洞。SQL 注入是應(yīng)該注意的主要威脅之一。除非您使用本模塊中討論的正確對策,否則攻擊者會(huì)利用您的數(shù)據(jù)訪問代碼在數(shù)據(jù)庫中運(yùn)行任意命令。傳統(tǒng)的安全措施(如防火墻和 SSL)對 SQL 注入攻擊不提供任何防御功能。您應(yīng)該徹底驗(yàn)證自己的輸入內(nèi)容,并將參數(shù)化存儲(chǔ)過程用作最基本的防御措施。

    其他資源

    有關(guān)詳細(xì)信息,請參閱下列資源:

    ?

    有關(guān)可打印的檢查表,請參閱本指南“檢查表”部分中的檢查表:保護(hù)數(shù)據(jù)訪問。

    ?

    有關(guān)保護(hù)開發(fā)人員工作站的詳細(xì)信息,請參閱本指南“如何”部分中的如何:保護(hù)開發(fā)人員工作站。

    ?

    有關(guān)結(jié)合使用 SSL 和 SQL Server 的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的“How To: Use SSL to Secure Communication with SQL Server 2000”,其網(wǎng)址為:http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHT19.asp(英文)。

    ?

    有關(guān)使用 IPSec 的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的“How To: Use IPSec to Provide Secure Communication Between Two Servers”,其網(wǎng)址為:http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHT18.asp(英文)。

    ?

    有關(guān)使用 DPAPI 的詳細(xì)信息,請參閱“Microsoft patterns & practices Volume I, Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication”的“How To”部分中的“How To: Create a DPAPI Library”,其網(wǎng)址為:http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHT07.asp(英文)。


    posted on 2006-11-17 15:08 風(fēng)雨兼程 閱讀(429) 評論(0)  編輯  收藏 所屬分類: Asp.net

    主站蜘蛛池模板: 国产99久久久久久免费看| 精品亚洲一区二区三区在线观看| 国产亚洲综合成人91精品 | 亚洲图片中文字幕| 最近免费中文字幕mv电影| 亚洲今日精彩视频| 91精品视频在线免费观看| 亚洲毛片基地日韩毛片基地| 麻豆国产精品免费视频| 亚洲xxxx视频| 国产免费观看黄AV片| 春意影院午夜爽爽爽免费| 丝袜熟女国偷自产中文字幕亚洲| 成人性做爰aaa片免费看| 综合自拍亚洲综合图不卡区| av无码久久久久不卡免费网站 | 黄色免费网站在线看| 日韩亚洲国产综合久久久| 国产99久久久国产精免费| 亚洲国产高清在线| 99re热免费精品视频观看| 国产精品亚洲AV三区| 国产精品亚洲不卡一区二区三区| 精品免费tv久久久久久久| 亚洲国产日韩在线成人蜜芽 | 免费无码不卡视频在线观看| 深夜a级毛片免费无码| 国产av无码专区亚洲av桃花庵| 日韩人妻无码精品久久免费一| 亚洲伊人久久大香线蕉AV| 久久久久久久亚洲精品| 91香蕉国产线在线观看免费| 亚洲欧美日韩国产精品一区| 国产亚洲情侣一区二区无| 1024免费福利永久观看网站| 伊人久久国产免费观看视频| 亚洲男人都懂得羞羞网站| 四虎影在线永久免费观看| 久久精品一区二区免费看| 亚洲AV成人片无码网站| 久久亚洲私人国产精品vA|