Software Security Issues

  • 許多漏洞是由不良的程式設計實務所造成的
  • 程式中對資料與錯誤代碼缺乏足夠的檢查/驗證,會導致各種後果
    • Unvalidated input
    • Cross-site scripting
    • Buffer overflow
    • Injection flaws
    • Improper error handling
  • 分類:
    • 元件之間的不安全互動
      • SQL injection, cross-site scripting, open redirect
    • 危險的資源管理
      • classical buffer overflow, path traversal, download of code without integrity check
    • 脆弱的防禦機制
      • missing authentication for critical function, authorization, or encryption of sensitive data

Software Security: Software Quality/Reliability?

  • Software Quality and Reliability
    • 關注程式的意外失敗
    • 重點不只是 bug 數量,而是它多常被觸發
    • 改善方式: 透過結構化設計與測試找出並消除 bug
  • Software Security
    • 攻擊者會專門尋找可被利用的 bug
    • 透過與正常情況完全不同的輸入來觸發
    • 不容易被一般測試方法發現

Defensive or Secure Programming

  • 在設計與實作軟體時,讓系統即使遭受攻擊仍能持續運作的過程
    • 能偵測因攻擊造成的錯誤狀況
    • 安全地繼續執行,或優雅地失敗 (fail gracefully)
  • Key rule: 永遠不要假設任何事情
    • 檢查所有假設,並處理所有可能的錯誤狀態

  • 一般程式設計師:
    • 注意力放在如何成功完成功能
      • 只關注程式正常執行流程
      • 但不會考慮所有可能失敗點
    • 常常對輸入與環境做假設
  • Defensive Programming
    • 程式必須驗證所有假設
    • 所有可能失敗都要安全且優雅地處理
    • 會增加程式碼與開發時間: Conflicts with business pressures
    • Requiring a changed mindset to traditional programming practices (改變傳統程式設計思維)

Handling Program Input

  • 錯誤的輸入處理是最常見的失敗原因之一
  • 輸入是任何來自外部、且其值並非程式設計師明確知道的資料來源
  • 必須辨識所有輸入資料來源
  • 在使用前,必須明確驗證對資料大小與型別的假設
  • 兩個主要關注點: sizeinterpretation (解讀方式)

Input Size & Buffer Overflow

  • 程式設計師常常會假設輸入的最大長度
    • 沒有確認配置的 buffer 大小是否足夠
    • 可能導致 buffer overflows
  • 測試可能無法發現這種漏洞
    • 測試輸入通常不會大到足以觸發 overflow
  • 安全程式設計實務: 使用安全的字串與 buffer 複製函式
  • Safe coding regards any input as dangerous
    • 以不讓程式暴露於危險中的方式處理輸入

Interpretation of Program Input

  • 程式輸入可能是 binary 或 textual
    • binary: 取決於 encoding,而且通常是 app-specific 的
  • 若未進行驗證,可能導致可被利用的漏洞
  • 越來越多不同的 character sets 被使用 (ex: ASCII)
    • 必須小心辨識目前使用的是哪一個 set,以及實際讀取到的是哪些字元

Injection Attacks

  • 當程式輸入資料可能意外地/故意地影響程式的執行流程時
    • 最常見的情況: 輸入資料被當作參數傳遞給另一個輔助程式
    • 常發生於使用 scripting languages (腳本語言) 時
      • ex: perl、PHP、python
  • 應對方法: 驗證輸入只包含英文字母與數字

Cross-site Scripting (XSS) Attacks

  • 某位使用者提供給程式的輸入,之後被輸出給另一位使用者
    • script code 可能需要存取與其他頁面相關的資料
    • 假設: 來自同一網站的所有內容都同樣可信,因此被允許與該網站的其他內容互動
    • 攻擊會利用這個假設,並試圖繞過瀏覽器的安全檢查
  • 最常見於使用腳本的 Web 應用程式
    • 涉及將 script code 包含在 Web 頁面的 HTML 內容中,並由使用者的瀏覽器顯示
    • ex: JavaScript, ActiveX, VBScript, Flash
  • 變種: XSS Reflection
    • 考慮 guestbook (留言板) 程式的廣泛使用
    • 允許存取網站的使用者留下留言,而這些留言之後會被其他使用者查看
    • 預防方式: 任何由使用者提供的輸入都應該被檢查

