漏洞说明:

跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Web脚本代码(html、javascript、css等),当用户浏览该页面时,嵌入其中的Web脚本代码会被执行,从而达到恶意攻击用户的特殊目的。

测试步骤

访问系统网站,点击基础报告库进行编辑,使用Burp抓包并重新构造数据包

重新访问,成功触发了XSS弹窗

解决方法:

将危险内容过滤去除,用HTML转义字符串(Escape Sequence)表达的则保留

添加脚本过滤类

    /// <summary>
/// Html 脚本过滤
/// </summary>
public class NHtmlFilter
{
protected static readonly RegexOptions REGEX_FLAGS_SI = RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled; private static string P_COMMENTS = "<!--(.*?)-->";
private static Regex P_COMMENT = new Regex("^!--(.*)--$", REGEX_FLAGS_SI);
private static string P_TAGS = "<(.*?)>";
private static Regex P_END_TAG = new Regex("^/([a-z0-9]+)", REGEX_FLAGS_SI);
private static Regex P_START_TAG = new Regex("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
private static Regex P_QUOTED_ATTRIBUTES = new Regex("([a-z0-9|(a-z0-9\\-a-z0-9)]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
private static Regex P_UNQUOTED_ATTRIBUTES = new Regex("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
private static Regex P_PROTOCOL = new Regex("^([^:]+):", REGEX_FLAGS_SI);
private static Regex P_ENTITY = new Regex("&#(\\d+);?");
private static Regex P_ENTITY_UNICODE = new Regex("&#x([0-9a-f]+);?");
private static Regex P_ENCODE = new Regex("%([0-9a-f]{2});?");
private static Regex P_VALID_ENTITIES = new Regex("&([^&;]*)(?=(;|&|$))");
private static Regex P_VALID_QUOTES = new Regex("(>|^)([^<]+?)(<|$)", RegexOptions.Singleline | RegexOptions.Compiled);
private static string P_END_ARROW = "^>";
private static string P_BODY_TO_END = "<([^>]*?)(?=<|$)";
private static string P_XML_CONTENT = "(^|>)([^<]*?)(?=>)";
private static string P_STRAY_LEFT_ARROW = "<([^>]*?)(?=<|$)";
private static string P_STRAY_RIGHT_ARROW = "(^|>)([^<]*?)(?=>)";
private static string P_AMP = "&";
private static string P_QUOTE = "\"";
private static string P_LEFT_ARROW = "<";
private static string P_RIGHT_ARROW = ">";
private static string P_BOTH_ARROWS = "<>"; // @xxx could grow large... maybe use sesat's ReferenceMap
private static Dictionary<string, string> P_REMOVE_PAIR_BLANKS = new Dictionary<string, string>();
private static Dictionary<string, string> P_REMOVE_SELF_BLANKS = new Dictionary<string, string>();
/**
* flag determining whether to try to make tags when presented with "unbalanced"
* angle brackets (e.g. "<b text </b>" becomes "<b> text </b>"). If set to false,
* unbalanced angle brackets will be html escaped.
*/
protected static bool alwaysMakeTags = true; /**
* flag determing whether comments are allowed in input String.
*/
protected static bool stripComment = true; /// <summary>
/// 不允许
/// </summary>
private string[] vDisallowed { get; set; }
/// <summary>
/// 允许
/// </summary>
protected Dictionary<string, List<string>> vAllowed { get; set; } /** counts of open tags for each (allowable) html element **/
protected Dictionary<string, int> vTagCounts; /** html elements which must always be self-closing (e.g. "<img />") **/
protected string[] vSelfClosingTags; /** html elements which must always have separate opening and closing tags (e.g. "<b></b>") **/
protected string[] vNeedClosingTags; /** attributes which should be checked for valid protocols **/
protected string[] vProtocolAtts; /** allowed protocols **/
protected string[] vAllowedProtocols; /** tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") **/
protected string[] vRemoveBlanks; /** entities allowed within html markup **/
protected string[] vAllowedEntities; /// <summary>
/// 是否为调试
/// </summary>
protected bool vDebug; public NHtmlFilter() : this(false) { } public NHtmlFilter(bool debug)
{
//List<Item> vAllowed = new List<Item>();
vAllowed = new Dictionary<string, List<string>>();
#region 允许通过数组 vAllowed.Add("a", new List<string>() { "target", "href", "title", "class", "style" });
vAllowed.Add("addr", new List<string>() { "title", "class", "style" });
vAllowed.Add("address", new List<string>() { "class", "style" });
vAllowed.Add("area", new List<string>() { "shape", "coords", "href", "alt" });
vAllowed.Add("article", new List<string>() { });
vAllowed.Add("aside", new List<string>() { });
vAllowed.Add("audio", new List<string>() { "autoplay", "controls", "loop", "preload", "src", "class", "style" });
vAllowed.Add("b", new List<string>() { "class", "style" });
vAllowed.Add("bdi", new List<string>() { "dir" });
vAllowed.Add("bdo", new List<string>() { "dir" });
vAllowed.Add("big", new List<string>() { });
vAllowed.Add("blockquote", new List<string>() { "cite", "class", "style" });
vAllowed.Add("br", new List<string>() { });
vAllowed.Add("caption", new List<string>() { "class", "style" });
vAllowed.Add("center", new List<string>() { });
vAllowed.Add("cite", new List<string>() { });
vAllowed.Add("code", new List<string>() { "class", "style" });
vAllowed.Add("col", new List<string>() { "align", "valign", "span", "width", "class", "style" });
vAllowed.Add("colgroup", new List<string>() { "align", "valign", "span", "width", "class", "style" });
vAllowed.Add("dd", new List<string>() { "class", "style" });
vAllowed.Add("del", new List<string>() { "datetime" });
vAllowed.Add("details", new List<string>() { "open" });
vAllowed.Add("div", new List<string>() { "class", "style" });
vAllowed.Add("dl", new List<string>() { "class", "style" });
vAllowed.Add("dt", new List<string>() { "class", "style" });
vAllowed.Add("em", new List<string>() { "class", "style" });
vAllowed.Add("font", new List<string>() { "color", "size", "face" });
vAllowed.Add("footer", new List<string>() { });
vAllowed.Add("h1", new List<string>() { "class", "style" });
vAllowed.Add("h2", new List<string>() { "class", "style" });
vAllowed.Add("h3", new List<string>() { "class", "style" });
vAllowed.Add("h4", new List<string>() { "class", "style" });
vAllowed.Add("h5", new List<string>() { "class", "style" });
vAllowed.Add("h6", new List<string>() { "class", "style" });
vAllowed.Add("header", new List<string>() { });
vAllowed.Add("hr", new List<string>() { });
vAllowed.Add("i", new List<string>() { "class", "style" });
vAllowed.Add("img", new List<string>() { "src", "alt", "title", "style", "width", "height", "id", "_src", "loadingclass", "class", "data-latex", "data-id", "data-type", "data-s" });
vAllowed.Add("ins", new List<string>() { "datetime" });
vAllowed.Add("li", new List<string>() { "class", "style" });
vAllowed.Add("mark", new List<string>() { });
vAllowed.Add("nav", new List<string>() { });
vAllowed.Add("ol", new List<string>() { "class", "style" });
vAllowed.Add("p", new List<string>() { "class", "style" });
vAllowed.Add("pre", new List<string>() { "class", "style" });
vAllowed.Add("s", new List<string>() { });
vAllowed.Add("section", new List<string>() { });
vAllowed.Add("small", new List<string>() { });
vAllowed.Add("span", new List<string>() { "class", "style" });
vAllowed.Add("sub", new List<string>() { "class", "style" });
vAllowed.Add("sup", new List<string>() { "class", "style" });
vAllowed.Add("strong", new List<string>() { "class", "style" });
vAllowed.Add("table", new List<string>() { "width", "border", "align", "valign", "class", "style" });
vAllowed.Add("tbody", new List<string>() { "align", "valign", "class", "style" });
vAllowed.Add("td", new List<string>() { "width", "rowspan", "colspan", "align", "valign", "class", "style" });
vAllowed.Add("tfoot", new List<string>() { "align", "valign", "class", "style" });
vAllowed.Add("th", new List<string>() { "width", "rowspan", "colspan", "align", "valign", "class", "style" });
vAllowed.Add("thead", new List<string>() { "align", "valign", "class", "style" });
vAllowed.Add("tr", new List<string>() { "rowspan", "align", "valign", "class", "style" });
vAllowed.Add("tt", new List<string>() { });
vAllowed.Add("u", new List<string>() { });
vAllowed.Add("ul", new List<string>() { "class", "style" });
vAllowed.Add("video", new List<string>() { "autoplay", "controls", "loop", "preload", "src", "height", "width", "class", "style" });
#endregion vDebug = debug;
vTagCounts = new Dictionary<string, int>(); vSelfClosingTags = new string[] { "img" };
vNeedClosingTags = new string[] { "a", "b", "strong", "i", "em" };
vDisallowed = new string[] { "script" };
vAllowedProtocols = new string[] { "http", "mailto" }; // no ftp.
vProtocolAtts = new string[] { "src", "href" };
vRemoveBlanks = new string[] { "a", "b", "strong", "i", "em" };
vAllowedEntities = new string[] { "amp", "gt", "lt", "quot" };
stripComment = true;
alwaysMakeTags = true;
} protected void reset()
{
vTagCounts = new Dictionary<string, int>();
} protected void debug(string msg)
{
if (vDebug)
System.Diagnostics.Debug.WriteLine(msg);
} //---------------------------------------------------------------
// my versions of some PHP library functions public static string chr(int dec)
{
return "" + (char)dec;
} /// <summary>
/// 转换成实体字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string htmlSpecialChars(string str)
{
str = str.Replace(P_QUOTE, "\""); str = str.Replace(P_LEFT_ARROW, "<");
str = str.Replace(P_RIGHT_ARROW, ">");
str = str.Replace("\n", "<br>");
return str;
} //--------------------------------------------------------------- /**
* given a user submitted input String, filter out any invalid or restricted
* html.
*
* @param input text (i.e. submitted by a user) than may contain html
* @return "clean" version of input, with only valid, whitelisted html elements allowed
*/
public string filter(string input)
{
reset();
string s = input; debug("************************************************");
debug(" INPUT: " + input); s = escapeComments(s);
debug(" escapeComments: " + s); s = balanceHTML(s);
debug(" balanceHTML: " + s); s = checkTags(s);
debug(" checkTags: " + s); s = processRemoveBlanks(s);
debug("processRemoveBlanks: " + s); s = validateEntities(s);
debug(" validateEntites: " + s); debug("************************************************\n\n");
return s;
} protected string escapeComments(string s)
{
return Regex.Replace(s, P_COMMENTS, new MatchEvaluator(ConverMatchComments), RegexOptions.Singleline);
} protected string regexReplace(string regex_pattern, string replacement, string s)
{
return Regex.Replace(s, regex_pattern, replacement);
} protected string balanceHTML(string s)
{
if (alwaysMakeTags)
{
//
// try and form html
//
s = regexReplace(P_END_ARROW, "", s);
s = regexReplace(P_BODY_TO_END, "<$1>", s);
s = regexReplace(P_XML_CONTENT, "$1<$2", s); }
else
{
//
// escape stray brackets
//
s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s);
s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); //
// the last regexp causes '<>' entities to appear
// (we need to do a lookahead assertion so that the last bracket can
// be used in the next pass of the regexp)
//
s = s.Replace(P_BOTH_ARROWS, "");
}
return s;
} protected string checkTags(string s)
{
//替换不允许标签
foreach (var item in vDisallowed)
{
s = Regex.Replace(s, string.Format(@"<{0}\b(.)*?>(.)+?</{0}>", item), "");
}
s = Regex.Replace(s, P_TAGS, new MatchEvaluator(ConverMatchTags), RegexOptions.Singleline); // these get tallied in processTag
// (remember to reset before subsequent calls to filter method)
foreach (string key in vTagCounts.Keys)
{
for (int ii = 0; ii < vTagCounts[key]; ii++)
{
s += "</" + key + ">";
}
} return s;
} protected string processRemoveBlanks(string s)
{
foreach (string tag in vRemoveBlanks)
{
s = regexReplace("<" + tag + "(\\s[^>]*)?></" + tag + ">", "", s);
s = regexReplace("<" + tag + "(\\s[^>]*)?/>", "", s);
}
return s;
} private string processTag(string s)
{
// ending tags
Match m = P_END_TAG.Match(s);
if (m.Success)
{
string name = m.Groups[1].Value.ToLower();
if (allowed(name))
{
if (!inArray(name, vSelfClosingTags))
{
if (vTagCounts.ContainsKey(name))
{
vTagCounts[name] = vTagCounts[name] - 1;
return "</" + name + ">";
}
}
}
} // starting tags
m = P_START_TAG.Match(s);
if (m.Success)
{
string name = m.Groups[1].Value.ToLower();
string body = m.Groups[2].Value;
string ending = m.Groups[3].Value; //debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
if (allowed(name))
{
string params1 = ""; MatchCollection m2 = P_QUOTED_ATTRIBUTES.Matches(body);
MatchCollection m3 = P_UNQUOTED_ATTRIBUTES.Matches(body);
List<string> paramNames = new List<string>();
List<string> paramValues = new List<string>();
foreach (Match match in m2)
{
paramNames.Add(match.Groups[1].Value); //([a-z0-9]+)
paramValues.Add(match.Groups[3].Value); //(.*?)
}
foreach (Match match in m3)
{
paramNames.Add(match.Groups[1].Value); //([a-z0-9]+)
paramValues.Add(match.Groups[3].Value); //([^\"\\s']+)
} string paramName, paramValue;
for (int ii = 0; ii < paramNames.Count; ii++)
{
paramName = paramNames[ii].ToLower();
paramValue = paramValues[ii]; if (allowedAttribute(name, paramName))
{
if (inArray(paramName, vProtocolAtts))
{
paramValue = processParamProtocol(paramValue);
}
params1 += " " + paramName + "=\"" + paramValue + "\"";
}
} if (inArray(name, vSelfClosingTags))
{
ending = " /";
} if (inArray(name, vNeedClosingTags))
{
ending = "";
} if (ending == null || ending.Length < 1)
{
if (vTagCounts.ContainsKey(name))
{
vTagCounts[name] = vTagCounts[name] + 1;
}
else
{
vTagCounts.Add(name, 1);
}
}
else
{
ending = " /";
}
return "<" + name + params1 + ending + ">";
}
else
{
return "";
}
} // comments
m = P_COMMENT.Match(s);
if (!stripComment && m.Success)
{
return "<" + m.Value + ">";
} return "";
} private string processParamProtocol(string s)
{
s = decodeEntities(s);
Match m = P_PROTOCOL.Match(s);
if (m.Success)
{
string protocol = m.Groups[1].Value;
if (!inArray(protocol, vAllowedProtocols))
{
// bad protocol, turn into local anchor link instead
s = "#" + s.Substring(protocol.Length + 1, s.Length - protocol.Length - 1);
if (s.StartsWith("#//"))
{
s = "#" + s.Substring(3, s.Length - 3);
}
}
}
return s;
} private string decodeEntities(string s)
{ s = P_ENTITY.Replace(s, new MatchEvaluator(ConverMatchEntity)); s = P_ENTITY_UNICODE.Replace(s, new MatchEvaluator(ConverMatchEntityUnicode)); s = P_ENCODE.Replace(s, new MatchEvaluator(ConverMatchEntityUnicode)); s = validateEntities(s);
return s;
} private string validateEntities(string s)
{
s = P_VALID_ENTITIES.Replace(s, new MatchEvaluator(ConverMatchValidEntities));
s = P_VALID_QUOTES.Replace(s, new MatchEvaluator(ConverMatchValidQuotes));
return s;
} private static bool inArray(string s, string[] array)
{
foreach (string item in array)
{
if (item != null && item.Equals(s))
{
return true;
}
}
return false;
} private bool allowed(string name)
{
return (vAllowed.Count == 0 || vAllowed.ContainsKey(name)) && !inArray(name, vDisallowed);
} private bool allowedAttribute(string name, string paramName)
{
return allowed(name) && (vAllowed.Count == 0 || vAllowed[name].Contains(paramName));
} private string checkEntity(string preamble, string term)
{ return ";".Equals(term) && isValidEntity(preamble)
? '&' + preamble
: "&" + preamble;
}
private bool isValidEntity(string entity)
{
return inArray(entity, vAllowedEntities);
}
private static string ConverMatchComments(Match match)
{
string matchValue = "<!--" + htmlSpecialChars(match.Groups[1].Value) + "-->";
return matchValue;
} private string ConverMatchTags(Match match)
{
string matchValue = processTag(match.Groups[1].Value);
return matchValue;
} private string ConverMatchEntity(Match match)
{
string v = match.Groups[1].Value;
int decimal1 = int.Parse(v);
return chr(decimal1);
} private string ConverMatchEntityUnicode(Match match)
{
string v = match.Groups[1].Value;
int decimal1 = Convert.ToInt32("0x" + v, 16);
return chr(decimal1);
} private string ConverMatchValidEntities(Match match)
{
string one = match.Groups[1].Value; //([^&;]*)
string two = match.Groups[2].Value; //(?=(;|&|$))
return checkEntity(one, two);
}
private string ConverMatchValidQuotes(Match match)
{
string one = match.Groups[1].Value; //(>|^)
string two = match.Groups[2].Value; //([^<]+?)
string three = match.Groups[3].Value;//(<|$)
return one + regexReplace(P_QUOTE, "\"", two) + three;
} public bool isAlwaysMakeTags()
{
return alwaysMakeTags;
} public bool isStripComments()
{
return stripComment;
} class Item
{
public string name { get; set; }
public List<string> parameter { get; set; }
} }

源代码出自:https://www.cnblogs.com/OleRookie/p/5970167.html

在请求时对参数的内容进行过滤:

var nHtmlFilter = new NHtmlFilter(false);
surveyPayload.PayloadContent = nHtmlFilter.filter(surveyPayload.PayloadContent);

再次请求时,已将危险代码转成HTML转义字符串的形式了

[Asp.Net Core] 网站中的XSS跨站脚本攻击和防范的更多相关文章

