Skip to content

taipei-doit/townpass2025-url-risk-analyzer

Repository files navigation

詐騙及風險網站檢測微服務

專案簡介 / Project Overview

本專案將原本難取得的網址相關資訊,以簡單易懂的方式公開,並提供判斷依據與詳細資料供民眾查閱。並分析常見詐騙模式並檢測網站流量與連線異常,標示主機所在地與轉向情況,協助民眾快速辨別網址是否可信,給出參考建議。

系統架構 / System Architecture

架構圖

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
Loading

系統架構流程說明

URL 檢測完整流程

系統通過以下步驟進行 URL 的風險檢測:

  1. Frontend → Backend:

    • 使用者於前端介面輸入需檢測的 URL,該介面以 Flutter 構建。
    • 輸入的 URL 透過 HTTP 請求傳送至後端伺服器。
  2. Backend → Cache (Redis):

    • 後端伺服器首先查詢 Redis 快取,看是否已存有該 URL 的檢測結果。
    • 快取命中:直接從 Redis 返回結果。
    • 快取未命中:若無儲存結果,則繼續執行以下步驟。
  3. Backend → WHOIS/DNS:

    • 後端呼叫 WHOIS 資料庫與 DNS 查詢服務,獲取與 URL 關聯的域名註冊及解析資訊。
  4. Backend → phishtank:

    • 使用 phishtank database,檢索已經驗證之釣魚網站。
  5. Backend → ML:

    • 將 WHOIS、DNS 返回的資料輸入機器學習模型。
    • 通過 Random Forest 演算法進行風險評估,產生最終檢測結果。
  6. 結果返回:

    • 檢測結果儲存至 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: 顯示檢測結果
Loading

Cache 策略說明

每一筆 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 檢測完整流程」章節。

使用 Cache 的目的

每次的 URL 檢測需要進行 DNS 查詢、網站請求及機器學習模型推論等步驟,使用者從發出檢測請求至收到 backend 回傳之檢測結果,受到網站回應及模型推論等時長影響,可能需要等待 5 秒以上的回應時長。透過將 Redis 作為 cache 伺服器,可以將回應時長縮短至 1 秒內。

Machine Learning 模型詳細規格

機器學習採用 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 分。

使用到的主要技術堆疊(Tech Stack)

類別 使用技術/版本 備註
Frontend Flutter
Backend Server Python Flask python >= 3.11, flask == 3.1.2
Cache Server Redis redis == 7.1.0
Machine Learning Random Forest 演算法

後端詳細規格

安裝與執行方式 / Installation & Run

Backend service

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

Frontend page

請替換 page/anti_fraud/anti_fraud_view.dart 變數 _apiUrl 為後端 api 地址。

目前分數的邏輯為 第一層檢測(phishing)通過後會(+25);第二層檢測(ML)通過後會(+25);第三層檢測若為政府或學術網站則會無條件設為滿分(100),此層亦會再次分析是否為釣魚網站,若安全則(+35)。
因此,普通安全網站最高分數為85分,而政府及學術網站為100分。
目前分數顯示邏輯為:

分數 提供結果
低於50 高度風險
50~84 建議謹慎
高於85~99 基本安全但建議謹慎
100 政府或學術網站

TODO

  • 新增免責聲明
  • 優化一些交互邏輯
  • 替換分數為較好的抽象化指標

功能說明 / Features

功能編號 功能名稱 簡述 資料來源描述
1 URL 風險檢測 透過機器學習模型、whois 資料庫和第三方檢測服務 phishtank資料庫比對 判斷 URL 的風險,並給出安全建議。 無使用政府資料

服務展示

demo1.webm
demo2

About

【2025臺北秋季程式設計節-城市通微服務大黑客松】第一名得獎團隊:DROP TABLE

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors