我們之前有介紹過 ZAP 這款開源的弱點掃描軟體,ZAP 是屬於黑箱測試,我們需要提供他 URL 來做程式碼的弱點測試。
但馬上就會遇到一個問題 – 權限驗證。
我相信大部分的系統都會有登入的功能,但總不可能因為這是需要登入的功能就不需要進行弱掃吧?
甚至你整個系統基本上要登入後才進行,就會發現 ZAP 取得了整排的 401 或 403。
事實上 ZAP 也提供了登入驗證的設定,基本上就是你提供登入的資訊,比如帳密或是 Token,ZAP 會使用你提供的帳密取得權限後,來進行弱掃。
我們會從建立 API 開始說明,到使用 ZAP 成功掃描到有驗證保護的 API。
建立 API
- 我們這邊選用的框架是使用 Python 的 FastAPI,首先進行安裝的部分 FastAPI
$ pip install "fastapi[standard]"
- 建立需登入與不需登入 API
這裡我們使用 FastAPI 快速建立兩個 API 來進行測試,一個不需登入就能取得,另一個則必須登入。
main.py
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBasic
from pydantic import BaseModel
app = FastAPI()
security = HTTPBasic()
class User(BaseModel):
username: str
password: str
mock_users_db = {
"admin": User(username="admin", password="password"),
}
@app.get("/")
def read_root():
return "Hello, world!"
@app.get("/login", response_model=User)
async def login(credentials: HTTPBasic = Depends(security)):
user = mock_users_db.get(credentials.username)
if not user or user.password != credentials.password:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": "Basic"},
)
return user
這邊就不詳細說明 FastAPI 的細節,可以參考官方文件:
- 執行伺服器
$ fastapi run main.py
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
- 用瀏覽器測試 API 是否正常
我們刻意都使用 GET,這樣可以直接使用瀏覽器測試。
會取得 Hello, world!
字樣。

有 Basic Auth 保護的 API,首先會跳出帳密彈窗,要求你進行登入驗證。

模擬的帳密是 admin / password,你可以隨便亂打試試,會卡在彈窗畫面。

成功登入的話,會顯示登入的帳密。

使用 ZAP 掃描 API (沒做驗證設定)
- 把 ZAP 的 Docker 跑起來
設定檔跟使用方法的部分可以參考上一篇 開源弱點掃描軟體 – ZAP
- 修改執行 FastAPI 伺服器指令
再來我們會遇到一個問題,ZAP 掃不到 localhost。

因為我們是使用 Docker 把 ZAP 跑起來,localhost 會指向 Container 的內部,肯定是怎樣都掃不到的。
$ fastapi run main.py
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
改用 run
之後,我們會發現 Uvicorn 把網址改跑在 http://0.0.0.0:8000 了,這樣外部就能連得到這個伺服器。
再來我們需要取得我們的私有 IP,取得方式可以參考這個:私有 IP 查詢

我們這次有掃到了 http://your.private.ip.ip:8000。
但取得根頁面之後,並不會知道我們還有哪些 API,爬蟲只會根據頁面的連結去判定有沒有其他頁面,這樣 /login
永遠都不會被找到。
使用 ZAP 掃描到完整的 API (沒做驗證設定)
FastAPI 預設就會產生 OpenAPI:http://127.0.0.1:8000/openapi.json。
你用瀏覽器打開會看到裡面會包含所有的 API 的資訊。

我們把裡面的內容儲存成檔案 openapi.json
。
- 選擇 OpenAPI 設定檔
ZAP 其實也能讀取 URLs.txt. GraphQL. Postman 等等設定檔,有興趣或需求可以再去嘗試。

- 選擇檔案

- 把檔案拖曳到右下角讓他上傳到 ZAP。

- 選擇
openapi.json

- 匯入
openapi.json
記得設定 Target URL。

- ZAP 讀取設定檔
會顯示有讀取到幾隻 API。

- 再次掃描
這次根據 openapi.json 提供的 url,有掃到 /login
了。

先選到 Active Scan 會發現,雖然有掃到 /login
,但他其實被擋下來了。

使用 ZAP 掃描到完整的 API (進行驗證設定)
因為 ZAP 有經歷過大改版,以前官方 GitHub 跟 Stack Overflow 有很多 FAQ 跟討論全部連結報廢,新版官方文件又基本上什麼都沒寫。
那時候找很久才找到相關的教學,推薦給大家:
https://www.youtube.com/watch?v=fikw_pNzxIk
- 選擇 Session 參數

- 設定 Authentication
選擇 HTTP Authentication,然後設定伺服器資訊。

- 新增使用者

- 設定使用者


設定完成之後點選 OK。
- 啟動掃描
這次我們不選擇中間的自動掃描,改由左邊啟動,會顯示一個彈窗。

- 設定掃描使用者為剛剛建立的使用者

- 掃描完成

結論
我們成功從建立範例 API,然後進行掃描,掃不到所有 API。
到掃到所有 API 卻無法通過驗證,到通過驗證,用 ZAP 進行完整的弱點掃苗。
掃不到全部 API 跟無法通過身份驗證,應該是大家使用 ZAP 馬上就會面臨的問題,希望這篇文章有幫助到大家。