缘由
上线的应用作渗透测试和安全测试,提了一个静态资源访问风险。静态资源存储在oss服务器上,配置为公共读,一般情况下直接返回前端静态资源的公网地址,给前端页面进行渲染,没有做多余的权限校验。测评公司认为是中风险,为了渗透测试报告和安全测试报告,认怂,想办法修改😢
方案
- oss部署在内网环境,我们通过nginx将其转发到公网上,想简单的配置一下,看能不能糊弄过测评人员,就在nginx添加了Referer配置,阻隔非同源网页的静态资源访问,本来以为意思意思,没想到被现实打击了,此方法失败
- 对方要求静态资源需要加上用户的token,要校验token来验证访问,nginx貌似无法配置自定义验证,我就想到写一个类似于nginx的代理服务器,验证token合法后,将继续转发将请求转发到oss服务器上,验证不通过则直接返回403拒绝服务
实现
刚好最近一直在学习go语言,被其强大的语法所震惊,决定抛弃java使用用go语言来写(我感觉使用webflux实现应该差不多)。
在系统服务中,文件服务器被单独独立出来,我们根据文件的主键id调用rpc服务查询出文件的url,在这个切点,在文件的url路径后面拼接了经过aes加密后的token信息,在代理服务器,如果解析到用户的token并且验证token合法后,将请求正常转发
package tcp
import (
"github.com/go-redis/redis"
aeswarp "go-test/aes-warp"
"log"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
var rdb *redis.Client
func init() {
rdb = redis.NewClient(&redis.Options{
Addr: "127.0.0.1:6379",
Password: "root",
DB: 0,
PoolSize: 3,
})
}
func ForwardHandler(writer http.
ResponseWriter, request *http.Request) {
//aeswarp.Decrypt()
query := request.URL.Query()
query_code := query["code"]
if len(query_code) == 0 {
writer.WriteHeader(403)
writer.Write([]byte("No right access"))
return
}
code := query_code[0]
token, err := aeswarp.Decrypt(code)
if err != nil {
writer.WriteHeader(403)
writer.Write([]byte("No right access"))
return
}
_, err = rdb.Get(token).Result()
if err != nil {
writer.WriteHeader(403)
writer.Write([]byte("No right access"))
return
}
u, err := url.Parse("https://douguohai.oss-cn-shenzhen.aliyuncs.com")
if nil != err {
log.Println("url parse error")
}
proxy := httputil.ReverseProxy{
Director: func(req *http.Request) {
req.Host = u.Host
req.URL.Scheme = u.Scheme
req.URL.Host = u.Host
req.URL.Path = strings.Split(request.RequestURI, "?")[0]
},
}
proxy.ServeHTTP(writer, request)
}
//代理服务器
func RunServer() {
http.HandleFunc("/", ForwardHandler)
http.ListenAndServe(":7777", nil)
}
完结
经过验证,实现了静态资源添加授权访问,看明天测评公司怎么说,咋要一份渗透报告和安全测试报告这么难呢😭
网友评论