首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

安全性程式碼審查實戰測驗:10 大經典漏洞挑戰你的安全 IQ

     編輯:關於C#

資安專家透過程式碼審查快速發現漏洞。本文提供 10 個含安全缺陷的程式碼片段(C/C++/C#/Silverlight),測試你的漏洞識別能力,並詳細解析每個錯誤的成因與修正方向。

錯誤 #1:緩衝區溢出(C/C++)


void func(char *s1, char *s2) {
    char d[32];
    strncpy(d, s1, sizeof d - 1);
    strncat(d, s2, sizeof d - 1); // 錯誤:未扣除 strncpy 已用空間
}

解析:strncat 最後參數為剩餘緩衝區大小,但 strncpy 已佔用部分空間,導致溢出。strncpy/strncat 比 strcpy/strcat 更難正確使用。VC++ 2005+ 會發出 C4996/C6053 警告。

錯誤 #2:語境相關的緩衝區溢出(C/C++)


int main(int argc, char* argv[]) {
    char d[32];
    if (argc==2) strcpy(d, argv[1]); // 風險視執行語境而定
}

解析:標準 EXE 非安全性錯誤(攻擊自己);但若為 SYSTEM 權限服務或 Linux setuid root 程式,即成本地提權漏洞。需掌握部署語境才能判斷。

錯誤 #3:密鑰生成回退弱隨機數 + 捕獲所有例外(C#)


byte[] GetKey(UInt32 keySize) {
    byte[] key = null;
    try {
        key = new byte[keySize];
        RNGCryptoServiceProvider.Create().GetBytes(key);
    }
    catch (Exception e) {
        Random r = new Random(); r.NextBytes(key); // 弱隨機數
    }
    return key;
}

解析:(1) 密碼學強隨機數失敗時回退 Random 可預測;(2) catch (Exception) 掩蓋真實錯誤(含緩衝區溢出等嚴重錯誤)。SDL 要求密碼學隨機數且禁止捕獲所有例外。

錯誤 #4:陣列離界寫入(C/C++)


void func(const char *s) {
    if (!s) return;
    char t[3];
    memcpy(t, s, 3);
    t[3] = 0; // 陣列只有 0-2 索引
}

解析:純編碼錯誤,攻擊者無控制權非安全性漏洞。但若索引可控(t[i]=0),即成任意寫入漏洞。/analyze 發出 C6201 警告。

錯誤 #5:唯讀集合被惡意轉型竄改(C#)


private static Monkey[] defaultMonkeys = new[] { new RhesusMonkey() };
private IEnumerable<Monkey> monkeys = null;
public IEnumerable<Monkey> Monkeys {
    get {
        if (monkeys == null) monkeys = MonkeysReady() ? PopulateMonkeys() : defaultMonkeys;
        return monkeys;
    }
}

解析:調用者可將 IEnumerable<Monkey> 轉型為 Monkey[] 修改靜態預設陣列,影響其他實例。解決:快取 ReadOnlyCollection<T> 或真正唯讀儲存。

錯誤 #6:跨站腳本攻擊 (XSS)(ASP.NET)


string lastLogin = Request["LastLogin"]; // 查詢字串優先於 Cookie
if (String.IsNullOrEmpty(lastLogin)) { /* 設定 Cookie */ }
else { Response.Write("Welcome back! " + lastLogin); } // 直接輸出未編碼輸入

解析:Request["key"] 優先讀取 QueryString,攻擊者可注入 ``。需對輸出進行 HTML 編碼。

錯誤 #7:XPath 注入(C#)


XmlNode node = doc.SelectSingleNode("//products/product[id/text()='" + Request["itemId"] + "']/price");

解析:未驗證輸入直接拼接 XPath 查詢,同 SQL 注入原理。需參數化或嚴格驗證輸入。

錯誤 #8:Session ID 可預測 + 伺服器陣列不支援(ASP.NET)


public override string CreateSessionID(HttpContext context) {
    lock (lockObject) {
        Int32? last = (int?)context.Application["LastSessionId"];
        last = (last ?? 0) + 1;
        context.Application["LastSessionId"] = last;
        return last.ToString(); // 連續整數,極易猜測
    }
}

解析:(1) HttpContext.Application 不跨伺服器共享,Web Farm 會產生衝突;(2) 連續整數 Session ID 極易被劫持。應用 GUID 或大範圍隨機字串。

錯誤 #9:登入失敗資訊洩露 + 明文密碼儲存(C#)


if (validPassword == null) { errorMessage = "Invalid user name"; return false; }
else if (validPassword != password) { errorMessage = "Incorrect password"; return false; }

解析:(1) 不同錯誤訊息讓攻擊者枚舉合法帳號;應統一為「帳號或密碼錯誤」。(2) 資料庫存明文密碼,應儲存雜湊值(如 bcrypt/PBKDF2)。

錯誤 #10:Silverlight 客戶端驗證邏輯完全不可信


bool verifyCode(string discountCode) {
    SHA1Managed hash = new SHA1Managed(); // SHA-1 已被 SDL 禁用
    byte[] codeHash = hash.ComputeHash(Encoding.Unicode.GetBytes(discountCode));
    byte[] secretCode = { ... }; // 硬編碼雜湊值
    // 元素比較...
    WebServiceSoapClient client = new WebServiceSoapClient();
    client.ApplyDiscountCode(); // 客戶端直接呼叫特權操作
    return true;
}

解析:(1) 使用已淘汰 SHA-1,應改用 SHA256Managed;(2) 未加鹽雜湊易遭彩虹表破解;(3) 核心錯誤:Silverlight 運行於客戶端瀏覽器,攻擊者可附加偵錯器竄改邏輯、繞過驗證、直接呼叫 Web Service。絕不在客戶端執行特權決策或嵌入機密。

評分參考

分數評語
15+資安專家級
11-14優秀,應用於夥伴程式碼審查
7-10不錯,優於 50% Web 開發者
4-6需加強,建議研讀專業資安書籍
0-3建議暫離編輯器

持續練習程式碼審查,建立安全開發生命週期 (SDL) 思維,是資安防禦最有效的投資。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved