序言
去年年底閑來幾天,有位同事專門在網上找一些注冊型的app和網站,研究其短信接口是否安全,半天下來找到30來家,一些短信接口由於分析難度原因,沒有繼續深入,但差不多挖掘到20來個,可以肆意被調用,雖然不能控制短信內容,但可以被惡意消耗,或者用於狂發信息給那些不喜歡的人。
漏洞分析
短信接收方無法約束
由於是注冊型接口,接收方往往都是平台內不存在的手機號,所以無法約束。
接口請求方無法約束
由於是http(s)接口,任何人都可以請求,只要簡單分析你的接口。
調用頻次無法約束
一般的,接口開發者可能會想到通過抓取接口請求者的ip,進行頻次約束,但實現是,他們拿到只是請求者的公網ip,有可能一個體量很大的局域網用戶,接口開發者抓取到的都是他們的同一個公網ip,所以通過ip約束在很多場景下是不能使用的。
漏洞原因
原因其實很簡單,接口開發者無法知道哪些請求是合理的,有些請求是不合理或惡意的,因為所有請求者都沒有身份信息。
漏洞填補
- 如果你的注冊功能是web頁面,最好加上驗證碼功能,但使用便利性會打折。
- 如果你的注冊功能是手機端,那就上SSL雙向驗證,中間人既無法分析你的接口,也無法發起請求連接到你接口服務,更不用說請求你的接口。
SSL/TLS雙向驗證
單向驗證
我們平時瀏覽器請求的https網頁,其實是SSL/TLS單向的客戶端驗證服務端的證書,也就是服務端不要求客戶端有公認的證書,但客戶端是要求服務端必須提供受信任的數字證書頒發機構證書。中間傳輸的數據是加密安全的,但服務端是無法得到能代表客戶端的身份信息的,而且,客戶端的請求加密數據是可以間接被攔截、解析、重構數據包再發送到服務端的(你可以了解Fiddler是怎么做到分析https接口的)。
雙向驗證
雙向驗證是指在單向驗證的基礎上,服務端也需要驗證客戶端的證書,只有客戶端持有服務端認定的指定證書,服務端才允許客戶端通過SSL握手,否則直接關閉tcp連接。對於需要雙向驗證的https接口,Fiddler也是無能為力,因為它自己也連接到不到服務端。
客戶端證書
客戶端證書我們不需要花錢去購買,使用openssl tools來自頒發就可以,服務端一般驗證其thumdata是否滿足就可以了。
安全的asp.net core
短信接口
回到實際干活擼代碼階段,我們可以把短信接口獨立出來,做單獨一個服務,其提供的只有短信功能的接口,接口必須雙向證書驗證,使用 kestrel ,我們很容易加入驗證客戶端的代碼邏輯。
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseKestrel((context, options) =>
{
var port = context.Configuration.GetValue<int>("SSL:Port");
var serverCertFile = context.Configuration.GetValue<string>("SSL:ServerCertFile");
var serverCertPassword = context.Configuration.GetValue<string>("SSL:ServerCertPassword");
options.Listen(IPAddress.Any, port, listenOptions =>
{
var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions()
{
ServerCertificate = new X509Certificate2(serverCertFile, serverCertPassword),
ClientCertificateMode = ClientCertificateMode.RequireCertificate,
ClientCertificateValidation = (cer, chain, error) =>
{
// 你的驗證邏輯
},
};
listenOptions.UseHttps(httpsConnectionAdapterOptions);
});
})
.UseStartup<Startup>();
}
}
Openssl生成cer、key和pfx
openssl genrsa -out openssl.key 1024
openssl req -new -x509 -key openssl.key -out openssl.cer -days 3650 -subj /CN=localhost
openssl pkcs12 -export -out openssl.pfx -inkey openssl.key -in openssl.cer
如果你在Postman請求,設置cer和key文件到postman即可,如果在.net環境請求這些接口,你需要使用pfx,你可以簡單理解pfx就是前兩者使用一個可選的密碼進行打包的得到單一文件。關於證書本身的內容非常龐大,本文不作任何解讀。
.net的客戶端怎么設置證書
這里先賣個關子,使用WebApiClient庫,可以輕松完成你想要的。