Validating Input Syntax

  • 在後續使用資料之前,必須確保資料符合對該資料所做的任何假設
  • 輸入資料應該與真正想要的內容進行比較
    • 只接受 valid input → whitelisting
  • 將輸入資料與已知危險值進行比較
    • blacklisting
  • 只接受已知安全的資料,可以讓程式更有可能維持安全
    • 使用 regular expressions

Validating Numeric Input

  • 數值在內部是以固定大小儲存的
    • 8, 16, 32, 64-bit integers
    • floating point numbers 取決於所使用的處理器
      • 32, 64, 96 bits
    • Values may be signed or unsigned
  • 必須正確解讀 text form 的數值
    • 在比較 signed 與 unsigned 時會有問題
    • 輸入作為 unsigned 時,可能被當成 signed value
    • 可能被用來 thwart (繞過) buffer overflow 檢查
      • input size (unsigned): s=1xxxxxxx
      • 被當成 signed: 負數 < max buffer size 通過檢查

Input Fuzzing

  • 一種軟體測試技術: 使用隨機產生的資料作為程式輸入
  • 以非常低的成本產生大量測試
  • 輸入可以是完全隨機產生的,或者依照某些模板隨機產生
    • 使用模板:
      • 優點: 提高找到漏洞的機率
      • 缺點: 對輸入做出了假設;可能會遺漏某些問題
    • 為了完整性,需要結合兩種方法
  • 概念上非常簡單,但通常只能識別較簡單類型的錯誤
    • 可能遺漏在極少數特定輸入值下才會被觸發的漏洞

Writing Safe Program Code

Key issues:

  • 正確的演算法實作: 正確解決指定的問題
  • 將演算法正確地轉換成機器指令
  • 合法且正確地操作資料

Correct Algorithm Implementation

  • 未正確實作問題的所有情況或變體
    • 對程式輸入的不當解讀或處理

  1. 早期 Netscape Web 瀏覽器中的漏洞
    • 隨機數產生器: 用於產生 session keys
    • 假設: 這些數字應該是不可預測的
    • Bug: seed 選擇不佳導致相對容易被預測
    • Fix: 重新實作隨機數產生器
  2. TCP Session Spoof/Hijack Attack
    • 欺騙伺服器接受 spoofed source address 的封包
    • Bug: initial sequence numbers 可預測
      • Sequence number: 封包的識別與驗證資訊
    • Hijack attack: 猜測 Sequence number,構造適當的 ACK 封包並送給伺服器
    • Hijack variant
      • 等待某個已授權的外部使用者連線並登入伺服器
      • 猜測正在使用的 sequence number,並 inject 具有偽造資訊的封包
    • DoS attack: 觸發伺服器送出 RST 封包,以終止該連線
    • Fix: truly randomized 產生初始 sequence numbers
  3. 程式設計師在程式中加入額外程式碼,以協助 test and debug
    • 不適當地向程式使用者釋出資訊
    • 允許使用者繞過安全檢查
    • Morris Internet Worm 利用 sendmail mail delivery program 中 DEBUG 指令的漏洞
  4. 中高階語言的 interpreter (直譯器)
    • 未能充分反映語言語意: 造成漏洞
    • 早期 JVM 實作中的問題: 對遠端程式碼的安全檢查
      • 允許攻擊者遠端注入程式碼,並欺騙 JVM 直譯器將其視為本地來源的程式碼

