在Web开发中,防止站外提交内容是保障网站安全的重要环节,尤其是对于ASP(Active Server Pages)经典架构的应用,由于早期设计对安全防护的考虑不足,更容易遭受CSRF(跨站请求伪造)和非法表单提交等攻击,本文将详细介绍ASP实现防止站外提交内容的两个核心方法,并辅以代码示例和对比分析,帮助开发者构建更安全的Web应用。

通过验证HTTP Referer字段识别请求来源
HTTP Referer字段是HTTP请求头的一部分,用于记录请求的来源页面,通过检查Referer字段,可以判断请求是否来自本站合法页面,从而拦截来自外部站点的恶意提交。
实现原理
当用户在本站页面提交表单时,浏览器会自动在请求头中添加Referer字段,值为当前页面的URL,若请求来自外部站点(如黑客构造的恶意页面),Referer字段将指向外部域名,在服务器端通过ASP的Request.ServerVariables(“HTTP_REFERER”)获取Referer值,并与本站域名进行比对,即可识别非法请求。
代码示例
在ASP处理表单的页面(如process.asp)中,添加以下验证逻辑:
<%
' 获取当前页面的完整URL(不含查询字符串)
Dim currentDomain
currentDomain = "http://" & Request.ServerVariables("SERVER_NAME") & ":" & Request.ServerVariables("SERVER_PORT")
' 获取请求来源的Referer值
Dim referer
referer = Request.ServerVariables("HTTP_REFERER")
' 检查Referer是否为空或是否包含本站域名
If IsEmpty(referer) Or InStr(referer, currentDomain) = 0 Then
' 非法请求,拦截并提示
Response.Write "非法请求来源!"
Response.End
Else
' 合法请求,继续处理表单数据
Dim username, password
username = Request.Form("username")
password = Request.Form("password")
' 后续业务逻辑...
End If
%> 注意事项
- Referer的可信度限制:用户可以通过浏览器设置(如禁用Referer)或代理工具伪造Referer字段,因此该方法需与其他防护手段结合使用。
- HTTPS环境兼容性:若网站从HTTP升级至HTTPS,需注意浏览器可能因安全策略导致Referer字段跨协议传输(如HTTP页面请求HTTPS资源时,部分浏览器会忽略Referer),此时需调整域名比对逻辑,支持协议无关的域名匹配(如仅比较
SERVER_NAME)。
使用ASP内置Session对象生成并验证Token
Token(令牌)机制是目前更可靠的防站外提交方法,其核心原理是为每个会话生成唯一随机Token,并在表单中提交,服务器端通过验证Token的有效性确认请求合法性,由于Token与会话绑定,外部站点无法获取合法Token,从而有效防止CSRF攻击。

实现步骤
- 生成Token并存储到Session:在表单页面生成随机Token,并存入Session对象。
- 将Token嵌入表单:在表单中添加隐藏字段,用于提交Token。
- 验证Token有效性:在提交处理页面检查Session中的Token与表单提交的Token是否一致。
代码示例
表单页面(form.asp)
<%
' 生成随机Token(16位字符)
Dim token
token = GenerateRandomToken(16)
Session("CSRFToken") = token ' 存入Session
' 生成随机Token的函数
Function GenerateRandomToken(length)
Dim chars, result, i
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
Randomize
For i = 1 To length
result = result & Mid(chars, Int(Rnd * Len(chars)) + 1, 1)
Next
GenerateRandomToken = result
End Function
%>
<form action="process.asp" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<!-- 隐藏字段提交Token -->
<input type="hidden" name="csrf_token" value="<%= token %>">
<input type="submit" value="提交">
</form> 处理页面(process.asp)
<%
' 获取表单提交的Token
Dim submittedToken
submittedToken = Request.Form("csrf_token")
' 检查Session中是否存在Token及是否匹配
If IsEmpty(Session("CSRFToken")) Or Session("CSRFToken") <> submittedToken Then
Response.Write "表单已过期或非法提交!"
Response.End
Else
' 验证通过,清除Session中的Token(一次性Token)
Session.Contents.Remove("CSRFToken")
' 处理表单数据
Dim username, password
username = Request.Form("username")
password = Request.Form("password")
' 后续业务逻辑...
Response.Write "提交成功!"
End If
%> 优化建议
- Token一次性使用:验证成功后立即清除Session中的Token,防止重复使用。
- Token有效期:可通过记录Token生成时间,设置有效期(如5分钟),超时后失效。
- Token复杂度:使用足够长度的随机字符串(推荐16位以上),并结合时间戳、用户ID等增强唯一性。
两种方法对比
为更直观地比较两种方法的适用场景,以下从安全性、实现复杂度、兼容性等维度进行总结:
| 对比维度 | Referer字段验证 | Session Token机制 |
|---|---|---|
| 安全性 | 中等(易被伪造或禁用) | 高(Token与会话绑定,外部无法获取) |
| 实现复杂度 | 简单(仅需几行代码) | 中等(需生成、存储、验证Token) |
| 兼容性 | 依赖浏览器,可能因HTTPS/代理失效 | 兼容所有浏览器,无环境依赖 |
| 适用场景 | 简单表单防护、临时性需求 | 涉及敏感操作(如登录、支付)、高安全需求场景 |
相关问答FAQs
Q1:为什么有时Referer验证会失效?
A:Referer验证失效主要有以下原因:

- 用户浏览器设置:用户手动禁用Referer功能(如通过浏览器插件或隐私模式),导致请求头中无Referer字段。
- HTTPS与HTTP混合内容:若页面通过HTTP加载,但提交表单跳转至HTTPS,部分浏览器出于安全考虑会过滤Referer字段。
- 代理或网络设备:部分代理服务器或防火墙会清除HTTP请求头中的Referer信息,导致服务器无法获取来源地址。
Q2:Token机制是否需要为每个表单单独生成Token?
A:建议为每个涉及数据修改的表单单独生成Token,尤其是不同业务逻辑的表单(如登录、注册、修改密码),若多个表单共用同一Token,可能导致Token被复用,增加安全风险,对于AJAX异步请求,也需在请求头或参数中携带Token,确保接口安全性。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复