為什麼忘記密碼時只能重設,不把舊密碼告訴我?

2021-07-09 作者: Huli 原文 #medium 的其它文章

為什麼忘記密碼時只能重設,不把舊密碼告訴我? ——

Photo by FLY:D on Unsplash

某天小明在整理他的我的最愛(到底誰的),發現了一個以前很常逛,但已經將近半年多沒去的一個論壇。小明想回去看看那邊變得怎麼樣了,於是點進去那個論壇,輸入了帳號密碼,得到了密碼錯誤的回覆。

嘗試了幾次之後,系統提示小明可以使用「忘記密碼」的功能,所以小明填了自己的 email 之後去信箱收信,發現系統傳來一個「重設密碼」的連結。雖然說最後小明成功利用重新設定的密碼登入,但有個問題讓他百思不得其解:

「奇怪欸,幹嘛要我重設密碼,為什麼不把舊的密碼寄給我就好?」

應該有許多人都跟小明一樣,有過類似的疑惑。把舊密碼寄給我不是很好嗎,幹嘛強迫我換密碼?

這一個看似簡單的問題,背後其實藏了許多資訊安全相關的概念,就讓我們慢慢尋找問題的答案,順便學習一些基本的資安知識吧!

先提醒一下,雖然說前半段看起來可能跟文章主題無關,但好酒沉甕底,我保證最後會把這些東西關聯起來。

被偷走的資料庫

大家應該很常看到新聞說哪個網站的資料又被偷走了,顧客個資全部都外洩出去。例如說麥當勞在近期就發生了類似的事件:

麥當勞資料外洩的通知信

這邊我想帶大家探討的兩個問題是:

  1. 資料真的這麼容易外洩嗎?
  2. 資料外洩之後,可能造成什麼後果?

我們先來看第一個問題,有很多安全性的漏洞可以造成資料外洩,而有些漏洞的攻擊方式,比你想的還簡單一百倍。

Photo by Arget on Unsplash

你想像中的駭客可能像上面那樣,打著一大堆不知道在幹嘛的指令,畫面上出現很多黑底白字或是綠字的畫面,完全搞不懂在幹嘛,但是做著做著網站就被打下來了。

而事實上有些漏洞,可能在網址列上面改幾個字就攻擊成功了,就算你不懂任何程式也做得到。

舉例來說好了,假設今天有個購物網站,你買了一些東西之後送出訂單,訂單成立後跳轉到訂單頁面,上面有著一大堆你的個資,例如說:姓名、收貨地址、聯絡電話以及 Email 等等。

然後你發現訂單頁面的網址是 https://shop.huli.tw/orders?id=14597

而正好你的訂單編號也是 14597,在好奇心的驅使之下,你就試著把數字改成 14596,然後按下 Enter。

當網站載入完成之後,你竟然還真的能看到編號為 14596 的訂單,上面出現一個你不認識的人的姓名、收貨地址、聯絡電話跟 Email。

有些攻擊就是這麼樸實無華且枯燥,只要改個字就能看到屬於其他人的資料。這時候如果你會寫程式的話,就可以寫個腳本自動去抓 id 是 1 一直到 id 是 15000 的資料,你就拿到了這個購物網站 15000 筆訂單的資訊,也就是一萬多個顧客的個資。

這過程中沒有什麼黑底白字的畫面,也不用一直瘋狂打字,唯一需要的只有改數字,個資就輕鬆到手。

這類型的漏洞有個專有名詞,稱為 IDOR,全名是:Insecure direct object references,大約就是不安全的直接資料存取的意思。漏洞產生的原因就是工程師在開發時,並沒有注意到權限控管,因此讓使用者能存取到其他人的資料。

有些人看到這邊可能以為我只是為了文章淺顯易懂,所以才舉一個簡化的例子,現實生活中的攻擊才沒這麼簡單。

