大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。
当前系列: ASP.NET 修改讲义
复习:原理架构-安全

AllowHtml和@Html.Raw()

MVC默认禁止具有“潜在威胁”的HTML代码提交到后台 (演示)

如果要允许HTML标签等传往后台,最安全的方式是:在相关属性上添加[AllowHtml]特性:

[AllowHtml]
public string Body { get; set; }

而且HTML内容默认会被自动编码后呈现(演示)

要原本的(raw)呈现出HTML效果,需要使用@Html.Raw()

@Html.Raw(Model.Body)


正则过滤

这部分内容其实就两个关键:

  1. 正则表达式书写,弄出标签和属性复习,作业第3.3题就是为此时准备的)
  2. .NET使用正则的类库,进行检查或者替换(复习

我们演示更复杂的替换:

  1. 准备好“白名单
    string[] allowedTags = new string[] { "p", "a", "img" };
    string[] allowedProperties = new string[] { "style", "class" };
  2. 找到所有的HTML元素,
    string fixedHtml = Regex.Replace(article.Body,
        "(<.*?>)",  //注意这个?:懒惰模式
        match => fixTag(match, allowedTags, allowedProperties),
        RegexOptions.IgnoreCase);
    
    private string fixTag(Match tagMatch,
        string[] allowedTags, string[] allowedProperties)
    {
        string tag = tagMatch.Value;
        Match m = Regex.Match(tag,
                                //(?<tagName>exp))指定“组”的名称
                                @"</?(?<tagName>[^\s/]*)[>\s/]",
                                RegexOptions.IgnoreCase);
        string tagName = m.Groups["tagName"].Value.ToLower();
    
    如果是
    • 非法标签,直接删除掉(用""替换)
      if (Array.IndexOf(allowedTags, tagName) < 0)
      {
          return "";//理解:替换的是标签本身(比如p),还是?
    • 合法标签,清理其中的属性
      private string fixProperty(Match propertyMatch, string[] allowedProperties)
      {
          string property = propertyMatch.Value;
      
          Match m = Regex.Match(property,
                          //(?=exp):零宽断言,这里取属性名
                          @"(?<prop>\S*)(\s*)(?==\s*[" + "\"|'])",
                          RegexOptions.IgnoreCase);
          string propertyName = m.Groups["prop"].Value.ToLower();
      
          //对比fixTag的返回值
          return Array.IndexOf(allowedProperties, propertyName) < 0 ? 
              string.Empty : property;
      }
      return Regex.Replace(tag,
          @"\S+\s*=\s*[" + "\"|" + @" ']\S*\s*[" + "\"|']",  //注意这别扭的写法
          match => fixProperty(match, allowedProperties),
          RegexOptions.IgnoreCase);

请同学们将上述方法封装成扩展方法,^_^


AntiForgeryToken()

复习:CSRF的产生是因为:服务器无法区分用户究竟是不是从“我们指定的页面”发起的HTTP请求。

ASP.NET MVC提供了:

@Html.AntiForgeryToken()

可以生成一个hide input:

<input name="__RequestVerificationToken" type="hidden" value="Zta3V_I0tB8WeYdiPvoLeI13tLvLssD4HskPBxygDHH1RzrT3X2f5vlq_0ONaS85EqJwrDK9NKrTFIv5EdPN51pwAhu2og8w2SbvYcw71g41">
和一个cookie:

__RequestVerificationToken:"a8pG2hMEnHb3NxQdbQhVGcMrP8QOtcH5UZ_uCnZxZ22mZ0wkfST8HsaaKOwiCVkVNS1RLVKt7bc_IgJrc_OJoZ0qwfIhasecPeYbJzrhUc41"在Action上添加一个特性:

[ValidateAntiForgeryToken]
ASP.NET就会根据接收到的hide input和cookie判断用户请求是不是自己生成的页面发起的。

演示:每次刷新页面都会生成不同的hide input和cookie


作业

  1. 文章发布时,过滤用户输入:

    1. 文章内容中(被<pre></pre>框住)的代码部分内容不要过滤,而是HTML转义
    2. 将外链的href="https://zyfei.com/Code/831"替换为href="/outsite?url=https://zyfei.com/Code/831"
    3. 自动提取255字以内摘要(去除html和空格等)    

    且能防范防止CSFR攻击

  2. 通过email重置密码 (考虑全面一点):
    1. 如何获得email地址?
    2. email内容中应包含一个链接,指向密码重置页面
    3. 系统如何通过链接中的url参数确定当前用户是谁,他有无权限修改密码?
学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 ASP.NET 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码