iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Security

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

C - null deference (記憶體損壞:空指標引用)

  • 分享至 

  • xImage
  •  

哭了QQ昨天和朋友出去加上太忙直接忘記要發文,就不能像leetcode一樣有三次贖罪券嗎?

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

C - null deference(記憶體損壞:空指標引用)

  • 形成原因:當原本指向null的指標被取消指向null,會讓指標已為自己原本是指向其他有意義的地址
  • 後果:取消指標值(null)通常會導致程式終止。駭客利用此漏洞可能會導致拒絕服務(DoS)
  • 實例:原本購物網站預設購買數量是1,但使用者送出訂單時將欄位值的數從1改成空值(null),導致網站會崩潰
  • 如何防止:
    • 在使用指標前確認指標不是指向空值
    • 在使用之前初始化所有變數
    • 對外部輸入變數和資料儲存區資料做驗證

第一題

錯誤區塊

 situation2.addTrack(*ownSubmarine.release());
 //程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:釋出後引用指標可能會導致程式崩潰或執行惡意程式。

主要修正方法

將錯誤區塊改成:

 situation2.addTrack(*ownSubmarine.get());
 //程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
使用指標時,如果稍後要使用託管物件,則不建議釋放該物件的所有權。為了獲取託管物件,使用了函式*get()。呼叫此函式後,記憶體管理將遵循 RAII 術語由std::unique_ptr控制,這確保了程式的可靠和安全執行。

第二題

錯誤區塊

auto crosses = pOrder->run( otherBook );
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
解析無效輸入時,std::unique_ptr< OrderT > parse( std::istream & istream ) 返回一個std::unique_ptr,它實際上是nullptr。程式缺少nullptr檢查,並且將空指標引用錯誤。攻擊者可以使用無效輸入來使目標拒絕服務。

主要修正方法

在錯誤區塊前加入檢驗:

if (!pOrder){
    return;
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
程式防禦性地檢查std::unique_ptr是否指向有效記憶體,防止空順差。

第三題

錯誤區塊

std::string const arg(argc > 0 ? argv[1] : "");
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
Argv陣列的第一個元素是正在執行的程式的路徑。 因此,argc總是大於零。在沒有給出引數的情況下,argv[1]通常為NULL,這將導致程式因記憶體訪問無效而終止。

主要修正方法

將錯誤區塊:

std::string const arg(argc > 0 ? argv[1] : "");
list_all_sub_directories(arg.empty() ?
    std::filesystem::current_path() :
    std::filesystem::path(arg));
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

改成:

try
{
    std::unique_ptr<char[]> bad_alloc_mem_fallback(new char[1024]);

    std::filesystem::path const root
    {
      argc > 1 ?
      std::filesystem::path(argv[1]) :
      std::filesystem::current_path()
    };
    list_all_sub_directories(root);
}
catch (std::bad_alloc const& ba)
{
    std::cerr << ba.what() << std::endl;
}
//程式碼片段擷取自 Secure Code Warrior 線上安全程式培訓平台

解釋:
程式正確檢查argc引數,並將主程式包裝在異常處理程式中,以便在掃描非常大的目錄結構時捕捉潛在的記憶體錯誤。


上一篇
C - double free (記憶體損壞:雙重釋放)
下一篇
C - use-after-free (記憶體損壞:釋放後使用)
系列文
你的程式真的安全嗎?從資安的角度做 code review25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言