  1. web应用程序安全攻防---sql注入和xss跨站脚本攻击

    kali视频学习请看 http://www.cnblogs.com/lidong20179210/p/8909569.html 博文主要内容包括两种常见的web攻击 sql注入 XSS跨站脚本攻击 代 ...

  2. Web攻防系列教程之跨站脚本攻击和防范技巧详解

    摘要:XSS跨站脚本攻击一直都被认为是客户端Web安全中最主流的攻击方式.因为Web环境的复杂性以及XSS跨站脚本攻击的多变性,使得该类型攻击很 难彻底解决.那么,XSS跨站脚本攻击具体攻击行为是什么 ...

  3. ASP.NET Core 网站在Docker中运行

    Docker作为新一代的虚拟化方式,未来肯定会得到广泛的应用,传统虚拟机的部署方式要保证开发环境.测试环境.UAT环境.生产环境的依赖一致性,需要大量的运维人力,使用Docker我们可以实现一次部署, ...

  4. ASP.NET Core 网站发布到Linux服务器

    长期以来,使用.NET开发的应用只能运行在Windows平台上面,而目前国内蓬勃发展的互联网公司由于成本的考虑,大量使用免费的Linux平台,这就使得.NET空有一身绝技但无法得到广大的施展空间,.N ...

  5. docker 初识之二(简单发布ASP.NET Core 网站)

