zoukankan      html  css  js  c++  java
  • 深入理解正则表达式-----应用于检测csrf的正则表达式

    如何写检测和防御csrf的规则?我们可以利用正则表达式进行匹配。对POST包进行正则匹配,这里只是提供了一个思路。

    pcre:"
    /POST /(?P<uri>.*?) HTTP((?! ).)*?
    Host: (?P<host>[^ ]*?)((?! ).)*?
    Referer: https?://((?!(?P=host))|[^/]*?/(?!(?P=uri)))/ims";

    如何理解该正则表达式?(我们尽量用大白话解释,要不扯那么多专业术语谁能看懂,哼,又不是写论文)

    首先要说明的是此处检测的类型是 referer字段 由不同源的地址构造的情况。通俗的解释就是referer字段本来应该是指的你的该连接是从哪里指过来的,假如存在csrf,攻击者可以从其他的网站伪造请求,从而使得该网站执行攻击者的请求。

    道理十分简单,大白话就是referer字段中要么包含post的字段,要么包含host字段。例如下图所示,referer字段就是host字段的内容。

    只利用正则表达式如何进行检测?上述的正则表达式就是干的这个事情,同时也是比较巧妙的。

    pcre:"
    /POST /(?P<uri>.*?) HTTP((?! ).)*?    
    Host: (?P<host>[^ ]*?)((?! ).)*?
    Referer: https?://((?!(?P=host))|[^/]*?/(?!(?P=uri)))/ims";

     我们对上面的正则表达式的各个点进行一下讲解。(本来计划只说一下比较难理解的,如果你会的话,请回答一下下面的问题,总有你不会的,哼,小样,就正则表达式这种非人类的东西,能天天都记住?!)推荐用kiki进行测试一下,如果遇到不懂的话。

    1、/POST当中的 / 代表什么意思?

    答:开头的 / 表示正则表达式要开始了,就是这么个意思,如果中间过程中还需要用到 / 的话就需要进行转义,使用 / 。同时POST呢,就是要匹配post字段,这条csrf检测规则主要是检测post包的么。

    2、/这个理解了吗?(要转义)

    3、(?P<uri>.*?)这个玩意是个神马东西??

    答:首先(1).*?是啥么意思?  .* 是匹配多个非换行符外的字符串,那多一个?是不是就有点mengbility。这里的?是懒惰模式的意思,就是只要匹配到一次就停止的意思

        (2)(?P<uri>.*?)这个应用叫做后向引用,大致的格式(?P<name>表达式),意思就是给此时表达式匹配到的内容起个名字叫做name。当你以后需要用到同样的内容的时候直接用name就可以了。举个例子就是妈妈生下了你,并给你取了个名字,以后直接用名字就可以代指你了,并不需要还是喊那个孩子。那在我们的这个例子中就是"POST /ajax/login_h.jsp?cmd=loginCorpNew&dogSrc=3"中匹配到ajax/login_h.jsp?cmd=loginCorpNew&dogSrc=3,并把这段命名为uri。以后再需要这段内容的时候,我们可以用uri这个名字进行检测。

    4、HTTP((?! ).)*?这个玩意是神马东西?

    答:HTTP((?! ).)*? 这个应用叫做负向零宽断言,大致的格式是(?!exp),意思就是在这个位置后面不能匹配到什么的意思。在这里就是匹配不是” “的任意元字符很多次,直到遇到下一个匹配单元,上面的例子就是Host:,也就说直到遇到Host:就停下来。上述的话(图片中)这段就匹配的是 HTTP /1.1。

    5、Host: (?P<host>[^ ]*?)是什么,[^ ]*?到底干了啥?

    答:首先Host:匹配到,同时 (?P<host>[^ ]*?)依旧是个后向引用,你不需要记住这个名词,反正知道就是给[^ ]*?取了个名字叫做host,那么问题来了,[^ ]*?到底匹配了个啥东西??

    此处[^ ]就是不是换行的意思,那么不是换行的话是不是就把Host: 这一行给匹配上了。在此例子中就是www.faisco.com,一换行后面的东西就不属于[^ ]*?匹配到的东西了。

    接下来的((?! ).)*?就是像上面的解释一下,知道碰到Referer: 就停下了。仔细想想,不详细解释了。

    6、Referer: https?:// 这个里面怎么跑出https了??

    答:这里的https? ,后面这个?有学问,意思就是前面的这个s可以有,也可以没有。所以此时可以匹配http和https两种。

      此处挖一个坑,假如是https??,有两个问号呢??又会是什么情况?

      其实第一个问号和上述的方式是一样的,对‘s’进行0次或者多次匹配。第二个?是开启懒惰模式,那么在懒惰模式下,就只能匹配到http了。(懒惰模式,既然s可以有0次或者其他次,反正我懒,我就不匹配0次,所以此处只能有http)

      那么// 呢?请看第二问,是不是一个转义啊,嗯,是的,很简单!

    7、(?!(?P=host))是啥意思??

    答:这里就是对负向零宽断言和后向引用的使用。意思就是这里不是上述我们命名为host的那个东西。(?!表达式)是负向零宽断言,表示这里不能是这个玩意。(?P=host)是我们在后向引用用到的,就是表示刚才我们刚才定义的host的那一串东西。

    (?!(?P=uri))意思和上述是一样的。就不详细解释了。

     8、((?!(?P=host))|[^/]*?/(?!(?P=uri))) 这里的 | 表示啥意思? [^/]*?/又是啥意思??

    答:这里 (a|b)的形式意思就是不匹配a,那么就是b.用在检测csrf实际案例当中就是referfer要么是http://www.faisco.com,要么就是http://www.faisco.com/ajax/login_h.jsp?cmd=loginCorpNew&dogSrc=3(这里仅仅是举一个栗子,不要当真,这个栗子吃了会造成不消化)。

    (?!(?P=host))的意思就是你这里不是www.faisco.com的话,你就是一个坏人,有可能是csrf攻击的流量。

    [^/]*?/(?!(?P=uri))呢?

    [^/]*?/意思是不是/的字符都给匹配上,在这里呢,就是把http://和第一个/之间的www.faisco.com匹配上,同时再加上/,就是http://www.faisco.com/匹配上了。剩下一个(?!(?P=uri)),意思就是检测上述提到叫做uri的这一串东西是不是等于ajax/login_h.jsp?cmd=loginCorpNew&dogSrc=3,如果不等于,那么你就被抓住了,就被认为是csrf的恶意流量。

    9、/ims

    /i  忽略大小写

    /m 将串视为多行

    /s 将串视为单行

    一堆修饰符,可以自行查找。

    总结:

    1、正则表达式很非人类,需要进行测试来进行理解。推荐kiki(我的机器是ubuntu,不知道windows下是什么工具)

    2、csrf防御依旧可以用正则表达进行检测,并不是不能做检测的。但是仅仅能检测referfer字段的问题,是不是想一想id/ps可以写出针对token的规则。

    3、耐心,耐性。很重要!

  • 相关阅读:
    第二篇:后端导出 Excel
    while 循环、for 循环
    <textarea></textarea>多行文本域
    git 基本命令
    如何让div可选中,有聚焦、失焦等事件。
    [leetcode]205. Isomorphic Strings
    [leetcode]204. Count Primes
    Here is a 10-line template that can solve most 'substring' problems子字符串问题的模板
    [leetcode]76. Minimum Window Substring
    [leetcode]166. Fraction to Recurring Decimal
  • 原文地址:https://www.cnblogs.com/lcamry/p/6732775.html
Copyright © 2011-2022 走看看