[{"content":"情境 在寫單元測試時，想判斷輸入物件的其中一個 property 是特定數值才回傳造假資料。 可以限縮造假的範圍來提高正確性。\n使用 NSubstitute Arg.Is\u0026lt;T\u0026gt; 有條件的比對參數 有個 mail 物件，在寫測試時想造假特定收件人寄送的回傳值。\n1 2 3 4 5 6 public class Mail { public string Recipient { get; set; } public string Subject { get; set; } public List\u0026lt;AttachFile\u0026gt; Attachment { get; set; } } 這時可以使用 Arg.Is\u0026lt;T\u0026gt;(condition) 裡面帶入指定條件，以下範例是當收件人為 Leo 時才回傳造假的結果 true。\n1 _mailService.Send(Arg.Is\u0026lt;Mail\u0026gt;(m =\u0026gt; m.Recipient == \u0026#34;Leo\u0026#34;)).Returns(true); 另外想測試是否有特定參數的呼叫 Received 一次，也可以使用 Arg.Is 去限縮條件。 此例為驗證是否有收件人是 Leo 的 mail 呼叫 Send() 方法。\n1 _mailService.Received(1).Send(Arg.Is\u0026lt;Mail\u0026gt;(m =\u0026gt; m.Recipient == \u0026#34;Leo\u0026#34;)); Reference Argument matchers - Conditionally matching an argument\n","date":"2022-11-13T00:00:00Z","permalink":"/p/unit-test-%E5%9C%A8%E7%89%B9%E5%AE%9A%E5%8F%83%E6%95%B8%E6%A2%9D%E4%BB%B6%E6%99%82%E5%9B%9E%E5%82%B3%E9%80%A0%E5%81%87%E8%B3%87%E6%96%99/","title":"unit test - 在特定參數條件時回傳造假資料"},{"content":" Windows 設定 \u0026gt; 網路和網際網路 \u0026gt; 狀態，點選 \u0026ldquo;變更介面卡選項\u0026rdquo; 找到要修改的網路，右鍵 \u0026gt; 內容 點選設定 進階 \u0026gt; 本地管理位置 \u0026gt; 值，修改成指定的 MAC address 即可 例如 F8:8C:21:77:FB:CB 則填入 F88C2177FBCB 最後再利用指令檢查是否修改完成 (實體位址)\n1 ipconfig /all ","date":"2022-09-19T00:00:00Z","permalink":"/p/%E5%A6%82%E4%BD%95%E5%9C%A8-windows-10-%E4%BF%AE%E6%94%B9-mac-address/","title":"如何在 Windows 10 修改 MAC Address"},{"content":"情境 在寫單元測試時，如果想要針對一個 protected method 做測試時，在測試專案想要存取 method 時會顯示 cannot access protected method 'XXX' here\n一般情況下最好是由呼叫 Protected 的 Public method 去做測試，但如果萬不得已，也有可以對 protected method 進行測試的方法。\nTesting Protected Methods 假設有個 protected method MyMethodName，我們想要對這個 method 進行單元測試。\n1 2 3 4 5 6 public class OriginalClass { protected override string MyMethodName(){ return \u0026#34;any string\u0026#34;; } } 這時可以在測試專案新增一個 FakeClass 去繼承 OriginalClass，並新增一個 method，透過 new 修飾詞隱藏繼承自基底類別的方法，FakeClass 中 method 的實作使用 base 呼叫基底類別原有的方法。\n1 2 3 4 5 6 7 public class FakeClass : OriginalClass { public new string MyMethodName() { return base.MyMethodName(); } } 最後測試時使用 FakeClass 呼叫 MyMethodName 進行測試即可。\nReference 了解使用 Override 和 New 關鍵字的時機\nnew 修飾詞 (C# 參考)\n","date":"2022-09-18T00:00:00Z","permalink":"/p/%E5%A6%82%E4%BD%95%E5%B0%8D-protected-method-%E5%81%9A-unit-test/","title":"如何對 protected method 做 unit test"},{"content":"\n敘述 做完健康檢查後，在網站上登入後查看報告時，發現有個報告書下載的功能。\n下載完成後是一個PDF檔，這時發現下載網址後有個 bid 的參數。\n看起來 bid 的參數是有規律且有序的，此時嘗試修改不同的數值嘗試發起 request，發現可以正常取得 PDF 報告書。\n此存取控制缺陷的漏洞會造成可以取得他人的健檢報告資料。\n相關網址 1 2 https://medirep.mornjoy.com.tw/Login/Index http://medirep.mornjoy.com.tw/siteadmin/Print?bid=_{Id}_ 時間軸 2022/05/30 - 提交漏洞\n2022/06/02 - 通報未回應 (由 HITCON ZeroDay 服務團隊)\n2022/06/07 - 複測已修復 (by Leo)\n2022/07/30 - 公開\n回報於 HITCON ZeroDay：晨悅預防醫學機構 醫療資料存取漏洞\nReference Access control vulnerabilities and privilege escalation | Web Security Academy\n","date":"2022-08-28T00:00:00Z","permalink":"/p/%E6%BC%8F%E6%B4%9E%E5%9B%9E%E5%A0%B1-%E5%81%A5%E6%AA%A2%E4%B8%AD%E5%BF%83%E9%86%AB%E7%99%82%E8%B3%87%E6%96%99%E5%AD%98%E5%8F%96%E6%8E%A7%E5%88%B6%E7%BC%BA%E9%99%B7/","title":"漏洞回報 健檢中心醫療資料存取控制缺陷"},{"content":" 1 2 3 4 5 6 7 8 9 10 interface ITextSummarizer{ string summarizeText(string text); } class TextSummarizer : ITextSummarizer{ string summarizeText(string text){ //do something return \u0026#34;summarize text\u0026#34;; } } 雖然 TextSummarizer 只有一個實作，就算之後不會有另一個實作，加上 interface 也有其他好處。\n定義 interface 的優點： 可以使測試更容易 - 如果要在測試期間使用 mock 或 fake 假的實作，會需要定義一個介面來執行此操作。 讓公用 API 更清晰 - 使用端應該或不應該使用哪些功能不會產生混淆。 有可能猜錯只需要一個實作 - 最初寫程式時可能確定真的不需要第二個實作，但經過一兩個月後，這個假設可能被證明是錯誤的。 同一類別可以解決兩個子問題 - 有時某個類別可以為兩個或多個不同的抽象層提供實作。例如 LinkedList 實作類別可以實作 List 和 Queue 介面。 定義 interface 的缺點： 需要付出更多努力 - 如果沒有 IDE 的幫忙，可能要手動多寫幾行程式碼。 -\u0026gt; 使用 Rider 自動產生 Interface Reference Good Code, Bad Code｜寫出高品質的程式碼 PART 1 理論篇 - 第2章 抽象層\n","date":"2022-08-07T00:00:00Z","permalink":"/p/why-add-interface/","title":"所有的 Class 都要加 Interface 嗎?"},{"content":"[Windows] 透過 Scoop 安裝：\n1 scoop install hugo Hugo start： https://gohugo.io/getting-started/quick-start/\nTheme： https://github.com/CaiJimmy/hugo-theme-stack\nRun server (include content marked as draft)\n1 hugo server -D -p 8888 ","date":"2022-07-31T00:00:00Z","image":"/p/hugo-start/hugo-logo.svg","permalink":"/p/hugo-start/","title":"Hugo start"},{"content":" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 interface IAlertService { void SendAlert(string message) } public class SlackAlertService : IAlertService { public void SendAlert(string message){} } public class TelegramAlertService : IAlertService { public void SendAlert(string message){} } 假如有個 TestAlertService 需要同時使用到 SlackAlertService 和 TelegramAlertService ，在使用 autofac 注入時因為兩個 service 都使用相同的介面，這個時候可以透過加上 KeyFilter attribute 的方式來指定所需要的實體。\nKeyFilter 的使用方式：\n1 2 3 4 5 6 public class TestAlertService : IAlertService { public TestAlertService([KeyFilter(\u0026#34;slack\u0026#34;)] IAlertService slackAlert, [KeyFilter(\u0026#34;telegram\u0026#34;)] IAlertService slackAlert){ ... } } 在註冊時需要透過設定好的 key 去指定相對應的實作，以及設定哪個類別要使用 attribute filter：\n1 2 3 4 builder.RegisterType\u0026lt;SlackAlertService\u0026gt;().Keyed\u0026lt;IAlertService\u0026gt;(\u0026#34;slack\u0026#34;); builder.RegisterType\u0026lt;TelegramAlertService\u0026gt;().Keyed\u0026lt;IAlertService\u0026gt;(\u0026#34;telegram\u0026#34;); builder.RegisterType\u0026lt;TestAlertService\u0026gt;().As\u0026lt;IAlertService\u0026gt;().WithAttributeFiltering(); 參考資料：[Autofac] resolving with attributes\n","date":"2022-07-22T00:00:00Z","permalink":"/p/autofac-keyfilter-attribute/","title":"使用 Autofac KeyFilter Attribute 在相同介面注入不同實體"},{"content":"on Windows 2012 (IIS 8)\n選擇想要檢視的 IIS Worker Process\n切到 detail 查看該 process 的 PID\n切換到 C:\\Windows\\System32\\inetsrv ，執行 .\\appcmd.exe list wp 找到對應的 PID\n","date":"2021-09-02T00:00:00Z","permalink":"/p/%E5%A6%82%E4%BD%95%E6%9F%A5%E8%A9%A2-w3wp.exe-%E5%B0%8D%E6%87%89%E7%9A%84-iis-application-pool/","title":"如何查詢 w3wp.exe 對應的 IIS Application Pool"},{"content":"某天逛 Facebook 突然發現有個「中文化電子郵件信箱體驗活動」，只要動動手指就可以體驗看起來很狂的中文信箱地址，而且還附贈該中文網域名稱一年，就趕緊就來申請囉。\n在經過很多步驟和教學後，終於拿到了成功獲得域名通知信，信中給了個連結可以設定管理網域的判別密碼。\n可以看到設定判別密碼的網址帶了兩個參數 key 及 dn，key 是一串亂碼，而 dn 則是個人中文網域名稱 (灰色方塊部分)。\n-\u0026gt;透過此網址可重複修改密碼\n接著就收到一封邀請好友的信件，點擊信中連結輸入好友 Gmail 信箱，成功推廣可以有抽獎點數。\n但點進去推廣頁面，看了網址所帶的參數覺得怎麼有種似曾相識的感覺？\n推廣頁面和設定密碼的頁面所使用的 key 竟然是同一把！\n如果任何人知道你的中文網域名稱及邀請頁面連結，代入 KEY 及 網域名稱 到設定密碼頁面，即可修改他人的判別密碼。\nhttps://rs.twnic.net.tw/cgi-bin/eai/chgpass.cgi?key= {KEY} \u0026amp;dn= {網域名稱}.台灣\n用修改後的密碼登入就可以取得原域名擁有者的所有權限，可以更改 DNS 設定、查看或修改個人資料等等。\n如果你公布了你的網域名稱，順便附上信中的推廣連結，等於是告訴人：來吧，可以幫我改密碼喔。\n為了避免關鍵 key 外流，我推廣好友自己打 Gmail 信箱總安全了吧，這樣想就大錯特錯了！\n就算自己打信箱推廣，被推廣好友所收到確認信所含連結也有那把可以重設密碼的 key (右下黃色區塊)。總之，如果要推廣好友，絕對不能把我的網域名稱告訴他人，不然他就能幫忙改密碼並接管自己的個人網域了。\n-\u0026gt;同一人所發出邀請 key 皆相同，參數 rec 不同被推廣者皆不相同。\n之後把情況詳情回報給台灣網路資訊中心，當天幾小時後重設密碼的頁面就自動跳轉到 https://rs.twnic.net.tw/cgi-bin/eai/chgpass.cgi 乾淨的網址，改成用 Form Data 的形式送出 key \u0026amp; dn，暫時先改變資料送出的形式，把漏洞變得比較不明顯。\n幸好隔天重設密碼的流程就換了，改成只回傳一個\u0026lt;script\u0026gt; alert，提示至信箱確認變更密碼連結，他人就不再能簡單取得個人網域權限了，當天的修改貌似只是不想讓更多人能一眼就發現並使用這個漏洞。\n設定密碼的頁面所使用的 key (灰色部分) 終於不是那組連推廣都共用的那把了。\n查了一下此活動開始也有一段時間了，不過看起來還沒有人發現。為了避免更多資料外洩，當天即送出了問題回報，他們也非常快速的解決了問題，在隔天即修復完成。除了讓人佩服工程師的努力外，正面面對漏洞修補的態度也值得讚賞。\n這個問題的根本原因就是重設密碼所用的 token 也被其他服務所使用，而該推廣中文域名活動的服務剛好會讓 token 流出給第三者，而讓外人可以輕易取得域名管理權限。\n其實只要多留意並不難發現這個漏洞，但它還是存在了幾個禮拜的時間，這也說明了網路上並不是沒有漏洞，而是缺少發現。身為使用者可以多仔細觀察，協助政府或企業發現問題。而開發者則要注意並不是使用亂數當 token 就安全，也要注意在設定密碼這種比較敏感的服務和其他一般服務所使用的 token 必須要有所區隔。\n時間軸：\n2017/3/30：漏洞詳情回報給財團法人台灣網路資訊中心 2017/3/31：修復了此漏洞 本文同步刊載於 HITCON Knowledge Base in 2017.04\n","date":"2021-03-10T00:00:00Z","permalink":"/p/%E5%8F%B0%E7%81%A3%E7%B6%B2%E8%B7%AF%E8%B3%87%E8%A8%8A%E4%B8%AD%E5%BF%83-%E5%9F%9F%E5%90%8D%E7%AE%A1%E7%90%86%E9%97%9C%E9%8D%B5-key-%E5%85%B1%E7%94%A8%E6%BC%8F%E6%B4%9E/","title":"台灣網路資訊中心 域名管理關鍵 Key 共用漏洞"}]