序言
去年年底闲来几天, 有位同事专门在网上找一些注册型的 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 的客户端怎么设置证书
这里先卖个关子, 使用 https://github.com/dotnetcore/WebApiClient 库, 可以轻松完成你想要的.
来源: https://www.cnblogs.com/kewei/p/10765421.html