4、应用安全防护:Web应用防火墙(WAF)、API安全防护、输入验证与防注入、会话管理
说到EMS系统的应用安全,我脑子里第一个蹦出来的画面,是几年前在某电厂做渗透测试的场景。对方工程师拍着胸脯说“我们系统在内网,绝对安全”。结果呢?我花了不到半小时,就通过一个未做任何校验的API接口,拿到了整个数据库的配置信息。嗯,从那以后,我对“内网安全”这四个字就特别敏感。
应用层是攻击者最喜欢下手的地方。为什么?因为这里直接跟用户打交道,入口多、逻辑复杂。你想想看,一个EMS系统里,Web界面、移动端APP、第三方数据接口……每个都是潜在的突破口。今天我们就来聊聊怎么把这些口子堵上。
4.1 Web应用防火墙(WAF)
WAF这东西,说白了就是给Web应用加个“门卫”。它站在用户和服务器之间,专门检查进来的请求有没有问题。
我个人习惯把WAF部署在反向代理层,而不是直接串在业务服务器前面。这样做的好处是:即使WAF挂了,业务还能跑,只是没了防护而已。我在项目中遇到过一家企业,把WAF直接串在Nginx前面,结果WAF一次升级重启,整个EMS系统瘫痪了半小时……
- SQL注入检测与阻断
- 跨站脚本(XSS)过滤
- CC攻击防护(频率限制)
- 恶意爬虫识别
- 敏感信息泄露防护(如/actuator/info等端点)
但要注意,WAF不是万能的。它只能识别已知的攻击模式。对于0day漏洞或者精心构造的绕过payload,WAF往往力不从心。所以我的建议是:WAF做第一道防线,但别把它当唯一防线。
4.2 API安全防护
现在的EMS系统,哪个不是一堆API在背后撑着?数据采集API、控制指令API、报表查询API……每个API都是攻击者的目标。
API安全防护,我总结了三件套:认证、授权、限流。
| 防护维度 | 具体措施 | 我在项目中踩过的坑 |
|---|---|---|
| 认证 | JWT + OAuth2.0,拒绝明文Token | 有人把Token直接写在URL里,日志一抓全暴露了 |
| 授权 | 基于角色的访问控制(RBAC),最小权限原则 | 一个普通运维账号居然能调用“重启PLC”的API |
| 限流 | 按用户/按IP/按API路径分级限流 | 没做限流,被一个爬虫把数据库连接池打满了 |
这里特别提一下API密钥的管理。我曾经见过一个EMS系统,API密钥硬编码在前端JavaScript里。你想想看,这跟把家门钥匙挂在门外有什么区别?正确的做法是:API密钥放在后端配置中心,前端通过服务端代理转发请求。
4.3 输入验证与防注入
输入验证,听起来很简单对吧?但恰恰是这里最容易出问题。攻击者最喜欢找那些“信任用户输入”的地方下手。
我个人的原则是:永远不要信任任何输入。不管是来自Web表单、API请求、还是文件上传,统统要过一遍“安检”。
常见的注入攻击类型:
- SQL注入:通过拼接SQL语句获取数据库数据
- 命令注入:在输入中嵌入系统命令
- LDAP注入:针对目录服务的攻击
- XML注入:通过XML解析器漏洞攻击
拿SQL注入来说,最有效的防护手段就是参数化查询。看看这个对比:
// ❌ 错误做法:字符串拼接
String sql = "SELECT * FROM users WHERE username = '" + username + "'";
// ✅ 正确做法:参数化查询
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE username = ?");
ps.setString(1, username);
我在项目中遇到过最离谱的一次,是有人用存储过程拼接SQL。他以为存储过程就安全了,结果呢?攻击者通过传入恶意参数,照样把整个用户表给拖走了。所以记住:存储过程不等于防注入,关键看你怎么用。
4.4 会话管理
会话管理,说白了就是怎么让系统知道“你是谁”。做得不好,攻击者就能冒充合法用户干坏事。
EMS系统的会话管理有几个特殊之处:
- 操作员可能长时间不操作(比如夜班值守),会话不能随便超时
- 一个操作员可能同时登录多个终端(中控室大屏+手持PAD)
- 紧急情况下需要快速切换用户(交接班场景)
我建议的会话管理策略:
- 使用HttpOnly + Secure + SameSite=Strict的Cookie,防止XSS窃取会话
- 会话超时采用“空闲超时+绝对超时”双机制:空闲超时30分钟,绝对超时8小时
- 每次敏感操作(如下发控制指令)重新验证身份,别让攻击者钻了会话固定的空子
- 登出时彻底销毁会话,包括清除服务端Session和客户端Cookie
嗯,会话管理这块还有一个容易被忽略的点:并发登录控制。EMS系统里,一个操作员账号被多个人同时使用的情况并不少见。我建议的做法是:允许同一账号在不同终端登录,但限制最大并发数(比如3个),并且记录每次登录的IP和设备信息,方便事后审计。
最后说一句,应用安全防护不是装个WAF就完事了。它是一个体系,需要从架构设计、编码规范、运维监控多个层面一起发力。我见过太多人把安全当成“上线前的安全检查”,结果呢?漏洞该在的还在,攻击该来的还来。安全,应该融入到开发的每一个环节里。