网络安全攻击方式有很多种,其中包括XSS攻击、SQL注入攻击、URL篡改等。那么XSS攻击到底是什么?XSS攻击有哪几种类型?
XSS攻击又称为跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行。XSS是一种经常出现在Web应用程序中的计算机安全漏洞,是由于Web应用程序对用户的输入过滤不足而产生的,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
常见的XSS攻击有三种:反射型XSS攻击、DOM-based型XSS攻击、存储型XSS攻击。
第一种:反射型XSS攻击
反射型XSS攻击一般是攻击者通过特定手法,诱使用户去访问一个包含恶意代码的URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类XSS攻击通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端Cookies或进行钓鱼欺骗
第二种:DOM-based型XSS攻击
客户端的脚本程序可以动态地检查和修改页面内容,而不依赖于服务器端的数据。例如客户端如从URL中提取数据并在本地执行,如果用户在客户端输入的数据包含了恶意的JavaScript脚本,而这些脚本没有经过适当的过滤或者消毒,那么应用程序就可能受到DOM-based型XSS攻击。
需要特别注意以下的用户输入源document.URL、location.hash、location.search、document.referrer等。
第三种:存储型XSS攻击
攻击者事先将恶意代码上传或者储存到漏洞服务器中,只要受害者浏览包含此恶意代码的页面就会执行恶意代码。这意味着只要访问了这个页面的访客,都有可能会执行这段恶意脚本,因此存储型XSS攻击的危害会更大。此类攻击一般出现在网站留言、评论、博客日志等交互处,恶意脚本存储到客户端或者服务端的数据库中。
好了,废话太多,还是直接上代码吧,XXSHelper.cs 工具类:
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace test.Defender
{
public class XSSHelper
{
//过滤后返回的结果
public static string XssFilter(string html)
{
string str = HtmlFilter(html);
return str;
}
//过滤html
public static string HtmlFilter(string Htmlstring)
{
//这里用正则表达式匹配到<[^>]*>全部过滤掉,当然也可以根据自身需求填写
string result = Regex.Replace(Htmlstring, @"<[^>]*>", String.Empty);
return result;
}
}
}
XXSFilterAttribute.cs过滤器
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace test.Defender
{
public class XSSFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var ps = context.ActionDescriptor.Parameters;
foreach (var p in ps)
{
if (context.ActionArguments[p.Name] != null)
{
if (p.ParameterType.Equals(typeof(string)))
{
context.ActionArguments[p.Name] = XSSHelper.XssFilter(context.ActionArguments[p.Name].ToString());
}
else if (p.ParameterType.IsClass)
{
PostModelFieldFilter(p.ParameterType, context.ActionArguments[p.Name]);
}
}
}
}
private object PostModelFieldFilter(Type type, object obj)
{
if (obj != null)
{
foreach (var item in type.GetProperties())
{
if (item.GetValue(obj) != null)
{
if (item.PropertyType.Equals(typeof(string)))
{
string value = item.GetValue(obj).ToString();
item.SetValue(obj, XSSHelper.XssFilter(value));
}
else if (item.PropertyType.IsClass)
{
item.SetValue(obj, PostModelFieldFilter(item.PropertyType, item.GetValue(obj)));
}
}
}
}
return obj;
}
}
}
LoginController.cs 控制器:
cs
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using test.Defender;
using test.Jwt;
using test.Models;
namespace test.Controllers
{
[XSSFilter] //在控制器加上XXSFilter即可过滤
[ApiController]
[Route("api/[controller]")]
public class LoginController : Controller
{
private string _names = "admin";
private string _role = "admin"; //角色,对应实体类的角色,在控制器中确定角色是否允许访问
// POST: api/Login
[HttpPost]
public IActionResult Index([FromBody] LoginModel model)
{
if (_names.Contains(model.Username) && model.Password == "admin")
{
return Ok(new
{
access_token = JwtHelper.create_Token(new User(1, model.Username, _role))
});
}
return Unauthorized();
}
}
}
防范手段
都说知己知彼方能百战不殆,知道了xss攻击的原理那么防御的方法也就显而易见了。
首先是过滤:对诸如<script>、<img>、<a>等标签进行过滤。
其次是编码:像一些常见的符号,如<>在输入的时候要对其进行转换编码,这样做浏览器是不会对该标签进行解释执行的,同时也不影响显示效果。
最后是限制:通过以上的案例我们不难发现xss攻击要能达成往往需要较长的字符串,因此对于一些可以预期的输入可以通过限制长度强制截断来进行防御。
后话
安全攻防双方的博弈永远都不会停止,也正是这种博弈推进了信息安全的发展。究竟是道高一尺还是魔高一丈很难定论。其实安全问题归根结底还是一个信任的前提。什么输入值得信任?什么输入不值得信任需要特殊处理是安全人员常常要思考的一个问题。
希望本文对你有帮助,感谢您的阅读。