    在发布ASP.NET Core网站以前,先介绍一下DaoCloud 一个免费的docker云容器服务平台.登陆官方网站,创建一台docker主机,这台主机有120分钟的使用时间,对于鄙人学习使用正好合 ...

  6. ASP.NET Core 网站发布到Linux服务器(转)

    出处;ASP.NET Core 网站发布到Linux服务器 长期以来,使用.NET开发的应用只能运行在Windows平台上面,而目前国内蓬勃发展的互联网公司由于成本的考虑,大量使用免费的Linux平台 ...

  7. ASP.NET Core MVC中构建Web API

    在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...

  8. ASP.NET Core WebAPI中的分析工具MiniProfiler

    介绍 作为一个开发人员,你知道如何分析自己开发的Api性能么? 在Visual Studio和Azure中, 我们可以使用Application Insight来监控项目.除此之外我们还可以使用一个免 ...

  9. asp.net core mvc中如何把二级域名绑定到特定的控制器上

    由于公司的工作安排,一直在研究其他技术,所以一直没时间更新博客,今天终于可以停下手头的事情,写一些新内容了. 应用场景:企业门户网站会根据内容不同,设置不同的板块,如新浪有体育,娱乐频道,等等.有的情 ...

  10. 在 ASP.NET Core 项目中使用 MediatR 实现中介者模式