這句話算是對了一半,大部分的網站確實都不會有這麼明顯的一個漏洞,攻擊方式會更複雜一點。但可怕的是,還真的有些網站就是這麼簡單,就是改個數字就可以拿到別人的資料。

台灣有一個網站叫做 HITCON ZeroDay,是由台灣駭客協會所維護的漏洞回報平台。有些人發現漏洞之後可能會竊取個資拿去賣,從事非法行為,也有些人發現漏洞只是為了鍛鍊技術,並沒有想要做什麼壞事。

因此就可以透過這個平台進行回報,回報漏洞之後負責維護平台的志工們會幫你驗證漏洞,驗證過後回報給負責的廠商,讓他們去修復漏洞。

這個平台上的漏洞在修復過後隔一陣子會公開,或者儘管廠商沒有回報修復,過一陣子(例如說兩個月)後也會公開,因此在這平台上可以找到許多公開的漏洞,看過之後你大概就不會想在網站註冊時留下真實個資了…

例如說這兩個就是 IDOR 的真實漏洞:

  1. 享健身xarefit 任意訪問/下載所有會員個資
  2. DoorGods 防疫門神實聯制系統IDOR導致個資外洩

對,不要懷疑,就真的只是在網址上改個數字而已這麼容易。

以後只要看到網址列上有這種數字,就可以試著去改改看,搞不好不會寫程式的你也可以發現 IDOR 的漏洞。

除了這種只要改個東西的漏洞之外,還有另外一個很常見但是需要一點技術能力才能攻破的漏洞,叫做 SQL Injection。

先來講講 SQL 是什麼,簡單來說就是跟資料庫查詢東西的一種程式語言。既然說是語言那就會有固定語法,若是以中文舉例,大概就像是:

去找「訂單資料」,給我「id 是 1 的」,按照「建立時間」排序

用「」框起來的部分代表可以變動,而其他關鍵字例如說「去找」、「給我」這些都是固定的,因為語法要固定才能寫程式去解析。

同樣以上面假想的購物網站為例,如果網址是 https://shop.huli.tw/orders?id=14597,那網站去跟資料庫拿資料時,指令大概就是:

去找「訂單資料」,給我「id 是 14597 的」

因為網址列上的 id 是 14597 嘛,所以這個 id 就會被放到查詢的指令去,如果 id 是別的,那查詢的指令也會不一樣。

這時候如果我的 id 不是數字,而是「1 的順便給我使用者資料」,查詢就變成:

去找「訂單資料」,給我「id 是 1 的順便給我使用者資料」

那整個網站的使用者資料就順便被我抓下來了。

這個攻擊之所以叫做 SQL injection,重點就在於那個 injection,攻擊者「注入」了一段文字被當作指令的一部分執行,所以攻擊者就可以執行任意查詢。

比起上面講的 IDOR,SQL injection 通常會更為致命,因為不只是訂單資料本身,連其他資料也會被一起撈出來。所以除了訂單資料,會員資料跟商品資料都有可能一起外洩。

這邊也隨便找兩個公開的案例:

  1. 北一女中網站存在SQL Injection漏洞
  2. 桃園高中 網站 SQL injection

而防禦方式就是不要把使用者輸入的「1 的順便給我使用者資料」直接當作指令,而是經過一些處理,讓整段查詢變成:「給我 id 是:『1 的順便給我使用者資料』的資料」,那因為沒有這個 id,所以什麼事也不會發生。

個資洩漏了,然後呢?

前面我們已經看到了針對那些沒有做好防禦的網站,個資外洩是多麽容易的一件事情。

那個資洩漏之後,對使用者會有什麼影響呢?

大家最感同身受的應該就是詐騙電話吧,例如說某些買書的網站或是訂房網站,打過來跟你說什麼要分期退款,為了博取你的信任,連你買了哪本書,訂了哪個房間,或是你家地址跟姓名全都講得出來。

這些都是因為資料外洩的緣故,詐騙集團才會知道的這麼清楚。

