本專案將原本難取得的網址相關資訊,以簡單易懂的方式公開,並提供判斷依據與詳細資料供民眾查閱。並分析常見詐騙模式並檢測網站流量與連線異常,標示主機所在地與轉向情況,協助民眾快速辨別網址是否可信,給出參考建議。
flowchart LR
%% Nodes
User([User])
front[Frontend]
back[Backend Server]
subgraph Data_Layer [Data & Processing]
direction TB
redis[(Redis Cache)]
whois[(Whois DB)]
ml{{ML Model}}
phishtank[(Phishtank DB)]
end
%% Edge Connections
User <--> front
front <--> back
back <--> redis
back <--> whois
back <--> ml
back <--> phishtank
系統通過以下步驟進行 URL 的風險檢測:
-
Frontend → Backend:
- 使用者於前端介面輸入需檢測的 URL,該介面以 Flutter 構建。
- 輸入的 URL 透過 HTTP 請求傳送至後端伺服器。
-
Backend → Cache (Redis):
- 後端伺服器首先查詢 Redis 快取,看是否已存有該 URL 的檢測結果。
- 快取命中:直接從 Redis 返回結果。
- 快取未命中:若無儲存結果,則繼續執行以下步驟。
-
Backend → WHOIS/DNS:
- 後端呼叫 WHOIS 資料庫與 DNS 查詢服務,獲取與 URL 關聯的域名註冊及解析資訊。
-
Backend → phishtank:
- 使用 phishtank database,檢索已經驗證之釣魚網站。
-
Backend → ML:
- 將 WHOIS、DNS 返回的資料輸入機器學習模型。
- 通過 Random Forest 演算法進行風險評估,產生最終檢測結果。
-
結果返回:
- 檢測結果儲存至 Redis 快取,以加速後續查詢。
- 後端伺服器最後將檢測結果返回至前端,提供給使用者。
- Frontend:
- 使用者的互動介面,負責收集輸入的 URL 及顯示檢測結果。
- Backend:
- 核心的邏輯處理模組,負責與快取、外部服務及機器學習模型互動。
- Redis:
- 暫存檢測結果,以提高後續查詢的回應速度。
- WHOIS & DNS:
- 提供域名註冊與 DNS 資訊,用於風險分析的基礎數據。
- phishtank database 本地資料庫比對:
- 檢測 URL 的地理位置及網絡安全相關資料。
- ML 引擎:
- 利用訓練後的機器學習模型進行 URL 的風險評估。
主要的資料流向如下: 使用者 → 前端 → 後端 → (快取/WHOIS/DNS/phishtank) → 機器學習 → 返回快取 → 後端 → 前端 → 使用者
以下以 Sequence Diagram 示意 URL 檢測的流程:
sequenceDiagram
participant User
participant Frontend
participant Backend
participant Redis
participant WHOIS
participant phishtank
participant ML
User->>Frontend: 輸入 URL
Frontend->>Backend: 提交 URL 請求
Backend->>Redis: 查詢快取
alt 快取命中
Redis->>Backend: 返回檢測結果
else 快取未命中
Backend->>WHOIS: 獲取 WHOIS 資料
Backend->>phishtank: 查詢已確認的釣魚網頁
Backend->>ML: 進行風險評估
ML->>Backend: 返回風險評估結果
Backend->>Redis: 儲存檢測結果至快取
end
Backend->>Frontend: 返回檢測結果
Frontend->>User: 顯示檢測結果
每一筆 cache 資料以檢測 URL 作為 key,將檢測結果從 JSON 格式轉換至字串後,作為對應的 value 儲存。下方為 cache 資料的範例:
| Key | Value |
|---|---|
| https://example.com | [{"phishtank":"safe"},{"MLtest":"safe"},{"domain_age_days":9500,"registrar":"IANA","is_new_domain":false},{"ServerLocation":"United States"}] |
每一筆 cache 資料預設存在時間為 1 小時,可透過修改 backend/app.py 當中的 save_cache 函式修改資料存在時長。 Cache 存在時間可視實際服務使用多寡狀況進行調整,例如在服務用量大的情形,可以適當增長存在時間,以減輕服務後端檢測壓力。但不建議設定長於 1 天,因為同一個 domain 對應到的網站可能改變 (改變頻率取決於服務供應商)。
Cache 命中與未命中流程參閱「系統架構流程說明」的「URL 檢測完整流程」章節。
每次的 URL 檢測需要進行 DNS 查詢、網站請求及機器學習模型推論等步驟,使用者從發出檢測請求至收到 backend 回傳之檢測結果,受到網站回應及模型推論等時長影響,可能需要等待 5 秒以上的回應時長。透過將 Redis 作為 cache 伺服器,可以將回應時長縮短至 1 秒內。
機器學習採用 RandomForest 模型,模型的參數設定如下
- n_estimators=200,
- 使用 200 顆決策樹
- max_depth=None,
- 不限制樹的最大深度
- n_jobs=-1,
- 使用電腦所有 CPU 進行平行運算
- random_state=42,
- 隨機樹種子,確保每次的執行結果都一樣
- class_weight="balanced"
- 模型會自動根據輸入資料計算權重,給予數量較少的類別較高的權重
資料集來自開源的UC Irvine Machine Learning Repository。訓練時使用的特徵包含
- having_IP_Address: url domain 部分是否為 ip 格式 (ex. 140.115.41.42)
- URL_Length: url 的長度
- Shortining_Service: url 是否為縮網址
- having_At_Symbol: url 中是否含有
@符號 - double_slash_redirecting: 是否使用
//redirect - Prefix_Suffix1: domain 中有沒有使用符號
- - having_Sub_Domain: sub domain 的數量
- SSLfinal_State: 網站有沒有使用 https、https 憑證的取得時長
- Domain_registeration_length: domain 名稱的註冊時間
- Favicon: 網站 icon 的來源 domain 是否和 url 的 domain 相同
- port: 特定 port 的狀態為開啟/關閉
- HTTPS_token: domain 出現字串 http
- Request_URL: 網頁內部各個資源的連結不和網頁 domain 相同的比例
- URL_of_Anchor: tag
<a>中的 url 和本身 domain 不同的比例 - Links_in_tags:
<Meta>、<script>和<link>和網頁本身同 domain 的比例 - SFH: Server Form Handler 包含空字串或
about:blank - Submitting_to_email: 使用
mail()或mailto處理使用者提交表單中的個人資訊 - Abnormal_URL: host 名稱不在 url 中
- Redirect: redirect 的次數
- on_mouseover: 是否用 onMouseOver 來更改 status bar
- RightClick: 有沒有禁止使用右鍵
- popUpWidnow: 是否有彈出對話框要修使用者輸入個人資訊
- Iframe: 有沒有使用 iframe 這個 tag
- age_of_domain: domain 的擁有時間
- DNSRecord: domain 是否有 DNS record
詳細參數的定義,請參考開源資料集下載後提供的說明文件 Phishing Websites Features.docx
模型放置在 backend\Training Dataset.arff 路徑,載入模型僅需執行下面指令
import joblib
model = joblib.load("phishing_model.joblib")使用模型進行預測的程式範例
# model 為載入後的模型
# sample 一次可以放多個 url 的 features 的格式為 [ [feat1, feat2, ...], [feat1, feat2, ...] ]
# y_probe 為模型預測結果,格式為 [[不是釣魚網址的機率,是釣魚網址的機率], [不是釣魚網址的機率,是釣魚網址的機率], ...]
y_probe = model.predict_proba(sample)在我們使用的測試集中,我們的模型表現 accuracy 為 0.9534147444595206
當模型輸出是釣魚網址的機率大於 50% 我們就判定為 unsafe,反之為 safe,如果預測為 safe,前端計算的 score 增加 25 分。
| 類別 | 使用技術/版本 | 備註 |
|---|---|---|
| Frontend | Flutter | |
| Backend Server | Python Flask | python >= 3.11, flask == 3.1.2 |
| Cache Server | Redis | redis == 7.1.0 |
| Machine Learning | Random Forest 演算法 |
cd backend
docker build -t townpass-backend .
# assuming Redis is running at localhost:6379, for full deployment guide see backend/DEPLOYMENT.md (including Redis, network and backend setup)
docker run -d -p 8001:8001 -e REDIS_HOST=host.docker.internal townpass-backend
請替換 page/anti_fraud/anti_fraud_view.dart 變數 _apiUrl 為後端 api 地址。
目前分數的邏輯為 第一層檢測(phishing)通過後會(+25);第二層檢測(ML)通過後會(+25);第三層檢測若為政府或學術網站則會無條件設為滿分(100),此層亦會再次分析是否為釣魚網站,若安全則(+35)。
因此,普通安全網站最高分數為85分,而政府及學術網站為100分。
目前分數顯示邏輯為:
| 分數 | 提供結果 |
|---|---|
| 低於50 | 高度風險 |
| 50~84 | 建議謹慎 |
| 高於85~99 | 基本安全但建議謹慎 |
| 100 | 政府或學術網站 |
TODO
- 新增免責聲明
- 優化一些交互邏輯
- 替換分數為較好的抽象化指標
| 功能編號 | 功能名稱 | 簡述 | 資料來源描述 |
|---|---|---|---|
| 1 | URL 風險檢測 | 透過機器學習模型、whois 資料庫和第三方檢測服務 phishtank資料庫比對 判斷 URL 的風險,並給出安全建議。 | 無使用政府資料 |
demo1.webm |
|
