軟體系統安全性

軟體系統安全性（software system safety）也稱為軟體安全（Software safety），要確保用在生命攸關系統的軟體，不會讓系統產生危害。

許多不同領域的安全標準，會指導安全相關軟體如何開發和如何測試。大部分會依軟體應用的關鍵程度為軟體分級，並針對不同等級的軟體，說明在開發和驗證過程需要用的技術和量測方式：

- 通用電子安全關鍵系統的軟體：IEC 61508（標準中的第3部份）
- 車用軟體：ISO 26262 （標準中的第6部份）
- 鐵路軟體：EN 50716
- 飛航軟體：DO-178C
- 空中交通管理軟體：DO-278A/ED-109A
- 醫療軟體：IEC 62304
- 核電廠：IEC 60880

## 詞語

系統安全是總體性的要求，目的是要將技術系統中的風險降到可接受的程度，以此實現安全性。根據功能安全標準IEC 61508，安全是「不會有無法接受的風險或傷害」。軟體本身可以視為是單純的資訊，本身不會造成傷害，因此有時會將「軟體安全」一詞改為「軟體系統安全」（例如Joint Software Systems Safety Engineering Handbook和MIL-STD-882E就使用此一詞語）。後者強調軟體只會造成其技術系統的傷害（參考NASA Software Safety Guidebook, chapter 2.1.2），而其傷害會對系統周圍有影響。

軟體安全的目的是確保軟體不會造成所在系統的危害，而且此事可以確認並且證明。這一般是用指定軟體的「安全等級」，並且選擇適當的開發程序以及證認程序來達到。

## 指定安全等級

創建安全相關軟體時的第一步是依照其安全關鍵程度來分類。不同安全標準有各自的分類：像是DO-178C的軟體等級A-E、IEC 61508的SIL（安全完整性等級，Safety Integrity Level）1-4、ISO 26262的ASIL（車用安全完整性等級、Automotive Safety Integrity Level）A-D。

一般會在系統層級指定安全等級，也會評估軟體失效的最壞後果。例如，車用標準ISO 26262要求在整車等級進行危害分析與風險評估（Hazard Analysis and Risk Assessment，簡稱HARA），以此推導某一元件上軟體的ASIL。

## 流程遵守與保證

在考慮軟體的安全性時，需要依軟體的安全關鍵程度，使用充足的開發流程以及驗證流程，配合適當的方法或是技術。軟體安全標準可能會建議一些方法或是技術，甚至強制使用特定方法或技術，視安全等級而定。

大部份的標準都會建議生命週期模型（像是EN 50716、IEC 61508的SIL 1-4會要求V模型），並且說明在軟體開發的不同階段需要進行的活動。例如，IEC 61508要求軟體需要有充份的規格說明（可能用型式方法或是半型式方法）、軟體設計需是模組化且可測試的、需使用有充份功能的程式語言、需進行文件化的程式碼評審、需有多層級的測試，以達到充夠的測試覆蓋率。

對軟體開發流程和驗證流程的注重是源自於一個事實：軟體品質（和安全）會高度的受到軟體流程的影響，如IEC 25010所述的一樣。IEC 25010提出流程會影響內在的軟體品質屬性（程式碼品質），因此也會影響外在軟體品質屬性（像是功能性和可靠度）。

以下是一些安全軟體的開發流程中會提到的活動和概念。

### 文件

在本質上，所有軟體安全標準都會要求針對開發流程和驗證流程全面且完整的文件。通常這些文件需經過第三方的評審和核可，是安全相關軟體核可的前提。文件包括許多的計劃文件、需求規格、軟體架構以及設計文件、不同抽象程度的測試案例、工具鑑定報告、評審證據、驗證和確認（verification and validation）結果等。在EN 50716的圖C.2中列出在開發生命週期中需要創建的32份文件。

### 可追蹤性

需求可追蹤性（Requirements traceability）是建立不同種類的需求之間的關係，需求和設計、實現和測試文件之間關係的實務。依照EN 50716，其目的是「確保所有需求都已妥善滿足，沒有引入任何無法追蹤的東西」。透過建立可追蹤性的文件，並且維護，就可能讓一個安全需求對應到系統設計（以驗證設計時已有充份的考量）、再對應到軟體程式碼（以驗證程式碼符合需求）、以及適當的測試案例以及測試實做（驗證安全需求已被充份的測試）。

### 軟體實現

安全標準中有些要求會直接影響軟體程式碼的實現，例如使用適當的程式語言、函式的大小和複雜度、使用特定的程式架構以及程式碼標準等。在IEC 61508的第三章包括了以下的要求和建議：

- 使用強型態的程式語言。有些語言比較適合用在安全相關系統中。支援強型態的程式語言可以在編譯時就偵測到錯誤，而不是在運行時才發現。因此，不建議用組合語言，建議使用針對安全相關市場的高階語言（例如ADA）。
- 使用定義了「安全」語言子集的程式碼標準，例如MISRA C。MISRA-C是C語言的程式碼標準，為了是要提昇程式碼品質和安全性，此標準會不允許一些易錯的程式寫法、一些與編譯器有關的特性（因此其行為是未定義的）。
- 限制遞迴、指標和中斷的使用（這些容易出現錯誤）
- 不允許「非結構化的流程控制」，也就是非結構化的跳躍指令，例如Goto指令。

### 測試覆蓋率

需要有適當的測試覆蓋率，若安全等級越高，就需要用越嚴謹的測試框架。以下是DO-178C針對不同軟體等級的需求：

- C級：指令覆蓋率。在測試時「每一個指令至少執行過一次」。
- B級：分支覆蓋率。「程式的每一個進入點和結束點都至少執行一次，程式中判斷的所有可能結果都已進行過一次。」
- A級：修改條件判斷覆蓋（MC/DC）：分支覆蓋的延伸，加上「判斷中所有的條件都會獨立影響判斷的結果。」

### 獨立性

軟體安全標準一般會需要在要求一定程度獨立性的情形下，進行特定流程活動，獨立性可能是不同的人、不同主管底下的員工、甚至是獨立組織。這避免利益衝突，也可以增加找到錯誤的可能性。

例如EN 50716的圖2要求「實現者」、「測試者」（tester）和「驗證者」（verifier）需是不同的人，「確認者」（validator）需是其他主管底下的員工，而「評估者」就是另一個部門的人。

DO-178C和DO-278A有要求一些活動（例如測試覆蓋率的驗證、保證活動等）要由具有獨立性的人員進行，獨立性定義為「責任的分工，以確保可以達成客觀的評估。」

## 未解決的問題

### 軟體失效率

在系統安全工程中，常會針對子系統或是元件的失效率訂定上限。接著必須證明子系統或是元件的失效率不會超過分配的失效率，不然就要加上冗餘或是其他容錯機制。此作法在軟體上不適用。

軟體失效率無法準確預測。儘管軟體可靠性領域已進行了大量研究（例如Lyu (1996)），但現有的軟體安全標準沒有要求使用其中任何一種方法，甚至是不鼓勵使用，例如 DO178C（73頁）中提到「許多基於開發指標預測軟體可靠性的方法已被發表，例如軟體結構、缺陷檢測率等。本文檔不提供這些方法的指導，因為在撰寫本文時，現有方法尚未提供值得信賴的結果證明。」ARP 4761的4.1.2條款提到軟體設計錯誤「和硬體失效不一樣。硬體失效有失效率，而軟體錯誤的機率無法量化。」

### Safety和security

軟體安全性（Software safety）和保安（security，保證資訊只會被授權使用者使用，保證資訊不會被破壞）注重的層面不同。若安全相關的軟體，可能會被修改盜用（secure相關問題），就可能會出現保安（security）的隱患。另一方面，有些保安（security）上的實務（例如頻繁且定期的更新補丁），和已實務的安全實務相衝突（在已運作的系統要變更任何事務，都需要嚴謹的測試以及驗證）。

### 人工智慧

使用人工智慧技術（例如機器學習）的軟體，其生命週期和傳統軟體差異很大。相對於以傳統方式開發的系統，上述軟體的行為不容易預測。現今仍在探討是否要在安全領域使用這類軟體，以及如何使用。目前，相關標準普遍不認可人工智慧和機器學習的應用。例如，EN 50716（表 A.3）指出，不建議在任何安全完整性等級中使用人工智慧和機器學習。

### 敏捷開發方法

敏捷軟體開發其特徵是會有非常多次的迭代，有時仍被認為過於混亂，不適用於安全相關的軟體開發。這一部份可能是因為敏捷開發宣言中提到的「可工作的軟體勝過詳盡的文件」。大部份軟體安全相關標準是類似傳統瀑布模型的生命週期，有些標準則允許更靈活的作法。DO-178C中提到「軟體生命週期的過程可以是迭代的，即可以重複進入和重新進入。」 EN 50716的附錄C有說明如何使用迭代式的開發週期，同時符合該標準的要求。

## 相關條目

- 軟體保證
- IEC 61508 - 電子/電機/可程式電子安全關鍵系統的功能安全
- ISO 26262 - 道路車輛 – 功能安全
- 功能安全
- 軟體質量保證
- 系統意外

## 參考資料

此條目使用美軍的 Software handbook 裡的公開領域文件。