但除了這些個資以外,還有兩個東西也會外洩,那就是你的帳號跟密碼。

也許你會想說:「不就帳號跟密碼嗎,我就在那個網站上面改密碼以後再用就好啦!」

事情也許沒有你想的這麼簡單。如果你沒有用密碼管理軟體的話,我大膽猜測你所有的密碼可能都是同一組。因為怕記不起來嘛,所以乾脆都用同一組密碼。

這時候如果帳密外洩,駭客是不是就可以拿這組帳密去其他服務試試看?

拿去登你的 Google,登你的 Facebook,這時候用同一組密碼的人就會被登進去。所以從表面看只是一個購物網站被入侵,但造成的結果卻是你的 Google 還有 Facebook 也一起被盜了。

所以,有時候某個網站被盜帳號可能不是那個網站的問題,而是駭客在其他地方拿到了你的帳號密碼,就來這邊試試看,沒想到就中了。

對於網站的開發者而言,保護好使用者的個資是天經地義的事情,保護密碼也是,有沒有什麼好方法可以保護密碼呢?

加密嗎?把密碼用某些演算法加密,這樣資料庫儲存的就會是加密後的結果,儘管被偷走了,駭客只要沒有解密的方法就解不開。

聽起來似乎是最安全的做法了,但其實還有一個問題,那就是網站的開發者還是會知道怎麼解密,如果有工程師監守自盜怎麼辦?他還是可以知道每個使用者的密碼是什麼,可以把這些資訊拿去賣或者是自己利用。

嗯…似乎我們也不能怎麼樣,因為無論如何,開發者都需要有方法知道資料庫存的密碼究竟是多少吧?不然在登入的時候怎麼確認帳號密碼是對的?

再者,這樣聽起來應該夠安全了,要怎麼樣才能更安全?難道要連網站的開發者都無法解密,都不知道密碼是什麼才夠安全嗎?

Bingo!答對了,就是要這樣沒錯!

沒有人知道你的密碼,包括網站本身

事實上,網站的資料庫是不會儲存你的密碼的。

或更精確地說,不會儲存你的「原始密碼」,但會儲存密碼經過某種運算後的結果,而且最重要的是,這個運算是無法還原的

直接舉例比較快,假設今天有個很簡單的演算法,可以把密碼做轉換,轉換方式是:「數字不做轉換,英文字母把 a 換成 1,b 換成 2…z 換成 26」,以此類推,第幾個字母就換成幾,大小寫不分都一樣(先假設不會有符號)。

如果密碼是 abc123,轉換完就變成 123123。

在使用者註冊的時候,網站就把使用者輸入的 abc123 轉成 123123,然後存到資料庫裡面。因此資料庫存的密碼是 123123,而不是 abc123。

當使用者登入時,我們就再把輸入的值用同樣的邏輯轉換,如果輸入一樣,轉換後的結果就會一樣對吧?就知道密碼是不是正確的。

當駭客把資料庫偷走以後,會拿到 123123 這組密碼,那一樣啊,不是可以推論出原本是 abc123 嗎?不不不,沒這麼簡單。

123123、abcabc、12cab3…這些密碼轉換之後,不也是 123123 嗎?所以儘管知道轉換規則跟結果,卻沒有辦法還原成「唯一一組密碼」,這就是這個演算法厲害的地方!

這樣的轉換就叫做雜湊(Hash),abc123 每次 hash 過後的結果都會是 123123,但是從 123123 卻無法推回輸入一定是 abc123,因為有其他種可能性存在。

這就是 hash 跟加密最大的不同。

加密跟解密是成對的,如果可以加密就一定可以解密,所以你知道密文跟密鑰,就可以知道明文。但 hash 不同,你知道 hash 的演算法跟結果,卻無法回推出原本的輸入是什麼。

而這個機制最常見的應用之一,就在於密碼的儲存。

