当前位置:首页 > 百科

网站网络安全自查报告

上周三凌晨两点,网站网络服务器监控突然报警——某个后台接口的安全响应时间从200毫秒飙到8秒。爬起来查日志,自查发现有人在用脚本批量请求用户信息接口,报告频率每秒40次。网站网络这不是安全攻击,但暴露了一个更尴尬的自查问题:我们连基本的请求频率限制都没做。

这次自查就从那个凌晨开始。报告我拉上运维和安全组的网站网络三个人,花了四天把公司主站和两个子域翻了个底朝天。安全下面按实际发现的自查问题分类说,不按什么标准框架走。报告

一、网站网络认证与授权:最薄弱的安全环节

后台管理系统的登录接口,密码错误时返回“用户名不存在”或“密码错误”两种不同提示。自查攻击者拿一份用户名字典就能枚举出哪些账号真实存在。这个漏洞是老代码遗留的,2019年写的,当时没人提。更麻烦的是,管理员账号的session有效期设了30天,且没有绑定IP或设备指纹。只要cookie被偷,攻击者能躺一个月。

修复动作:统一错误提示为“用户名或密码错误”,session有效期砍到4小时,加了一层基于User-Agent的简单指纹校验。不完美,但比没有强。

二、接口层面的裸奔

那个凌晨报警的接口,现在加了Redis做的滑动窗口限流——单IP每分钟最多60次,单用户token每分钟30次。但查的过程中发现另外三个接口连基本的参数校验都没有。比如一个查询订单的接口,直接拿URL里的order_id拼SQL。测试时我传了1 OR 1=1,返回了全表数据。开发说“这是内部接口”,可它部署在公网。

用sqlmap跑了一遍,确认是注入。当天下午改成预编译语句,加了一层WAF规则拦截明显注入特征。这里有个个人判断:内部接口和外部接口的边界越来越模糊,别拿“内部”当免死金牌。

三、日志与监控的盲区

我们有ELK,但只收集了Nginx的access log。应用层的错误日志、登录失败记录、敏感操作日志,全散落在各台机器的/var/log/app/下面。查那个凌晨的异常请求时,花了半小时才定位到具体是哪个服务。更离谱的是,日志里记录了用户ID和操作类型,但没记录请求来源IP。等于说,知道有人干了坏事,但不知道是谁干的。

改了日志格式,统一输出JSON,加了client_ip和request_id字段。用Filebeat推到Elasticsearch,配了三条告警规则:登录失败超过10次/分钟、单IP请求量突增5倍、SQL关键词出现在URL参数里。告警发到钉钉群,不是邮件——邮件没人看。

四、依赖组件的老旧问题

扫了一遍pom.xml和package.json,发现log4j版本是2.14.1。对,就是那个核弹级漏洞的版本。开发说“我们没用JNDI lookup”,但攻击者不关心你用没用。升级到2.17.1,顺手把fastjson从1.2.60升到1.2.83。另外,前端用的jQuery是1.12.4,2016年的版本。虽然没爆出大漏洞,但很多XSS过滤绕过技巧都针对老版本。换成了3.6.4,改了两处依赖旧API的代码。

这事给我的教训:依赖管理不能靠人肉记。后来加了一个mvn versions:display-dependency-updates的定时任务,每周一早上发报告到群里。

五、还没做完的事

HTTPS证书还有20天到期,自动续签脚本写了一半。文件上传接口只校验了扩展名,没校验MIME类型和文件头,传个.jpg的PHP文件理论上能解析——测试环境复现了,生产环境因为Nginx配置了location ~ \.php$ { deny all; }暂时没事。但这是运气,不是设计。打算下周用filetype库做二次校验,再把上传目录挂到独立域名下,彻底禁止执行权限。

自查报告不会写“整体安全状况良好”这种话。四个漏洞,两个高危,一个中危,一个低危。修了三个,还剩一个文件上传的在排期。安全这事,修完旧的,新的又来了。

分享到: