在現今網路攻擊日益猖獗的環境下,確保網頁應用程式的安全性至關重要。OWASP ZAP 提供了強大的工具和技術,協助開發者識別和修復應用程式中的安全漏洞。透過 Juice Shop 這個具有多種已知漏洞的應用程式,開發者可以在安全的環境中練習使用 ZAP 進行滲透測試,並學習如何分析掃描結果和修復漏洞。瞭解 ZAP 的操作模式,例如安全模式、保護模式、標準模式和攻擊模式,能幫助開發者根據不同的測試需求選擇合適的設定。此外,使用 ZAP API 可以將安全掃描整合到自動化測試流程中,提升開發效率並確保應用程式安全。

使用OWASP ZAP進行安全性測試的實務操作

隨著網路安全威脅日益增加,開發人員需要具備完善的安全測試工具來保護其網頁應用程式。由OWASP(開放式網頁應用程式安全計畫)開發的ZAP(Zed Attack Proxy)是一款強大的開源安全測試工具,能協助開發人員識別和修復網頁應用程式中的安全漏洞。

為何選擇OWASP Juice Shop作為測試目標?

為了有效地示範ZAP的功能,OWASP提供了Juice Shop,一個特意設計成具有多種安全漏洞的網頁應用程式。Juice Shop可以在多個平台上執行,包括Node.js、Docker、Vagrant,以及在Amazon Web Services(AWS)Elastic Compute Cloud(EC2)、Azure和Google Compute Engine上佈署。這個應用程式提供了一個安全的環境,讓開發人員可以在不擔心對實際系統造成損害的情況下進行安全測試。

安裝OWASP ZAP

安裝ZAP的過程取決於您所使用的作業系統:Linux、macOS或Windows。您可以從ZAP的官方網站下載適合您平台的安裝包並按照安裝指示進行安裝。啟動ZAP後,您將被提示是否要儲存當前的工作階段,以便稍後繼續。圖3-6顯示了這個提示畫面。

重要步驟:

  • 選擇是否儲存工作階段。如果不確定,可以選擇“是,我想以當前時間戳記儲存這個工作階段”。
  • 您也可以勾選“記住我的選擇,不要再詢問”以避免未來出現相同的提示。

使用ZAP進行手動掃描

ZAP提供了多種模式來防止誤用,包括安全模式(Safe Mode)、保護模式(Protected Mode)、標準模式(Standard Mode)和攻擊模式(ATTACK Mode)。預設情況下,ZAP可能不在安全模式下,因此建議將其設定為安全模式,以避免對非您擁有的網站進行掃描。

ZAP操作模式:

模式描述
安全模式(Safe Mode)禁止可能造成損害的操作。
保護模式(Protected Mode)對未驗證的URL掃描能力有限。
標準模式(Standard Mode)允許所有操作。
攻擊模式(ATTACK Mode)允許所有操作,並在掃描時自動掃描新發現的專案。

在安全模式下,您可以手動瀏覽目標網站並使用ZAP的Heads Up Display(HUD)來檢視發現的問題。啟動手動瀏覽後,ZAP將透過其代理啟動Firefox瀏覽器,並在頁面上顯示HUD,提供有關已發現問題的資訊。

使用ZAP進行自動掃描

雖然手動瀏覽是一種學習ZAP功能的好方法,但重複進行此操作既耗時又無趣。因此,ZAP提供了自動掃描功能,可以快速識別目標網站中的安全漏洞。

執行自動掃描的步驟:

  1. 將ZAP的操作模式切換到標準模式(Standard Mode)。
  2. 點選“自動掃描”按鈕並輸入目標URL。
  3. ZAP將開始掃描指定的網站並報告發現的漏洞。

掃描結果與分析

自動掃描完成後,您可以使用ZAP的HUD或直接在ZAP介面中檢視掃描結果。結果將按嚴重程度分類別,您可以點選每個警示以檢視詳細資訊和建議的解決方案。

程式碼範例:使用ZAP API進行自動掃描

from zapv2 import ZAPv2

# 初始化ZAP API客戶端
zap = ZAPv2(proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})

# 開啟目標URL
zap.urlopen('http://localhost:5150')