Correct Machine Instructions for Algorithm

  • 大多數程式設計師通常會忽略這個問題
    • 假設: 編譯器或直譯器會產生或執行能正確實作語言敘述的程式碼
  • 惡意的編譯器開發者: 在編譯器中加入指令,使其產生額外的程式碼
  • 對策: 仔細比較機器碼與原始碼
    • 緩慢且困難

Correct Data Interpretation

  • 電腦中的所有資料都是以 groups of binary bits 儲存
    • 這些資料會被解讀為: character, integer, floating-point number?
  • 不同程式語言對於限制與驗證資料 interpretation 的能力有所不同
    • Strong typing (強型別): 限制較多,但也較安全
    • 對資料採取較寬鬆的解讀方式: 允許程式碼明確地改變資料的解讀方式
      • ex: C 語言
      • 對系統層級程式設計具有顯著好處
      • 可能造成許多錯誤
  • 正確使用記憶體
    • dynamic memory storage (heap) 的配置與管理問題
      • 用來操作未知大小的資料
      • 在需要時配置,使用完成後釋放
    • Memory leak
      • heap 中可用記憶體會持續減少,直到完全耗盡
      • DoS attack: 導致程式 crash
    • 許多較舊的語言 (包括 C) 沒有對動態配置記憶體提供明確支援
      • 容易發生問題
    • 現代語言 (例如 Java 與 C++) 會自動處理這些問題

Preventing Race Conditions with Shared Memory

  • Race condition
    • 多個 processes 與 threads 競爭,以取得對某些資源的非受控存取
    • 解決方式: 正確選擇並使用適當的同步機制 (synchronization primitives)
    • deadlock 仍然可能是一個問題
    • 攻擊者可能觸發 deadlock,以發動 DoS

Interacting with the OS and Other Programs

  • 一般而言,在大多數電腦系統上,程式並不是獨立執行的
    • 多個使用者/程式
    • 各種共享檔案與裝置
    • 作業系統負責仲介對系統資源的存取
    • 作業系統會在所有執行中的程式之間共享這些資源的使用
  • 重要議題:
    • Environment variables
    • Using appropriate, least privileges
    • Systems calls and standard library functions
    • Preventing race conditions with shared system resources
    • Safe temporary file use
    • Interacting with other programs

System Calls and Standard Library Functions

  • 程式會使用系統呼叫與標準函式庫函式來完成常見操作
  • 程式的實際行為可能不如預期
    • 對系統呼叫與標準函式庫函式的操作方式做出了錯誤假設
    • 可能是因為系統會最佳化對共享資源的存取
    • 為了最佳化系統使用,服務請求可能會被 buffered、重新排序,或以其他方式修改
    • 這些最佳化可能與程式本身的目標互相衝突

Example

How to Securely Delete a File?

  • 標準 file delete: simply removes the linkage between the file’s name and its contents (移除連結)
  • 想要安全的移除檔案,避免又被讀取:
  • 錯誤假設:
    • System will write the new data to same disk blocks
    • Data are written immediately to disk
    • When the I/O buffers are flushed and the file is closed, the data are then written to disk
  • 修正後:
    • 改用 open file for update: 寫到相同 disk blocks
    • 增加 flush application write buffers: 馬上寫入 disk
    • 增加 sync file system write buffers with device: 將 file system 的資料與 device 同步

Handling Program Output

  • 程式輸出
    • May be stored for future use, sent over net, displayed
    • May be binary or text
  • 必須符合預期的格式與解讀方式
  • 程式必須辨識哪些內容是允許的輸出
    • 過濾任何可能不可信的資料,以確保只有合法輸出會被顯示
  • 明確指定 Character set

紅字整理

P7, 8: Defensive Programming, increase codes and time spent

  • Conflicts with business pressures
  • Requiring a changed mindset to traditional programming practices (改變傳統程式設計思維)

P12: Input Size & Buffer Overflow, Safe coding regards any input as dangerous

  • 把所有輸入都視為危險的