[食譜好菜] 常在面試出現的題目:SQL Injection

  • 3649
  • 0
  • C#
  • 2016-03-20

「你如何預防 SQL Injection?」這個問題已經成為了一個顯學,現在我們寫程式如果沒有把解決 SQL Injection 的方式變成習慣,我們就絕對是個不及格的程式設計師,一個領域如果夠成熟,那這個領域會累積一定厚度的必學項目,像 SQL Injection 的問題就是累積來的,面試也常常會問。

黑大在 2007 年的時候寫了一篇文章,第一段就是在講 SQL Injection,黑大講得非常清楚,裡面也還有其他 Security 的議題,建議大家可以閱讀這篇文章。

接下來我舉一個例子來說明 SQL Injection 是怎麼發生的,下圖的畫面上有一個輸入框,輸入 Id 就可以取得該 Id 所賦予的角色權限,但是只有 1 這個 Id 是保留的,因為權限最大,所以可以看到當 Id 輸入 1 時,是顯示「拒絕存取」的訊息。

不過當我輸入 '' OR 1=1 這串字串,神奇的事情發生了,我取得了所有的權限,我愛用哪一個權限就用哪一個權限。

這個就是一種 SQL Injection 的攻擊,通常發生的原因都是我們用組字串的方式來組 SQL 的查詢條件。

using (SqlConnection sql = new SqlConnection(connectionString))
{
    sql.Open();

    using (SqlCommand sqlCmd = new SqlCommand())
    {
        sqlCmd.Connection = sql;
        sqlCmd.CommandText =
            @"SELECT *
              FROM Member
              WHERE Id = " + id;

        using (SqlDataReader sqlReader = sqlCmd.ExecuteReader())
        {
            if (sqlReader.HasRows)
            {
                while (sqlReader.Read())
                {
                    ...
                }
            }
        }
    }
}

現在如果還看到有程式設計師這樣在寫 Production Code 的話,應該被抓去關,讓他不要再出來害人。

在 .Net 要防範 SQL Injection 一勞永逸的方法就是使用參數化查詢,將 SQL 查詢條件的值宣告為 SQL 參數,再使用 SqlParameter 將 SQL 查詢條件真正的值塞給指定的參數。

using (SqlConnection sql = new SqlConnection(connectionString))
{
    sql.Open();

    using (SqlCommand sqlCmd = new SqlCommand())
    {
        sqlCmd.Connection = sql;
        sqlCmd.CommandText =
            @"SELECT *
              FROM Member
              WHERE Id = @Id";

        sqlCmd.Parameters.AddWithValue("@Id", id);

        using (SqlDataReader sqlReader = sqlCmd.ExecuteReader())
        {
            if (sqlReader.HasRows)
            {
                while (sqlReader.Read())
                {
                    ...
                }
            }
        }
    }
}

這時候我再輸入 '' OR 1=1 進行 SQL Injection 攻擊,就無效了。

再次提醒大家,SQL Injection 會對資訊安全造成很大的影響,尤其是對於機敏資料會產生非常嚴重的威脅,一定要防範!

相關資源

C# 指南
ASP.NET 教學
ASP.NET MVC 指引
Azure SQL Database 教學
SQL Server 教學
Xamarin.Forms 教學