# 進行主動掃描
scan_id = zap.spider.scan('http://localhost:5150')

# 檢視掃描狀態
while int(zap.spider.status(scan_id)) < 100:
    print('Spider scan progress: ' + zap.spider.status(scan_id) + '%')
    time.sleep(2)

# 取得掃描結果
print('Spider scan completed.')
print(zap.core.alerts())

內容解密:

上述Python指令碼利用ZAP的API實作自動掃描。首先,我們初始化ZAP客戶端並開啟目標URL。接著,我們啟動蜘蛛掃描並持續檢查掃描狀態,直到完成。最後,我們取得並列印掃描結果,包括發現的警示資訊。

隨著網路安全威脅的不斷演變,ZAP等安全測試工具也將持續更新和改進,以應對新的挑戰。開發人員應持續關注最新的安全測試技術和工具,不斷提升其應用程式的安全性。

安全性考量

在使用ZAP進行安全測試時,應始終確保您有權對目標網站進行測試,並且不會對生產環境中的應用程式造成不必要的風險。

圖表翻譯:
  graph LR;
    A[開始安全測試] --> B[安裝OWASP ZAP];
    B --> C[選擇操作模式];
    C --> D[手動瀏覽或自動掃描];
    D --> E[檢視掃描結果];
    E --> F[分析並修復安全漏洞];

此圖示展示了使用OWASP ZAP進行安全測試的基本流程,從安裝ZAP開始,到分析並修復發現的安全漏洞為止。透過這個流程,開發人員可以系統性地提升其網頁應用程式的安全性。

使用 OWASP ZAP 進行自動化安全掃描與整合開發安全測試

在現代化的 DevSecOps 流程中,自動化安全掃描是不可或缺的一環。OWASP ZAP(Zed Attack Proxy)作為一個廣泛使用的開源安全測試工具,能夠有效地協助開發團隊在開發過程中識別潛在的安全漏洞。本文將介紹如何使用 OWASP ZAP 對本地 Juice Shop 網站進行自動化掃描,並進一步探討如何將 ZAP 整合到 CI/CD 管道中,以實作持續的安全測試。

啟動對本地 Juice Shop 網站的自動化掃描

當我們使用 OWASP ZAP 對本地佈署的 Juice Shop 網站進行安全測試時,首先需要啟動自動化掃描。點選「Attack」按鈕後,ZAP 便會開始對目標網站發起掃描。


#### 自動化掃描流程圖示
```mermaid
graph LR
    A[啟動 ZAP 自動掃描] --> B[掃描進行中]
    B --> C[發現潛在安全問題]
    C --> D[生成詳細報告]

圖表翻譯: 此圖示展示了使用 OWASP ZAP 進行自動化掃描的基本流程,包括啟動掃描、掃描進行中的狀態,以及最終生成安全問題的詳細報告。

掃描過程中的 Juice Shop 網站變化

在掃描過程中,Juice Shop 網站上會出現彩帶(confetti)並彈出提示,表明某些安全挑戰已被成功解決。這是因為 Juice Shop 內建了多項安全挑戰,而 ZAP 的掃描恰好觸發了這些挑戰的條件。例如,ZAP 可能會透過模擬攻擊來觸發未處理的錯誤、存取機密檔案、檢視其他使用者的購物車或重複註冊等操作。

自動化掃描結果分析

ZAP 的自動化掃描會持續一段時間,期間會傳送數千個請求來遍歷網站的各個頁面並發現新的資源。掃描完成後,ZAP 會顯示「Alerts」標籤頁,其中包含了掃描過程中發現的安全問題詳細資訊。


#### SQL 注入漏洞範例
```sql
-- SQL 注入攻擊範例程式碼
SELECT * FROM users WHERE username = 'admin' AND password = 'password' OR '1'='1';

內容解密:

上述 SQL 注入範例展示了一種常見的攻擊方式。攻擊者透過在輸入欄位中注入惡意 SQL 程式碼,繞過驗證機制,取得未授權的資料存取許可權。正確的做法是使用預編譯 SQL 陳述式(Prepared Statements)來避免此類別攻擊。

