﻿# 講解 SQL 連線字串中關於 Persist Security Info 參數的用途

可能許多人不知道資料庫連線參數 (Connection String) 中的 Persist Security Info 參數是做什麼用的，且用到的機會也很少，但我們這幾天就遇到了一個跟 Persist Security Info 參數有關的錯誤，特別分享一下處理的經驗。

先從 Visual Studio 的 Server Explorer 講起，請先參考下圖。

當你在新增連線時，可以選擇 \[Save my password\] 選項，如果你有勾選，可以點選 \[Advanced...\] 按鈕查詢透過工具幫你產生的連線字串。

![當你在新增連線時，可以選擇 \[Save my password\] 選項，如果你有勾選，可以點選 \[Advanced...\] 按鈕查詢透過工具幫你產生的連線字串。](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d0932901377b068580b2-image_15.png "當你在新增連線時，可以選擇 [Save my password] 選項，如果你有勾選，可以點選 [Advanced...] 按鈕查詢透過工具幫你產生的連線字串。")

![Add Connection -> Advanced Properties](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/1b353ff66941864775f5-image_12.png "Add Connection -> Advanced Properties")

實際儲存在 web.config 的連線參數大概將會長這樣：

```
Data Source=.;Initial Catalog=master;Persist Security Info=True;User ID=sa;Password=xxxx
```

光透過 Visual Studio 工具上的說明就可大略得知 Persist Security Info 的用途。在預設不加上 Persist Security Info 的情況下，預設為 False，當程式需要進行資料庫連線時，此時會將「敏感資訊」例如：密碼(Password) 等資訊暫存在連線物件中(記憶體裡)，當連線建立成功之後，就會立即將「敏感資訊」清除，這能確保記憶體中的「敏感資訊」會立即清除，降低資訊揭露(Information Leakage)的風險，因為這樣的風險也是出現在 [OWASP Top 10 (2007)](https://github.com/OWASP/Top10/blob/master/2007/OWASP%20Top%2010%202007.pdf) 的第六位 (A6)。

> 精確的來說，連線資訊是在 [SqlConnection](http://msdn.microsoft.com/zh-tw/library/system.data.sqlclient.sqlconnection.aspx) 類別的 [ConnectionString](http://msdn.microsoft.com/zh-tw/library/system.data.sqlclient.sqlconnection.connectionstring.aspx) 屬性或[DbConnection](http://msdn.microsoft.com/zh-tw/library/system.data.common.dbconnection.aspx) 類別的 [ConnectionString](http://msdn.microsoft.com/zh-tw/library/system.data.common.dbconnection.connectionstring.aspx) 屬性中。

當你將 Persist Security Info 宣告為 True 時，即便連線已經建立，也會將密碼儲存在記憶體中，供後續程式引用，而我們就剛好有一支程式需要在程式執行的過程中取得新的連線，需要用到原本的連線參數，所以需要將 Persist Security Info 宣告為 True 才能正常運作。

> 其實也不一定要將Persist Security Info 宣告為 True，因為只要將該程式修改成直接從 web.config 中重新讀取 Connection String 即可。

除此之外，我同事也遇到一個奇怪的事件，就是同一段程式碼在執行時明明有些頁面不會掛掉，有些頁面就會掛掉，不同人看同一頁時，也會有時成功、有時失敗的情況。那是因為 ADO.NET 有 Connection Pool 的概念，在連線數足夠的情況下是不需要重新建立連線的，所以才會有這種類似靈異事件的情況。

我必須要再次聲明，在程式設計的領域沒有什麼「靈異事件」只有因為你不了解技術細節無法理解問題時才會感覺「有鬼」，所以養成追根究底的習慣是很重要的，真理是越辯越明，如果一直讓自己處於一知半解的狀態，慢慢的就會變的越來越「迷信」。

**相關連結**

-   [Securing Connection Strings](http://msdn.microsoft.com/zh-tw/library/89211k9b%28en-us,VS.80%29.aspx)
-   [Protecting Connection Information (ADO.NET)](http://msdn.microsoft.com/en-us/library/89211k9b.aspx)
-   [ConnectionStrings.com - Forgot that connection string? Get it here!](http://www.connectionstrings.com/)
