iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
AI Security

30 天打造 AI 輔助 SOC 資安事件分析平台系列 第 14 篇

Day 14|事件搜尋:從大量 SOC Event 找到需要的資料

  • 分享至 

  • xImage
  •  

前幾天已經完成事件解析、欄位標準化以及 Severity 的基本分類。不過,隨著 Security Event 數量增加,如果只能從 Dashboard 的表格中逐筆查看資料,實際使用上會相當不方便。
因此今天開始加入事件搜尋功能,希望可以透過 Event Type、IP、Protocol 或 Signature 等資訊,快速找到需要進一步分析的事件。

建立 Search API

今天在 FastAPI 中新增:

GET /events/search

並使用 Query Parameter 接收搜尋關鍵字。例如:

/events/search?q=Network

Backend 收到關鍵字後,會透過 SQLite 搜尋欄位:

event_type
src_ip
dest_ip
protocol
signature

實際搜尋 Network 後,可以成功找到先前建立的 Network Scan 測試事件。
修改 main.py
https://ithelp.ithome.com.tw/upload/images/20260928/20177754l5P7UANgdZ.png
重新啟動 FastAPI
於 FastAPI 新增 Security Event Search API
https://ithelp.ithome.com.tw/upload/images/20260928/201777542jOMR6fHeY.png
搜尋 Network
https://ithelp.ithome.com.tw/upload/images/20260928/20177754dk0CU84p0P.png
再測 IP 搜尋同樣找到Network Scan,因為我們的 SQL 不只搜尋 event_type,還搜尋src_ip、dest_ip、protocol、signature
https://ithelp.ithome.com.tw/upload/images/20260928/20177754TY7VogUZ4q.png
Login 找到 Login Attempt
https://ithelp.ithome.com.tw/upload/images/20260928/20177754AUdQqKmmXy.png

使用參數化查詢

今天在 SQLite 搜尋時,沒有直接將使用者輸入拼接到 SQL 指令,而是使用參數化查詢:

rows = conn.execute("""
    SELECT * FROM events
    WHERE event_type LIKE ?
       OR src_ip LIKE ?
       OR dest_ip LIKE ?
       OR protocol LIKE ?
       OR signature LIKE ?
""", (
    keyword,
    keyword,
    keyword,
    keyword,
    keyword
)).fetchall()

除了程式比較容易維護之外,也可以避免直接將外部輸入組合進 SQL 指令,降低 SQL Injection 等不必要的風險。

將搜尋功能加入 Dashboard

完成 Backend Search API 後,我進一步在 React Dashboard 加入搜尋框。
當使用者輸入:Network
React 會呼叫:

GET /events/search?q=Network

FastAPI 再從 SQLite 搜尋符合條件的 Event,最後將結果回傳給 React。
整體流程為:

使用者輸入 Network
        ↓
React Search Box
        ↓
GET /events/search?q=Network
        ↓
FastAPI
        ↓
SQLite
        ↓
找到 Network Scan
        ↓
React 顯示搜尋結果

在App.jsx新增 search state

const [events, setEvents] = useState([]);
// 加入
const [search, setSearch] = useState("");

建立搜尋函式
在useEffect後面加入:

const searchEvents = () => {
  if (search.trim() === "") {
    fetch("http://127.0.0.1:8000/events")
      .then((response) => response.json())
      .then((data) => setEvents(data));

    return;
  }

  fetch(
    `http://127.0.0.1:8000/events/search?q=${encodeURIComponent(search)}`
  )
    .then((response) => response.json())
    .then((data) => {
      setEvents(data.results);
    })
    .catch((error) => {
      console.error("Search error:", error);
    });
};

加入搜尋框

<h2>Recent Security Events</h2>
// 加入搜尋框
<div className="search-box">
  <input
    type="text"
    placeholder="Search event, IP, protocol..."
    value={search}
    onChange={(e) => setSearch(e.target.value)}
  />

  <button onClick={searchEvents}>
    Search
  </button>
</div>

在nano src/App.css加 CSS
https://ithelp.ithome.com.tw/upload/images/20260928/20177754ZNeT2KFteo.png
測試 Dashboard 搜尋

npm run dev -- --host 0.0.0.0

https://ithelp.ithome.com.tw/upload/images/20260928/20177754Xeai417HIe.png


上一篇
Day 13|Severity 分類:區分一般事件與資安告警
下一篇
Day 15|事件統計:從單筆 Event 到整體 SOC 狀況
系列文
30 天打造 AI 輔助 SOC 資安事件分析平台 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言