-- 正確的 SQL 查詢範例
PREPARE stmt FROM 'SELECT * FROM users WHERE username = ? AND password = ?';
SET @username = 'admin';
SET @password = 'password';
EXECUTE stmt USING @username, @password;

內容解密:

在這個修正後的範例中,我們使用了預編譯 SQL 陳述式,引數 ? 會被實際輸入的值所替代,而不會被直接拼接到 SQL 陳述式中,從而有效防止 SQL 注入攻擊。

將 ZAP 整合到 CI/CD 管道

除了手動掃描外,ZAP 還可以透過命令列執行,並整合到 CI/CD 管道中,實作自動化的安全測試。這樣可以在開發的早期階段就發現並修復安全問題,大大提高軟體的安全性。

# 使用命令列執行 ZAP 掃描
zap-cli quick-scan --self-contained --spider https://example.com

內容解密:

上述命令列指令使用 zap-cli 工具對指定的目標網站進行快速掃描,並啟用爬蟲功能來遍歷網站頁面。掃描結果將直接輸出到終端,便於開發人員及時檢視和處理。

管理程式碼與測試

在 DevSecOps 的生命週期中,有三個階段專注於與開發人員相關的任務,包括程式碼開發、構建可執行的應用程式以及測試應用程式。完整的測試流程會涉及其他團隊,如品質保證(QA)團隊,但至少部分測試是在開發人員層級進行的。構建步驟會根據所使用的程式語言進行高度自定義,有些語言需要編譯產出物,而其他語言則可以以未編譯的狀態佈署。本章節將首先關注開發過程,然後介紹用於測試軟體的概念和工具。同時,本章節還將介紹 Git 用於原始碼管理,以及在軟體開發過程中使用 Git 的兩種模式。

程式碼開發考量

由於現有的程式語言數量眾多,不可能在一章節或甚至一本文中涵蓋所有知識。因此,我們需要參考一些經典的資源,如 O’Reilly 出版的書籍,以及 Martin Fowler 在軟體設計和架構領域的著作。這些資源為開發人員提供了深入的指導和最佳實踐。

在軟體開發過程中,遵循一些基本的原則和最佳實踐至關重要。這些原則包括但不限於程式碼的可讀性、可維護性以及可擴充套件性。同時,使用適當的工具和流程,如 Git 進行原始碼管理,可以大大提高開發效率和程式碼品質。

Git 原始碼管理

Git 是一個分散式版本控制系統,廣泛應用於軟體開發中,用於管理程式碼變更和協調多個開發人員之間的合作。正確使用 Git 可以有效地追蹤程式碼變更,避免衝突,並簡化程式碼合併過程。

# 初始化新的 Git 倉函式庫
git init

# 新增檔案到 Git 倉函式庫
git add .

# 提交變更
git commit -m "Initial commit"

內容解密:

上述 Git 指令展示瞭如何初始化一個新的 Git 倉函式庫,將檔案新增到倉函式庫中,並提交變更。正確使用 Git 可以有效地管理程式碼變更,提高開發效率。

軟體測試策略

軟體測試是確保軟體品質的重要環節。除了單元測試和整合測試外,還需要進行更全面的測試,如系統測試和驗收測試。使用適當的測試工具和框架,可以自動化測試流程,提高測試效率和準確性。

# 使用 Python unittest 進行單元測試
import unittest

def add(a, b):
    return a + b

class TestAddFunction(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(1, 2), 3)

if __name__ == '__main__':
    unittest.main()

內容解密:

上述 Python 程式碼展示瞭如何使用 unittest 框架進行單元測試。正確的測試策略可以確保軟體的功能正確性,提高軟體品質。

管理程式碼與測試的最佳實踐

在軟體開發過程中,如何有效地管理程式碼和進行測試是至關重要的。良好的程式碼管理和測試策略不僅能提高程式碼的品質,還能減少未來維護的困難度。本文將探討一些關鍵的最佳實踐,包括如何編寫有意圖的程式碼、避免重複程式碼,以及使用Git進行原始碼管理。

有意圖的程式碼編寫

在編寫程式碼時,開發者常常面臨時間壓力或其他因素的限制,這可能導致程式碼不夠完善。例如,以下程式碼假設美國總是有50個州,且它們的字母順序永遠不會改變:

