28、MVC中的安全最佳实践:常见漏洞与防护

说实话,安全这个话题,很多做MVC开发的朋友一开始都不太重视。我早年也踩过坑——项目上线第二天,数据库被人拖走了。嗯,那滋味真不好受。

今天咱们就聊聊MVC架构里最常见的三个安全漏洞:SQL注入、XSS和CSRF。我会结合自己的实战经验,告诉你它们是怎么发生的,又该怎么防。

MVC安全防护核心体系 SQL注入 XSS跨站脚本 CSRF跨站请求 防护措施 参数化查询 ORM框架 / 输入过滤 防护措施 输出编码 / CSP策略 HttpOnly Cookie 防护措施 CSRF Token SameSite Cookie MVC安全最佳实践:分层防御

一、SQL注入:最经典的漏洞

SQL注入说白了,就是攻击者把恶意的SQL代码塞进你的输入框里。如果你的代码直接拼接SQL语句,那就中招了。

⚠️ 危险示例: 千万别这么写!
// 错误示范 —— 直接拼接SQL
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);

攻击者输入 admin' OR '1'='1,你的SQL就变成了:

SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = ''

结果呢?整个用户表都暴露了。我在项目中遇到过类似的事,还好只是测试环境,不然就出大事了。

正确做法:参数化查询

// 正确做法 —— 使用参数化查询
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
💡 我的建议: 能用ORM框架(比如Hibernate、MyBatis)就别手写SQL。ORM自带参数绑定,省心又安全。

二、XSS跨站脚本攻击

XSS攻击,就是攻击者往你的页面里注入恶意脚本。比如在评论区写一段JavaScript,其他用户一打开页面就中招。

为什么会这样?说白了,就是你把用户输入的内容直接当HTML渲染了,没有做转义处理。

🔴 典型场景: 用户提交 <script>alert('xss')</script>,你的页面直接输出这段内容。

防护措施

  • 输出编码: 在View层对用户输入做HTML实体编码。比如 < 转成 &lt;
  • 设置HttpOnly Cookie: 让JavaScript无法读取Cookie,防止攻击者窃取会话
  • 启用CSP(内容安全策略): 限制页面只能加载白名单内的脚本
// 在MVC的View中做输出编码(以Java Spring为例)
<div th:text="${userInput}"></div>
// th:text会自动做HTML转义,安全!
💡 避坑指南: 我曾经在项目里用了 th:utext(不转义输出),结果被安全团队打回来了。记住:除非你100%确定内容安全,否则永远用 th:text

三、CSRF跨站请求伪造

CSRF攻击,简单说就是:你登录了银行网站,然后不小心点开了一个钓鱼链接。这个链接偷偷向银行网站发了个转账请求,因为你的Cookie还在,银行就以为是你本人操作的。

你想想看,这多可怕?

防护措施

防护方式 说明 推荐度
CSRF Token 每个表单生成一个随机Token,提交时校验 ⭐⭐⭐⭐⭐
SameSite Cookie 设置Cookie的SameSite属性为Strict或Lax ⭐⭐⭐⭐
验证Referer头 检查请求来源是否合法 ⭐⭐⭐
// Spring MVC中启用CSRF防护(配置类)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .authorizeRequests()
            .anyRequest().authenticated();
    }
}
✅ 最佳实践: 我建议你同时使用CSRF Token + SameSite Cookie。双重保险,基本就稳了。

四、MVC分层防御总结

安全不是某一个层的事,而是整个MVC架构都要参与。我个人习惯这样分配:

  • Model层: 参数化查询、ORM框架、数据校验
  • View层: 输出编码、CSP策略、HttpOnly Cookie
  • Controller层: CSRF Token、输入过滤、权限校验
⚠️ 最后提醒: 安全没有银弹。别以为用了框架就万事大吉。我见过太多人用了Spring Security,结果自己手写SQL又忘了参数化——嗯,该漏还是漏。

记住一句话:永远不要信任用户的输入。不管是来自表单、URL参数还是Cookie,统统当成恶意数据来处理。这样你的MVC应用才能睡得安稳。


公众号:蓝海资料掘金营,微信deep3321