iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Security

你的程式真的安全嗎?從資安的角度做 code review系列 第 15

C - insufficiant validation (業務邏輯:驗證不足)

  • 分享至 

  • xImage
  •  

下方程式碼片段全部都是擷取自 Secure Code Warrior 線上安全程式培訓平台,因為練習互動時的題目多半不會只有單一個檔案,可能涉及多個檔案、資料夾及多處地方修改,因此我的文章主要是針對最主要的區塊做修改及說明,若有不好理解的地方非常抱歉也還請見諒,也可以實際上去 Secure Code Warrior 玩玩看,搭配著互動,會更有感的學習哦~

C - insufficiant validation (業務邏輯:驗證不足)

  • 形成原因:輸入參數驗證不充分,像是使用未記錄或隱藏的輸入值
  • 後果:可能停止服務,或是允許攻擊者存取特權資訊並濫用業務功能。
  • 實例:一個網站可以買東西,但購買數量欄位沒有設定不能輸入負值,攻擊者輸入負值後導致系統損壞,或是網站反而退錢給攻擊者的錢包
  • 解決方法:
    • 驗證每個輸入,並假設所有輸入都是惡意的
    • 使用參數允許清單
    • 將輸入永遠轉換為預期的資料型態

第1題

錯誤區塊

FILE *f = fopen(xaction_file, "rt");
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台
int const year = atoi(strchr(f, '/')+1) + today->tm_year - (today->tm_year % 100);
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
Validate_expiry() 函式中,存在潛在的崩潰風險。如果在 atoi()的呼叫中沒有找到字元 “/”,那麼 strchr 會返回空指標,隨後對這個空指標進行操作會導致程式崩潰。此外,嘗試使用空指標調用 fopen 也會失敗。因此,應該在使用 strchr()fopen() 時加入檢查,以防止空指標引發錯誤。

主要修正方法

爆改一堆,部分擷取,主要是把fopen()函式換掉換成:

validate_transaction_file(xaction_file);
std::ifstream in;
in.exceptions(std::ios_base::badbit);
in.open(xaction_file)
程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

還有

int const month = atoi(f);
int const year = atoi(strchr(f, '/')+1) + today->tm_year - (today->tm_year % 100);

if (year < today->tm_year || (year == today->tm_year && month < today->tm_mon))
{
    return "Credit card expired.";
}
return nullptr;

改成

std::tm datetime = {};
std::istringstream iss(f);
iss >> std::get_time(&datetime, "%m/%Y");
if (iss.fail())
{
    throw invalid_transaction_error("Invalid expiry date format.");
}
if (datetime.tm_year < today->tm_year || (datetime.tm_year == today->tm_year && datetime.tm_mon < today->tm_mon))
{
    throw invalid_transaction_error("Credit card expired.");
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
Field_t 已經替換為 std::string。配合 C++ 流輸入操作,這消除了所有不安全的讀取操作,並且允許更靈活的欄位大小變化。此外,對事務檔案的輸入參數進行了更嚴格的驗證,現在能夠更準確地報告錯誤。透過使用 Luhn 演算法,提升了信用卡號的驗證有效性。同時,系統會始終回報空欄位的情況。遇到某些無效輸入時,程式也不再會崩潰。

第2題

錯誤區塊

ScwService scwService;
scwService.init();
LDAPService ldap( &scwService );
ldap.init();
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
程式執行包括幾個階段:初始化必要的服務,然後執行使用者命令。如果這些步驟中的任何一個在錯誤情況下完成,整個程式的行為可能不符合使用者的預期。如果在任何階段出現無法恢復的錯誤,應用程式必須立即正確退出,透過返回適當的錯誤程式來表明問題。

主要修正方法

將錯誤區塊改成:

ScwService scwService;
if( scwService.init() == false )
{
	return 1;
}

LDAPService ldap( &scwService );
if( ldap.init() == false )
{
	ldap.ping();
	return 2;
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
在程式執行期間,履行應用程式所需的所有執行步驟都會被正確檢查。


上一篇
C - business logic (業務邏輯:邏輯錯誤)
下一篇
C - missing function level access control (存取控制:遺漏功能層級存取控制)
系列文
你的程式真的安全嗎?從資安的角度做 code review18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言