for i in range(50):
    if i == 49:
        state_name = "Wisconsin"

這種寫法雖然在特定情況下可以完成任務,但卻引入了技術債。技術債是指在開發過程中,為了快速完成任務而採取的權宜之計,這些權宜之計可能會在未來造成更多的問題。

技術債的影響

技術債可能導致程式碼難以維護、擴充套件性差,並且在未來需要花費更多時間和資源來修正。硬編碼的值尤其如此,因為當這些值需要更改時,所有相關的程式碼都需要更新,這不僅耗時,還可能引入新的錯誤。

避免重複程式碼

另一個重要的最佳實踐是避免重複程式碼。例如,在計算訂單總額時,可能會有多個地方需要使用稅率。如果每個地方都硬編碼稅率,那麼當稅率變更時,就需要修改多個地方的程式碼。這不僅容易出錯,還增加了維護的困難度。

# 不好的做法:硬編碼稅率
order_tax = subtotal * 0.055

更好的做法是使用常數來代表稅率:

# 好的做法:使用常數
const TAX_RATE = 0.055
order_tax = subtotal * TAX_RATE

這樣,當稅率需要變更時,只需修改一處即可,大大減少了出錯的可能性。

內容解密:

  1. 使用常數的好處:使用常數可以減少程式碼中的重複值,使得程式碼更容易維護。
  2. 避免硬編碼:硬編碼的值在未來可能需要變更,使用變數或常數可以減少這種情況下的維護成本。
  3. 提高程式碼的可讀性:使用有意義的常數名稱可以提高程式碼的可讀性,讓其他開發者更容易理解程式碼的意圖。

使用Git進行原始碼管理

Git是一種流行的原始碼管理工具,它可以幫助開發者追蹤程式碼的變更歷史,並且可以輕鬆地回復到之前的版本。無論是個人開發還是團隊協作,Git都是非常有用的。

簡單的Git設定

在本地伺服器上設定Git可以提供更高的隱私性和成本效益。以下是設定Git伺服器的基本步驟:

  1. 安裝Git和SSH伺服器:在Linux伺服器上安裝Git和SSH伺服器。
  2. 建立Git使用者和群組:建立一個名為gituser的使用者和一個名為gitusers的群組。
  3. 組態SSH存取:組態SSH存取以允許使用者透過SSH協定與Git伺服器互動。
# 新增gituser使用者
adduser gituser

# 更改gituser的shell
chsh gituser

# 建立.ssh目錄並設定許可權
cd /home/gituser && mkdir .ssh
chown gituser.gituser .ssh && chmod 700 .ssh

# 新增authorized_keys檔案
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

# 建立gitusers群組
groupadd gitusers

內容解密:

  1. Git伺服器的設定:設定Git伺服器需要安裝Git和SSH伺服器,並組態使用者和群組。
  2. SSH存取組態:透過SSH協定存取Git伺服器需要組態SSH金鑰。
  3. 使用者和群組管理:建立和管理使用者及群組是控制Git儲存庫存取許可權的重要步驟。

在Git伺服器上建立開發者帳號與設定SSH金鑰

為了確保開發者能夠安全地存取Git儲存函式庫,首先需要在伺服器上為開發者建立帳號。假設需要新增的開發者帳號分別為suehringrkonkol,可使用以下指令:

adduser suehring
adduser rkonkol

接著,將這些開發者帳號加入到gitusers群組中,以便他們能夠存取Git相關資源:

usermod -G gitusers suehring
usermod -G gitusers rkonkol

設定SSH金鑰認證

為了讓開發者能夠安全地存取Git儲存函式庫,需要為他們生成SSH金鑰。開發者可以使用ssh-keygen命令生成金鑰對:

su - suehring
mkdir .ssh
chmod 700 .ssh
cd .ssh
ssh-keygen

在執行ssh-keygen時,可以選擇接受預設的檔案名稱,並決定是否為金鑰設定密碼。

內容解密:

  1. su - suehring:切換到suehring使用者帳號。
  2. mkdir .ssh:在使用者目錄下建立.ssh目錄,用於存放SSH相關設定。
  3. chmod 700 .ssh:設定.ssh目錄的許可權,確保只有使用者本人能夠存取。
  4. ssh-keygen:生成SSH金鑰對,包括私鑰(id_rsa)和公鑰(id_rsa.pub)。