    一.前言  最近有在看 DDD 的相关资料以及微软的 eShopOnContainers 这个项目中基于 DDD 的架构设计,在 Ordering 这个示例服务中,可以看到各层之间的代码调用与我们之前 ...

随机推荐

  1. mysql表操作2

    表介绍: 表就相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段 创建表: #语法: create table 表名( 字段名1 类型[(宽度) 约束 ...

  2. SpringBoot - Lombok使用详解2(@Setter、@Getter、@ToString、@EqualsAndHashCode)

    四.Lombok 注解详解(2) 1,@Setter 和 @Getter (1)这两个注解用于生成 setter 和 getter 方法,可以用在类或者属性上: 如果用在属性上:则只为该属性提供 se ...

  3. 获取n位数m进制的随机数 js

    js 获取n位数m进制的随机数 n 的取值范围为 0 < n > 1.7976931348623157e+308 (Number.MAX_VALUE) m的取值范围为 2 <= m ...

  4. jsp第6个作业—jdbc

    UsersDao.java package a; import java.sql.Connection; import java.sql.PreparedStatement; import java. ...

  5. 加热算法,加热温度控制加热功率,加热功率控制加热速度(PWM)

    uint8_t user_heating_algorithmPID(void) { uint32_t temp_1; uint16_t Adcn; nrfx_err_t err_code; HEATI ...

  6. 中兴radius属性列表new.xls

    标准属性 自定义属性

  7. Matlab %陆

    第六章 MATLAB IN ENGINEERING Polynomial Differentiation多项式微分  %幂级数 f(x) = x^3-2x-5; p = [1 0 -2 -5]  %自 ...

  8. 005Java开发环境搭建

    005Java开发环境搭建 1.JDK下载与安装 (1)卸载 首先我们先来学习一下如何卸载JDK. 删除Java的安装目录(jdk整个包). 删除环境变量里的"JAVA_HOME" ...

  9. Typora配置本地图片自动上传阿里云OSS

    一.下载Typora ​ Gitee下载地址 二.下载Picgo.app ​ Github下载地址 三.配置Picgo 打开Typora,格式→图像→图像全局设置: 四.图床设置 注册阿里云账号 打开 ...

  10. nginx学习之路

    nginx反向代理服务器 1.技术选型 nginx主要能实现的功能有负载均衡,反向代理,动静分离.选择nginx主要为了实现反向代理以及负载均衡功能, *为什么要实现反向代理 传统项目直接暴露在外网入 ...