這是主動攻擊嗎?
不是。它只送出一般的 GET、HEAD 和 OPTIONS 請求,進行 TLS 交握(包括嘗試 TLS 1.0 和 1.1),透過 Cloudflare 的 DNS over HTTPS 查詢 DNS,並對 12 個連接埠做簡單的 TCP 連線。不利用任何漏洞,不送出任何表單,也不修改任何內容。
我可以掃描任何網站嗎?
只能掃描你擁有或已獲授權測試的網站。未經許可掃描第三方基礎設施,在你所在地可能是違法的。
為什麼一項檢查顯示"未檢查"?
因為它無法完成 - 通常是因為該來源沒有任何回應。它會被誠實地回報,而不會被記為通過。
我可以匯出報告嗎?
可以,匯出為 Markdown 或 JSON,有效期一小時:報告在這一小時內保存在伺服器快取中以便下載,之後過期。兩種匯出都不使用模型。使用紀錄只保存發現數量和等級,不保存網域。
它會檢測哪些檔案和連接埠?
檔案:23 個固定路徑,包括 /.git/HEAD, /.git/config, /.env, /.env.local, /.env.production, /.aws/credentials, /id_rsa, /backup.zip, /backup.sql, /dump.sql, /wp-config.php.bak, /phpinfo.php, /server-status, /actuator/env;只有當回應與該檔案特有的簽章相符時才會回報。若已發布 /.well-known/security.txt,則計為加分項。連接埠:對 21 FTP, 23 Telnet, 25 SMTP, 3306 MySQL, 5432 PostgreSQL, 6379 Redis, 27017 MongoDB, 9200 Elasticsearch, 3389 RDP, 5900 VNC, 11211 Memcached, 8080 發起一般 TCP 連線,絕不嘗試登入。可從外網存取的資料庫連接埠(MySQL、PostgreSQL、Redis、MongoDB、Elasticsearch)或 Telnet 會被評為嚴重。
SPF 和 DMARC 檢查會標記哪些問題?
兩筆記錄都從公共 DNS 讀取,即使網站不寄信也會檢查,因為少了它們,任何人都能寄出冒充你網域的郵件。沒有 SPF 記錄為中風險;含 +all 的 SPF 記錄允許網際網路上任何伺服器寄信,為高風險。_dmarc 下沒有 DMARC 記錄為中風險;p=none(或沒有 p= 標籤)只做監控,為低風險;p=quarantine 或 p=reject 通過。完全不寄信的網域可以發布 v=spf1 -all。
會檢查哪些安全標頭,什麼值才算通過?
檢查首頁回應中的六個標頭。缺少時,HSTS 與 Content-Security-Policy 為高風險,X-Content-Type-Options 與 X-Frame-Options 為中風險,Referrer-Policy 與 Permissions-Policy 為低風險。Strict-Transport-Security 的 max-age 至少要 15552000(180 天):更短為低風險,max-age=0 為中風險。如果 script-src 允許 'unsafe-inline'、政策允許 'unsafe-eval',或 default-src、script-src 中有單獨的 * 萬用字元,Content-Security-Policy 會被標為已削弱(中風險)。X-Content-Type-Options 必須正好是 nosniff。X-Frame-Options 應為 DENY 或 SAMEORIGIN,如果 CSP 已設定 frame-ancestors 則不需要。Referrer-Policy 只有在 unsafe-url 或 no-referrer-when-downgrade 時才會被標記。Permissions-Policy 只要存在即可。每個缺少或偏弱的標頭都附有一條 curl -sI 指令,方便你自行核對。
它如何檢查 Cookie 屬性(Secure、HttpOnly、SameSite)?
它讀取首頁回應中的每個 Set-Cookie 標頭(最多 12 個 Cookie),逐一檢查 Secure、HttpOnly 與 SameSite。缺少 Secure 或 HttpOnly 為中風險;只缺 SameSite 為低風險;SameSite=None 但沒有 Secure 會被單獨指出,因為瀏覽器會拒絕這種 Cookie。三項齊全即通過。常見修正是 Secure; HttpOnly; SameSite=Lax(Django 中為 SESSION_COOKIE_SECURE、SESSION_COOKIE_HTTPONLY 與 SESSION_COOKIE_SAMESITE)。掃描不會登入,所以看不到只在登入後才設定的 Cookie。可以用這條指令自行核對:curl -sI https://your-site/ | grep -i set-cookie
CORS 檢查如何進行,什麼情況下是嚴重?
它向首頁送出一個帶 Origin: https://scanner-probe.example 的 GET 請求,讀取回應中的 Access-Control-Allow-Origin 與 Access-Control-Allow-Credentials。沒有 Access-Control-Allow-Origin 標頭,或回傳一個不回顯測試來源的固定來源,即通過。回顯測試來源並同時回傳 Access-Control-Allow-Credentials: true 為嚴重,因為已登入使用者造訪的任何網站都能讀取其回應。回顯來源但不帶憑證為中風險。萬用字元 * 為低風險,若同時允許憑證則為中風險(瀏覽器會拒絕這種組合)。只檢測首頁,也不送出 OPTIONS 預檢請求,所以請另外檢測 API 路由:curl -sI -H "Origin: https://scanner-probe.example" https://your-site/api/ | grep -i access-control
TLS 檢查會測試哪些內容(憑證到期、TLS 1.0 和 1.1)?
它連線到 443 連接埠,驗證憑證鏈和主機名稱。無法通過驗證的憑證為高風險,已過期的憑證還會額外標為嚴重,剩餘不到 15 天的為中風險;否則會把主體、簽發者、到期日期和 SAN 名稱列為通過項目。協商出的協定必須是 TLS 1.2 或 TLS 1.3,更舊的版本為高風險。接著它分別單獨嘗試一次 TLS 1.0 交握和一次 TLS 1.1 交握:伺服器接受其中任何一個都會得到中風險結果,因為兩者都已被 RFC 8996 淘汰。如果掃描器本身的 OpenSSL 無法提供舊版本,就不回報任何內容,而不是去猜測。nginx 的修正方法是 ssl_protocols TLSv1.2 TLSv1.3; 可以用以下指令自行查看日期:echo | openssl s_client -connect your-site:443 -servername your-site 2>/dev/null | openssl x509 -noout -dates
它會檢查 HTTP 是否重新導向到 HTTPS 嗎?
會。它在不跟隨重新導向的情況下請求 http://your-site/。以 301 或 308 導向 https:// 位址即為通過。以 302、303 或 307 導向 HTTPS 為低風險,因為瀏覽器不會記住暫時性重新導向,每次新的造訪都會先送出一個未加密的請求。透過未加密 HTTP 直接提供頁面(2xx 回應)為高風險。如果 80 連接埠完全沒有回應,只是提示資訊,不算失敗。nginx 的修正方法是 server { listen 80; return 301 https://$host$request_uri; },然後加上 Strict-Transport-Security。可以用以下指令自行檢查:curl -I http://your-site/
它會標記哪些 HTTP 方法(TRACE、PUT、DELETE)?
它向你的首頁送出一次 OPTIONS 請求,讀取 Allow 回應標頭;沒有 Allow 時讀取 Access-Control-Allow-Methods。宣告了 TRACE、TRACK、PUT 或 DELETE 為中風險;只有 PATCH 或 CONNECT 為低風險;只有標準讀取方法即為通過。如果伺服器兩個標頭都沒有送出,就不回報任何內容。宣告了某個方法並不能證明它真的可用,所以修改之前先確認。TRACE 可能把請求標頭(包括 Cookie)原樣回傳給呼叫端(Cross-Site Tracing)。nginx 預設拒絕 TRACE;Apache 需設定 TraceEnable Off。把 PUT 和 DELETE 限制在確實需要它們的 API 路由上,並放在身分驗證之後。可以用以下指令自行檢查:curl -X OPTIONS -i https://your-site/
它如何偵測目錄列表("Index of /")?
它請求 7 個路徑:/, /static/, /assets/, /uploads/, /images/, /files/ 和 /backup/。某個路徑以 HTTP 200 回應、且頁面標題或主標題以 "Index of /" 開頭時,回報為中風險(CWE-548),因為目錄列表會暴露沒有任何連結指向的檔案,例如備份、匯出檔和舊版本。如果都沒有,檢查即為通過;如果無法連上網站,則回報為未執行。nginx 的修正方法是 autoindex off;(這本來就是預設值,所以要找明確寫出的 autoindex on),Apache 是 Options -Indexes,然後把所有敏感檔案移出網站根目錄。可以用以下指令自行檢查:curl -s https://your-site/uploads/ | head -20
它能發現混合內容和透過 HTTP 送出的表單嗎?
能,針對首頁。它依伺服器回傳的原樣讀取 HTML(不執行 JavaScript),列出 src 或 href 以 http:// 開頭的每個 script、link、iframe 或 img 標籤。只要其中有 .js 或 .css 檔案,結果就是中風險,因為在傳輸途中被替換的指令碼或樣式表會在你的 HTTPS 頁面裡執行;只有圖片和框架為低風險;一個都沒有則通過(CWE-311)。action 以 http:// 開頭的表單回報為高風險(CWE-319),因為在其中輸入的一切,包括密碼,都以明文傳送。修正方法是把這些 URL 改為 https:// 或改成相對路徑,並加上 Content-Security-Policy: upgrade-insecure-requests 回應標頭作為保險。自己檢查:curl -s https://your-site/ | grep -Eo "(src|href|action)=.http://[^ >]*"
它在 robots.txt 和 security.txt 中檢查什麼?
robots.txt:它取得 /robots.txt,若回傳 HTTP 200 且為文字檔,就讀取前 8000 個字元中的 Disallow 行。包含 admin, internal, private, backup, config, staging, test, api, secret, dev 等字的 Disallow 路徑回報為低風險(CWE-200):robots.txt 是公開的,只是請守規矩的爬蟲不要造訪,列出這些路徑等於替它們打廣告。請用登入保護它們,並用 noindex 讓頁面不進入搜尋結果。security.txt:它請求 RFC 9116 規定的位置 /.well-known/security.txt,檔案中有 Contact: 行時計為加分。沒有該檔案不扣分。RFC 9116 也要求 Expires: 欄位,掃描不檢查它,所以兩者都要發布,例如 Contact: mailto:security@your-site, Expires: 2027-06-30T23:00:00Z。自己檢查:curl -s https://your-site/.well-known/security.txt
CAA 檢查看什麼?如何新增 CAA 記錄?
它透過 Cloudflare 的 DNS-over-HTTPS 查詢你輸入的主機名稱的 CAA 記錄(RFC 8659)。找到記錄則檢查通過,證據中最多顯示 5 筆;一筆都沒有則回報 "No CAA record",嚴重程度為低,因為此時任何公開憑證授權單位都能為該名稱簽發憑證。CAA 記錄列出你實際使用的 CA,例如 your-site. IN CAA 0 issue "letsencrypt.org",再加上 0 iodef "mailto:security@your-site" 以接收回報。每個使用的 CA 加一行 issue;若萬用字元憑證要由另一家 CA 簽發,再加一行 issuewild。自行確認:dig CAA your-site
為什麼掃描 www 或子網域時顯示沒有 CAA、SPF 或 DMARC?
每項 DNS 檢查都針對你輸入的確切名稱,所以 www.example.com 以 www.example.com 查詢,而不是 example.com,而這三種記錄的繼承方式各不相同。CAA:憑證授權單位在 www.example.com 找不到 CAA 記錄時,會往上查到 example.com 並使用那裡的記錄(RFC 8659 第 3 節),因此子網域上的 "No CAA record" 可能是誤報。DMARC:收件端會改用組織網域的政策,該政策可以用 sp= 為子網域另行設定(RFC 9989,已取代 RFC 7489),因此 _dmarc.www.example.com 沒有記錄時,通常已由 _dmarc.example.com 涵蓋。SPF:沒有繼承(RFC 7208),所以 "No SPF record" 對該名稱是正確的;不寄信的主機名稱可以發布 v=spf1 -all。DNS 查詢失敗也會顯示為沒有記錄。請一併掃描不含 www 的主網域,或用 dig CAA example.com 和 dig TXT _dmarc.example.com 確認