設定公鑰到授權金鑰檔案

生成金鑰對後,需要將公鑰(id_rsa.pub)的內容新增到gituser使用者的authorized_keys檔案中,以便開發者能夠以gituser的身分進行SSH連線:

cat id_rsa.pub >> ~gituser/.ssh/authorized_keys

內容解密:

  1. cat id_rsa.pub:顯示公鑰檔案的內容。
  2. >> ~gituser/.ssh/authorized_keys:將公鑰內容附加到gituser使用者的authorized_keys檔案中,確保使用兩個大於符號(>>)以避免覆寫原有內容。

建立Git儲存函式庫

完成上述設定後,便可以在Git伺服器上建立新的Git儲存函式庫。首先,建立儲存函式庫的目錄:

mkdir /opt/git/devsecops.git && cd /opt/git/devsecops.git

然後,使用git init --bare --shared=group命令初始化儲存函式庫:

git init --bare --shared=group

內容解密:

  1. git init --bare:建立一個裸的Git儲存函式庫,適合用於遠端伺服器。
  2. --shared=group:設定儲存函式庫的許可權,使其能夠被gitusers群組中的成員存取。

接著,變更儲存函式庫的擁有者和許可權:

chown -R gituser.gitusers /opt/git/devsecops.git
chmod 770 /opt/git/devsecops.git

內容解密:

  1. chown -R gituser.gitusers:將儲存函式庫目錄及其內容的擁有者變更為gituser,並將群組設定為gitusers
  2. chmod 770:設定儲存函式庫目錄的許可權,使gitusergitusers群組成員能夠讀寫該目錄。

使用Git進行版本控制

完成Git儲存函式庫的設定後,開發者便可以將儲存函式庫複製到本地開發環境:

git clone gituser@source.example.com:/opt/git/devsecops.git

內容解密:

  1. git clone:將遠端Git儲存函式庫複製到本地。
  2. gituser@source.example.com:/opt/git/devsecops.git:指定遠端儲存函式庫的位置。

開發者首次連線至伺服器時,會被提示接受主機金鑰。確認主機金鑰無誤後,輸入yes即可完成複製。

Git基本操作流程

使用Git進行版本控制的基本步驟如下:

  1. 複製儲存函式庫:使用git clone命令下載儲存函式庫到本地。
  2. 編寫程式碼:在本地進行開發工作。
  3. 提交變更:使用git addgit commit命令將變更提交到本地儲存函式庫。
  4. 推播變更:使用git push命令將本地變更推播到遠端儲存函式庫。
  5. 合併變更:當多人協作時,需要使用git merge命令合併不同開發者的變更。

Git常用指令詳解

新增檔案到儲存函式庫

當新增檔案到Git儲存函式庫時,需要使用git add命令將檔案納入版本控制:

git add README.md

內容解密:

  1. git add README.md:將README.md檔案新增到Git的追蹤列表中。

提交變更

當檔案內容發生變更時,需要使用git commit命令提交變更:

git commit -m "Initial commit of README.md"

內容解密:

  1. git commit:提交變更到本地儲存函式庫。
  2. -m "Initial commit of README.md":為此次提交新增註解,描述變更內容。

Git檔案狀態詳解

在Git中,檔案主要有兩種狀態:未追蹤(Untracked)已追蹤(Tracked)

  1. 未追蹤檔案:Git尚未開始追蹤的檔案。
  2. 已追蹤檔案:Git正在追蹤變更的檔案。

對於已追蹤的檔案,Git會監控其變更。當檔案內容發生變更時,需要使用git add命令將變更暫存,然後再使用git commit提交變更。

合併變更與衝突解決

在多人協作的開發環境中,合併變更是常見的操作。當不同開發者對同一檔案進行變更時,可能會發生合併衝突。Git提供了多種工具來幫助解決合併衝突,例如:

git merge feature-branch

若發生衝突,Git會標示出衝突區域,並需要手動解決衝突後再提交變更。

內容解密:

  1. git merge:合併指定的分支到當前分支。
  2. feature-branch:需要合併的分支名稱。