·7 分鐘IDOR授權實戰
授權漏洞實戰 — URL中的一個數字,打開了全部客戶資料
IDOR是自動掃描工具最難抓到的代表性漏洞之一。實際的攻擊模式,以及在程式碼層級防範的方法。
只是把URL裡的/orders/1042改成/orders/1043,就看得到別人的訂單紀錄——這不是偶然,而是授權(Authorization)漏洞。業界稱之為IDOR(Insecure Direct Object Reference,不安全的直接物件參照),是自動掃描工具最難抓到的漏洞之一。
認證與授權是不同的
能不能登入(認證,Authentication),和登入的人是否有資格查看那份資料(授權,Authorization),是完全不同的問題。大多數服務都會仔細打造登入功能,卻很容易忘記檢查「這個使用者是不是真的擁有這個資源」。
實際上是這樣被攻破的
GET /api/orders/1042 → 我的訂單(正常) GET /api/orders/1043 → 直接看到別人的訂單(有漏洞)
當伺服器程式碼大致長這樣時,就會發生這個問題。
// 有漏洞的程式碼:只用id查詢,沒有確認擁有者
app.get('/api/orders/:id', async (req, res) => {
const order = await db.order.findUnique({ where: { id: req.params.id } });
res.json(order);
});只確認有沒有登入,沒有確認「這筆訂單是不是登入使用者本人的」。 只要依序把數字ID換過一輪,就能瀏覽所有客戶的訂單。
為什麼掃描工具容易漏掉
一般的自動掃描工具擅長抓「這個API是不是回傳200」、「是否有SQL注入」這類模式。但IDOR的回應確實正常地回傳200和有效資料,必須理解「這份資料是誰的」這種商業脈絡,才能發現問題。這需要比單純模式比對更深一層的分析。
修正方法
// 修正:查詢條件務必包含擁有者(userId)
app.get('/api/orders/:id', async (req, res) => {
const order = await db.order.findFirst({
where: { id: req.params.id, userId: req.user.id },
});
if (!order) return res.status(404).end();
res.json(order);
});原則只有一個:「查詢條件永遠要包含目前登入的使用者」。 只要有單靠ID查詢的query,都應該視為可疑對象。
測試方法
最確實的做法是建立兩個帳號,在登入A帳號的狀態下,直接請求B帳號的資源ID。 如果回應是200和正常資料,就代表有問題。回應應該是404或403才正常。
IDOR不需要花俏的駭客技術。只要在瀏覽器網址列改一個數字就能被發現並利用。這正是它更危險的原因。
WhiteHat Code的深度掃描會一併分析程式碼的商業脈絡,找出這類授權缺漏的模式。現在就用免費掃描確認看看。