在註冊時把 hash 過後的密碼存進資料庫,登入時把輸入的密碼 hash 過後跟資料庫比對,就知道密碼是否正確。就算資料庫被偷,駭客也不知道使用者的密碼是什麼,因為回推不出來。

這就是為什麼忘記密碼的時候,網站不會跟你講原本的密碼是什麼,因為網站本身也不知道啊!

所以不能「找回密碼」,只能「重設密碼」,因為重設就代表你輸入新的密碼,然後網站把新的密碼 hash 之後存進資料庫,未來登入時就會用這組新的 hash 去比對。

有些人可能會注意到這樣的儲存方式似乎有個漏洞,延續前面的例子,資料庫存的是 123123 而我的原始密碼是 abc123,這樣如果用「abcabc」,hash 過後也是 123123,不就也可以登入嗎?這樣不太對吧,這不是我的密碼欸

有兩個不同的輸入卻產生出同一組輸出,這種狀況稱為碰撞(hash collision),碰撞一定會發生,但如果演算法設計的好,碰撞的機率就超級無敵小,小到幾乎可以忽略。

前面提的轉換規則只是為了方便舉例,真實世界中用的演算法複雜許多,就算只有一個字不同,結果都會天差地遠,以 SHA256 這個演算法為例:

  1. abc123 => 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090
  2. abc124 => cd7011e7a6b27d44ce22a71a4cdfc2c47d5c67e335319ed7f6ae72cc03d7d63f

類似的輸入卻產生截然不同的輸出。

像我前面舉例用的轉換就是不安全的 hash 演算法,要盡量避免使用或是避免自己設計,盡可能使用密碼學家跟專家設計出的演算法,像是上面提到的 SHA256。

結語

忘記密碼時網站不會把密碼寄給我,因為網站自己都不知道我的密碼是什麼。雖然聽起來不太可能,但實際狀況就是如此。為了安全性,這是必須的手段。

要達成這樣的目的,背後最重要的技術原理就是 hash,「同樣的密碼會產生同樣的 hash 值,但從 hash 值沒辦法對應回原本的密碼」就是秘訣所在。

反之,如果你發現有網站可以找回你的密碼,那就得要多加注意,有可能網站資料庫存的不是 hash 值而是你的密碼。在這種狀況下,萬一有天資料庫被入侵,帳密被偷走,駭客就能得知你真實的密碼,然後去試其他的服務。

有關於密碼管理,現在瀏覽器也有功能可以自動幫你產生密碼外加記憶密碼,或也可以使用現成的密碼管理軟體,都可以在不同網站產生不同的密碼。

還有一點要注意,那就是並不是存 hash 值就絕對安全了。前面有提過同樣的輸入會產生同樣的結果,因此有心人可以先把常見密碼的 hash 值都算出來,例如說上面算過的 abc123 hash 過後是 6ca13d52ca70c883e0f0bb101e425a89e8624de51db2d2392593af6a84118090,只要把這個對應關係存起來,駭客看到這一大串 hash 就會知道對應的可能性之一是 abc123,就可以去嘗試這組密碼。

至於要怎麼防禦這類的攻擊,就又有其他的防禦方式,礙於篇幅這篇就先不提了,想知道更多可以參考這篇:[資訊安全] 密碼存明碼,怎麼不直接去裸奔算了?淺談 Hash , 用雜湊保護密碼

這篇希望能讓對這個領域陌生的讀者們也能知道一些基本的概念,包括:

  1. 有些網站比你想得脆弱很多,改個網址就可以拿到別人的資料
  2. 對於安全性做得不好的網站,拿到整個資料庫不是一件難事
  3. 忘記密碼只能找回,是因為網站也不知道你的密碼
  4. 如果有網站可以把舊密碼給你,那你得要小心一點

為什麼忘記密碼時只能重設,不把舊密碼告訴我? was originally published in Cymetrics Tech Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.


文章版权归原作者所有。
二维码分享本站