精华内容
下载资源
问答
  • 2019-06-26 01:16:51

    我们先来看一道例题:
    CPU执行一段程序时,cache完成存储的次数为3000次,主存完成存储的次数为400次,已知cache存取周期为50ns,主存存取周期为250ns,求cache/主存系统的效率和平均访问时间?

    思路:cache,中译名高速缓冲存储器,其作用是为了更好的利用局部性原理,减少CPU访问主存的次数。简单地说,CPU正在访问的指令和数据,其可能会被以后多次访问到,或者是该指令和数据附近的内存区域,也可能会被多次访问。因此,第一次访问这一块区域时,将其复制到cache中,以后访问该区域的指令或者数据时,就不用再从主存中取出。
    现在回到开始的问题:当CPU发出读请求时,如果cache命中,就直接对cache进行读操作,与主存无关;如果cache中没有需要的信息,则需要访问主存并把该块信息从主存中调到cache中,再次访问cache获取需要的信息。

    所以:⑴命中率:CPU欲访问的信息已经在Cache中的比率称之为命中率。
    设执行程序时,cache访问次数Nc,访问主存次数Nm,则

    h= N c N c + N m \frac{Nc}{Nc+Nm} Nc+NmNc=0.882

    ⑵平均访问时间:设Tc为命中时cache访问时间,Tm为未命中时主存访问时间
    则Ta=h*Tc+(1-h)*Tm=73.6 ns

    ⑶访问cache效率:e= T c T a \frac{Tc}{Ta} TaTc*100%= T c h ∗ T c + ( 1 − h ) ∗ T m \frac{Tc}{h*Tc+(1-h)*Tm} hTc+(1h)TmTc*100%=0.679

    更多相关内容
  • 引 言  随着集成电路的工作速度和芯片集成度不断提高,芯片的功耗问题变得...Cache平均访问功耗由Cache命中访问功耗、失效时访问功耗和失效率三者决定。失效时访问功耗又包括两部分:一部分是Cache失效时Cach
  • 体系结构19_降低Cache失效率的方法

    千次阅读 2020-02-11 16:57:14
    第一次访问一个块,该块不在Cache中,需从下一级存储器中调入Cache,这就是强制性失效 (冷启动失效,首次访问失效) (2)容量失效(Capacity miss) 如果程序执行所需的块不能全部调入Cache中,则某些...

    1.三种失效(3C)

    (1)强制性失效(Compulsory miss)

         当第一次访问一个块时,该块不在Cache中,需从下一级存储器中调入Cache,这就是强制性失效

        (冷启动失效,首次访问失效)

    (2)容量失效(Capacity miss)

        如果程序执行时所需的块不能全部调入Cache中,则当某些块被替换后,若又重新被访问,就会发生失效。这种失效称为容量失效。

    (3)冲突失效(Conflict miss)

      在组相联或直接映像Cache中,若太多的块映像到同一组(块)中,则会出现该组中某个块被别的块替换(即使别的组或块有空闲位置),然后又被重新访问的情况。这就是发生了冲突失效。

            (碰撞失效,干扰失效

     

    2.三种失效所占的比例

     可以看出:

      (1)相联度越高,冲突失效就越少

      (2)强制性失效不受Cache容量的影响,但容量失效却随着容量的增加而减少;请执行失效和容量失效不受相联度的影响。

      (3)表中的数据符合2:1的Cache经验规则,即大小为N的直接映像Cache的失效率约等于大小为N/2的两路组相联Cache的失效率

    3.减少三种失效的方法

      强制性失效:增加块大小,预取(本身很少)

      容量失效:增加容量  (防止出现抖动现象)

      冲突失效:提高相联度  (理想情况:全相联)

    4.许多降低失效率的方法会增加命中时间或失效开销

    增加Cache块大小

    1.失效率与块大小的关系

    (1)对于给定的Cache容量,当块大小增加失效率开始时下降,后来反而上升。

    (2)Cache容量越大,失效率达到最低的块大小就越大

    2.增加块大小会增加失效开销

    例1: 假定存储系统在延迟40个时钟周期后,每两个时钟周期能送出16个字节。即:经过42个时钟周期,它可提供16个字节;经过44个时钟周期,可提供32个字节;依次类推。试问:对于表5-6中列出的各种容量的Cache,在块大小分别为多少时,平均访存时间最小?假设命中时间为一个时钟周期

    解:

         解题过程

          1KB、4KB、16KB Cache:块大小=32字节

           64KB、256KB Cache:块大小=64字节

    提高相联度

    1. 采用相联度超过8的方法实际意义不大

    2. 2:1 Cache经验规则

         容量为N的直接映像Cache

                                  约等于容量为N/2的两组相联Cache

    3.提高相联度是以增加命中时间为代价

        例如:

                TTL或ECL板级Cache,两路组相联:(板级Cache:以前的CPU中不包含Cache,他俩放在一个板子上)

                增加10%

                定制的CMOS Cache,两路组相联:(Cache做在了CPU里)

                增加2%

    Victim Cache

    1.基本思想

      在Cache和它从下一级存储器调数据的通路之间设置一个全相联的小Cache,用于存放被替换出去的块(称为Victim),以备重用。

    工作过程:

    2.作用

     对于减小冲突失效很有效,特别是对于小容量的直接映象数据Cache,作用尤其明显。例如,项数为4的Victim Cache:使4KBCache的冲突失效减少。  20%~90%(跟程序有关)

    伪相联Cache

    取直接映象及组相联两者的优点:

       命中时间少,失效率低

    缺点: 多种命中时间会使CPU流水线的设计复杂化

    (1)基本思想及工作原理

       在逻辑上把直接映象Cache的空间上下平分为两个区。对于任何一次访问,伪相联Cache先按直接映象Cache的方式去处理。若命中,则其访问过程与直接映象Cache的情况一样。若不命中,则再到另一区相应的位置去查找。若找到,则发生了伪命中,否则就只好访问下一级存储器。

    (2)快速命中与慢速命中

       要保证绝大多数命中都是快速命中

     

     

     

     

    展开全文
  • 在上篇文章讲解整合分布式缓存Redis埋下了一个伏笔:如何让我们的缓存注解支持自定义TTL失效时间呢? 这篇文章本可以不用写,因为其实基于Redis的RedisCacheManager它本身天生就是能够针对不同的Cache配置不同的...

    每篇一句

    不为外界技术更替而动摇,不为眼前无收益而动摇。学一门技术,学到的不仅仅是知识,还有决胜于千里之外的格局

    前言

    在上篇文章讲解整合分布式缓存Redis时埋下了一个伏笔:如何让我们的缓存注解支持自定义TTL失效时间呢?

    这篇文章本可以不用写,因为其实基于RedisRedisCacheManager它本身天生就是能够针对不同的Cache配置不同的TTL的。但是我发现有的小伙伴觉得使用得还是不太方便,希望能在使用注解的时候直接控制失效时间,为了帮助解决小伙伴的这个困惑,这就是我书写本文的目的~

    Spring Cache与失效时间TTL

    首先此处我有必要再次强调一点:Spring Cache抽象本省是并不支持Expire失效时间的设定的,我粗暴的把它归为了Spring Cache抽象的一个设计上的bug,可参考文章:【小家Spring】玩转Spring Cache — @Cacheable/@CachePut/@CacheEvict注解的原理深度剖析和使用

    若想在缓存注解上指定失效时间,必须具备如下两个基本条件:

    1. 缓存实现产品支持Expire失效时间(Ehcache、Redis等几乎所有第三方实现都支持)
    2. xxxCacheManager管理的xxxCache必须扩展了Expire的实现

    因为缓存的k-v键值对具有自动失效的特性实在太重要和太实用了,所以虽然org.springframework.cache.Cache它没有实现Expire,但好在第三方产品对Spring缓存标准实现的时候,大都实现了这个重要的失效策略,比如典型例子:RedisCache

    本文以最为常用的Redis缓存为例,介绍两种控制缓存失效时间的方式。

    实现Cache失效时间的两种通用方式

    接下来就以Redis Cache为例,介绍两种常用的、通用的管理缓存失效时间的方式。

    方式一:使用源生的RedisCacheManager进行集中式控制

    由于控制key的失效时间这一块非常的实用和重要,所以其实Spring Data Redis工程早就给与了支持(不管是1.x版本还是2.x版本)。因此话不多说,直接给个例子就非常清晰明了:

    1、准备Cache配置:

    @EnableCaching // 使用了CacheManager,别忘了开启它  否则无效
    @Configuration
    public class CacheConfig extends CachingConfigurerSupport {
    
        @Bean
        public CacheManager cacheManager() {
            RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofDays(1)) // 默认没有特殊指定的
                    .computePrefixWith(cacheName -> "caching:" + cacheName);
    
            // 针对不同cacheName,设置不同的过期时间
            Map<String, RedisCacheConfiguration> initialCacheConfiguration = new HashMap<String, RedisCacheConfiguration>() {{
                put("demoCache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1))); //1小时
                put("demoCar", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10))); // 10分钟
                // ...
            }};
    
            RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory())
                    .cacheDefaults(defaultCacheConfig) // 默认配置(强烈建议配置上)。  比如动态创建出来的都会走此默认配置
                    .withInitialCacheConfigurations(initialCacheConfiguration) // 不同cache的个性化配置
                    .build();
            return redisCacheManager;
        }
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory() {
            RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
            configuration.setHostName("10.102.132.150");
            configuration.setPort(6379);
            configuration.setDatabase(0);
            LettuceConnectionFactory factory = new LettuceConnectionFactory(configuration);
            return factory;
        }
    
        @Bean
        public RedisTemplate<String, String> stringRedisTemplate() {
            RedisTemplate<String, String> redisTemplate = new StringRedisTemplate();
            redisTemplate.setConnectionFactory(redisConnectionFactory());
            return redisTemplate;
        }
    
    }
    

    使用示例:

    @Service
    public class CacheDemoServiceImpl implements CacheDemoService {
    
    
        @Caching(cacheable = {
                @Cacheable(cacheNames = "demoCache", key = "#id + 0"),
                @Cacheable(cacheNames = "demoCar", key = "#id + 10"),
                @Cacheable(cacheNames = "demoFsx", key = "#id + 100")
        })
        @Override
        public Object getFromDB(Integer id) {
            System.out.println("模拟去db查询~~~" + id);
            return "hello cache...";
        }
    }
    

    运行单元测试

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {RootConfig.class, CacheConfig.class})
    public class TestSpringBean {
    
        @Autowired
        private CacheDemoService cacheDemoService;
        @Autowired
        private CacheManager cacheManager;
    
    
        @Test
        public void test1() {
            cacheDemoService.getFromDB(1);
            cacheDemoService.getFromDB(1);
    
            System.out.println("----------验证缓存是否生效----------");
            Cache cache = cacheManager.getCache("demoCache");
            System.out.println(cache);
            System.out.println(cache.get(1, String.class));
        }
    }
    

    打印结果如下:

    模拟去db查询~~~1
    ----------验证缓存是否生效----------
    org.springframework.data.redis.cache.RedisCache@721eb7df
    hello cache...
    

    缓存生效。去Redis服务端查看对应的key情况:

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

    眼睛尖的小伙伴可能发现了,只有最后一个key前面有caching前缀,其余两个木有,这是为何呢?
    这是我故意留出来的一个小问题,留给小伙伴们自行思考~

    由此可见,通过RedisCacheManager完成了对不同的Cache进行了失效时间的定制化配置,达到了我们的目的。

    小细节

    针对如上的配置,总结如下两点小细节使时需要注意:

    1. 即使禁用前缀disableKeyPrefix(),也是不会影响对应CacheName的TTL(因为TTL针对的是Cache,而不是key
    2. 每个CacheName都可以对应一个RedisCacheConfiguration(它里面有众多属性都可以个性化),若没配置的(比如动态生成的)都走默认配置

    Spring提供的在RedisCacheManager来统一管理Cache的TTL,这种集中式的管理其实是我赞同的方式,若让他分散在各个缓存注解上,反而非常不利于后期的维护管理~~~因此这种方式我也是推荐的

    方式二:自定义cacheNames方式

    虽然我觉得方案一已经能够满足我们需求了,但是广大小伙伴还是觉得使用起来不太自由,毕竟大多数Cache都希望是通过在注解指定CacheNames让其自动生成就行(其实提前追备好有助于提升初次访问的性能)。但是为了便用性摆第一位的话,那就应广大小伙伴的要求,写出本例供以参考

    其实最终我们期望的使用方式如下:

    @Cacheable(cacheNames = "demoCache#3600", key = "#id + 0"),
    

    通过#分隔,后面部分表示此Cache的TTL(单位:秒)

    为了实现这个效果,其实并不难,只需要对RedisCacheManager稍稍的改造一下即可达到目的:

    public class MyRedisCacheManager extends RedisCacheManager {
    
        public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
            super(cacheWriter, defaultCacheConfiguration);
        }
    
        @Override
        protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
            String[] array = StringUtils.delimitedListToStringArray(name, "#");
            name = array[0];
            if (array.length > 1) { // 解析TTL
                long ttl = Long.parseLong(array[1]);
                cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl)); // 注意单位我此处用的是秒,而非毫秒
            }
            return super.createRedisCache(name, cacheConfig);
        }
    
    }
    

    使用我自定义的MyRedisCacheManager配置CacheConfig如下:

    @EnableCaching // 使用了CacheManager,别忘了开启它  否则无效
    @Configuration
    public class CacheConfig extends CachingConfigurerSupport {
    
        @Bean
        public CacheManager cacheManager() {
            RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofDays(1))
                    .computePrefixWith(cacheName -> "caching:" + cacheName);
    
            MyRedisCacheManager redisCacheManager = new MyRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory()), defaultCacheConfig);
            return redisCacheManager;
        }
    
        @Bean
        public RedisConnectionFactory redisConnectionFactory() {
            RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
            configuration.setHostName("10.102.132.150");
            configuration.setPort(6379);
            configuration.setDatabase(0);
            LettuceConnectionFactory factory = new LettuceConnectionFactory(configuration);
            return factory;
        }
    
        @Bean
        public RedisTemplate<String, String> stringRedisTemplate() {
            RedisTemplate<String, String> redisTemplate = new StringRedisTemplate();
            redisTemplate.setConnectionFactory(redisConnectionFactory());
            return redisTemplate;
        }
    
    }
    

    使用示例如下:

    @Service
    public class CacheDemoServiceImpl implements CacheDemoService {
    
        @Cacheable(cacheNames = {
                "demoCache#3600", "demoCar#600", "demoFsx"
        }, key = "#id")
        @Override
        public Object getFromDB(Integer id) {
            System.out.println("模拟去db查询~~~" + id);
            return "hello cache...";
        }
    }
    

    打印结果:

    模拟去db查询~~~1
    ----------验证缓存是否生效----------
    org.springframework.data.redis.cache.RedisCache@53f4c1e6
    hello cache...
    

    缓存生效。Redis Server里查到缓存结果如图(TTL都分别生效了):
    在这里插入图片描述

    说明:demoFsx没有指定TTL,所以走了默认值ttl=1天

    小细节
    1. 同样的,禁用前缀并不影响它的TTL的生效与否
    2. 若在CacheManager已经配置了Cache对应的TTL配置,那就以CacheManager里配置的为准
    3. 多个方法里配置了同一个CacheNameTTL以第一个执行的生成Cache的方法配置的为准

    总之一个原则:TTL是和Cache绑定的,且是在Cache在首次被初始化的时候就被指定好了

    关于此方案,其实还可以扩展一下,比如可以扩展成可配置的如下:

    @Cacheable(cacheNames = "demoCache#${cache.timeout:1800}",key = "#id")
    

    方案提出来,实现此处我就不写了,因为还是比较容易实现的。

    TTL能精确到key吗?

    据我了解,这是很多小伙伴都想问的一个问题,但其实我一直不明白为何有非常多的小伙伴会有这种呼声呢?

    很多小伙伴是希望把TTL写在key上,形如这样书写:

    @Cacheable(cacheNames = "demoCache",key = "#id_3600")
    

    其实这么想的小伙伴,我觉得根本原因是不太能理解cacheNameRedis的key的关系导致的(本文以Redis为例~)

    我此处不直接解答这个问题,但我对此额外抛出3个问题,相信答案就不攻自破了:

    1. 为何同一个Cache下管理的key你需要不同的TTL???(这种设计本身就不合理吧)
    2. 在不禁用前缀的情况下,cacheName默认都会反映到key上。因此即使你有这种特殊需求,你也可以通过定义特殊的CacheName来实现
    3. 若你真想控制到key这种细粒度,我只能说:实现成本太高了且会打破一定的封装性,后续扩展受限

    综合来说,不管从场景上还是技术上,我都是极力不推荐这种行为的。

    总结

    本文主要介绍了让缓存注解支持TTL失效时间,提供的两种方式都可以用在生产环境中。合理的使用、控制失效时间,能让你的应用更加的高效,缓存利用得更合理。

    另外关于Spring缓存其实还有一个重要知识点:缓存即将过期时主动刷新缓存
    因为缓存失效后,就会有一些请求会打到DB上,这段时间如果是高并发的话DB压力就很大(sync=true可以有一定的缓解作用),DB就很危险,容易造成雪崩。
    因此我们是期望在缓存即将过期的某一时间点,后台主动去更新缓存以确保前端请求的缓存命中率。关于这部分的实现,只有在高并发系统下才有需求,有兴趣和有需要的小伙伴可往这方面考虑一把~


    关注A哥

    AuthorA哥(YourBatman)
    个人站点www.yourbatman.cn
    E-mailyourbatman@qq.com
    微 信fsx641385712
    活跃平台
    公众号BAT的乌托邦(ID:BAT-utopia)
    知识星球BAT的乌托邦
    每日文章推荐每日文章推荐

    BAT的乌托邦

    展开全文
  • 系统结构第四次作业

    2014-06-30 23:03:29
    写出三级 cache 的平均访问时间的公式。给定以下的假设,试计算直接映像 Cache 和两路组相联 Cache 的平均访问时间以及 CPU 的性能。由计算结果能得出什么结论?
  • 失效访问控制

    千次阅读 2018-08-16 11:25:05
    失效访问控制 出现的问题 文件包含/目录遍历 权限绕过(越权) 权限提升(提权) 不安全直接对象的引用 访问控制的(防御)思路 基于角色的访问控制(RBAC) 自由访问控制(DAC) 强访问控制(MAC) 基于权限的...

    失效的访问控制

    这是我在OWASP上几篇文章翻译整理加删减总结出的一个关于失效的访问控制的检查可解决的文章。勉强算个原创吧。

    由于缺乏自动化的检测和应用程序开发人员缺乏有效 的功能测试,因而访问控制缺陷很常见。导致攻击者可以冒充用户、管理员或拥有特权的用户,或者创建、访问、更新或删除任何记录。

    出现的问题

    文件包含/目录遍历

    许多web应用使用文件管理作为它们日常操作的一部分。但他们使用没有被好好设计的输入验证方法,攻击者可以利用(这个漏洞)来修改或写入文件,甚至执行任意代码。

    传统的web服务器和web应用程序用身份验证来控制文件资源访问。web服务器尝试将用户的文件限制在“根目录”或“web文档根”中,后者标识文件系统层面的物理目录。用户必须将此目录十位web应用程序层次结构的基本目录。

    许多web应用程序使用服务器端脚本来包含不同类型的文件。如管理图像,模板,加载静态文本等,但如果未正确验证输入参数(如表单,cookie)这些程序会暴露安全漏洞。这种问题出现在路径遍历/文件包含攻击中。通过利用此类漏洞,攻击者能读取它们通常无法读取的目录或文件,访问web文档根目录之外的数据,或包含来自外部网络的脚本或其他类型文件。

    如臭名昭著的%5c 暴库或dot-dot-slash (../)目录遍历,目录爬升或回溯。

    例子

    http://example.com/getUserProfile.jsp?item=ikki.html 
    http://example.com/getUserProfile.jsp?item=../../../../etc/passwd

    若getUserProfile.jsp是从文件加载静态信息并向用户显示,如果在访问控制不理想的情况下,攻击者可以构造相对路径,读取etc/passwd的文件内容。

    其他地方也可能有类似漏洞如cookie:

    Cookie:USER = 1826cc8f:PSTYLE = GreenDotRed
    Cookie:USER = 1826cc8f:PSTYLE = .. / .. / .. / .. / etc / passwd

    也可能包含外部网站的文件:

    http://example.com/index.php?file=http://www.owasp.org/malicioustxt

    如果可接受协议类参数,也可以构造如下攻击:

    http://example.com/index.php?file=file:///etc/passwd

    或探测本地服务:

    http://example.com/index.php?file=http://localhost:8080http://example.com/index.php?file=http://192.168.0.2:9080

    甚至可以不使用任何目录遍历字符开显示CGI组件源代码:

    http://example.com/main.cgi?home=main.cgi

    main.cgi的组件和普通html静态文件在同一个目录中,在某些情况下,攻击者使用. %00 null等的编码可以绕过扩展名校验。

    关于不同操作系统的路径分隔符

    Linux
    根目录:“/” 
    目录分隔符:“/”
    Windows
    根目录:“<驱动器号>:\”   
    目录分隔符:“\”或“/”
    Mac OS
    根目录:“<驱动器号>:” 
    目录分隔符:“:”

    url编码与双url编码绕过:

    %2e%2e%2f 表示 ../
    %2e%2e / 表示 ../ 
    ..%2f 表示 ../
    %2e%2e%5c 表示 .. \ 
    %2e%2e \ 表示 .. \ 
    ..%5c 代表 .. \ 
    %252e%252e%255c 代表 .. \ 
    ..%255c 代表 .. \等等。

    Unicode/UTF-8编码绕过

    ..%c0%af 表示 ../ 
    ..%c1%9c 代表 .. \

    Windows shell中,解析文件非常灵活,如以下任何内容附加到shell命令中使用的路径会导致函数没有区别:

    • 路径末端的尖括号“>”和“<”
    • 在路径末尾双引号(正确关闭)
    • 无关的当前目录标记,例如“./”或“。\”
    • 具有可能存在或可能不存在的任意项的无关父目录标记
    -  file.txt 
    -  file.txt ... 
    -  file.txt <spaces> 
    -  file.txt“”“” 
    -  file.txt <<< >>> < 
    -  ./././file.txt 
    - nonexistant / ../file.txt

    在任何shell命令或API调用中使用时,下面的符号会被丢弃,其中字符串被视为文件名:

    句号
    空格

    Windows UNC文件路径:用于引用SMB共享上的文件。有时,可以使应用程序引用远程UNC文件路径上的文件。如果是这样,Windows SMB服务器可能会将存储的凭据发送给攻击者,攻击者可以捕获并破解。这些也可以与自引用IP地址或域名一起使用来逃避过滤器,或者用于访问攻击者无法访问的SMB共享上的文件,但可以从Web服务器访问。

    \\ server_or_ip \ path \ to \ file.abc 
    \\\ server_or_ip \ path \ to \ file.abc

    Windows NT设备命名空间:用于指代Windows设备命名空间。某些引用将允许使用不同的路径访问文件系统。

    • 可能相当于驱动器号,例如c:\,甚至是没有指定字母的驱动器卷。

      \\.\GLOBALROOT\Device\HarddiskVolume1\
    • 指机器上的第一个光盘驱动器。

      \\.\CdRom0\

    权限绕过(水平越权)

    用户未经过身份验证访问资源,或注销后仍可访问资源,对不同用户访问的资源没有做很好的校验,如标准用户可访问管理员资源,或访问其他用户私有资源等。

    例子

    下面例子的url是管理员彩蛋的一部分:

     https://www.example.com/admin/addUser.jsp 

    访问这个页面你的HTTP请求如下:

    POST /admin/addUser.jsp HTTP/1.1
    Host: www.example.com
    [other HTTP headers]
    
    userID=fakeuser&role=3&group=grp001

    如果一个非管理员用户发送这个请求到服务器,会执行什么操作,在权限验证和访问控制不理想的情况下,非管理员用户通过构造管理员相应操作的数据包,也能达到管理员的权限。如增加/删除用户等。

    权限提升(垂直越权)

    权限提升是指用户权限从一个阶段提升到另一个阶段的问题,当用户访问的资源比通常情况下访问到的资源更多时,就发生了权限提示漏洞,应用程序应该阻止该权限提升或更改。权限提升一般是由于应用程序自身的缺陷引起的,最后导致程序执行的操作拥有比开发人员或系统管理员预期更多的权限。

    例子

    下面的HTTP POST请求允许属于grp001的用户访问#0001订单:

     POST /user/viewOrder.jsp HTTP/1.1
     Host: www.example.com
     ...
    
     groupID=grp001&orderID=0001

    如果对权限的校验不正常的情况,一个不属于grp001的用户修改groupID参数也可获得查看#0001的权限。

    操纵用户配置权限:下面服务器的响应显示校验成功后返回给用户的HTML中的隐藏字段。

    HTTP/1.1 200 OK
    Server: Netscape-Enterprise/6.0
    Date: Wed, 1 Apr 2006 13:51:20 GMT
    Set-Cookie: USER=aW78ryrGrTWs4MnOd32Fs51yDqp; path=/; domain=www.example.com 
    Set-Cookie: SESSION=k+KmKeHXTgDi1J5fT7Zz; path=/; domain= www.example.com
    Cache-Control: no-cache
    Pragma: No-cache 
    Content-length: 247
    Content-Type: text/html
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
    Connection: close
    
    <form  name="autoriz" method="POST" action = "visual.jsp"> 
    <input type="hidden" name="profile" value="SysAdmin">
    <body onload="document.forms.autoriz.submit()">
    </td>
    </tr>

    如果我们将profile改为”SysAdmin”,可能会变成管理员。

    操纵条件值:在服务器发送错误消息时,该消息包含在一组相应代码中的特定参数中,如:

    @0`1`3`3``0`UC`1`Status`OK`SEC`5`1`0`ResultSet`0`PVValid`-1`0`0` Notifications`0`0`3`Command  Manager`0`0`0` StateToolsBar`0`0`0`    
    StateExecToolBar`0`0`0`FlagsToolBar`0

    如果我们将“PVValid”从-1改为0,那可能代表没有错误,从而通过管理员身份验证

    操纵IP地址:某些网站使用IP地址来限制访问或根据IP地址计算错误登录次数,如:

    X-Forwarded-For: 8.1.1.1

    如果可以修改X-Forwarded-For就可以绕过这种检验

    URL遍历:尝试遍历网站查看是否有页面漏掉权限检验

    /../.././userInfo.html

    弱SessionID:

    若SessionID加密算法很弱,或使用有规律的算法,可能会被攻击者猜到或解密,造成越权。

    不安全直接对象的引用

    当应用程序根据用户提供的输入提供对对象的直接访问时,会发生不安全的直接对象引用。 攻击者可以直接绕过授权并访问系统中的资源,例如数据库记录或文件。

    由于应用程序获取用户提供的输入并使用它来检索对象而不执行足够的授权检查。不安全的直接对象引用允许攻击者通过修改用于直接指向对象的参数值来直接绕过授权和访问资源。这些资源可以是属于其他用户的数据库条目,系统中的文件等。

    例子

    参数值直接用于数据库检索:

    http://foo.bar/somepage?invoice=12345

    参数invoice的值直接进入发票数据库检索,并将结果显示,如不对检索对象进行校验,那么攻击者可以遍历发票编号造成信息泄露。

    参数值直接在系统中操作:

    http://foo.bar/changepassword?user=someuser

    user参数值用于告诉应用程序用户访问哪个功能,若没有对用户本身作出限制,那么用户修改user参数,可能造成越权访问功能。

    访问控制的(防御)思路

    授权是应该授予或拒绝访问特定资源的请求的过程。Web应用程序需要访问控制以允许用户(具有不同的权限)使用该应用程序。他们还需要管理员来管理应用程序访问控制规则以及向用户和其他实体授予权限或权利。提供各种访问控制设计方法。要选择最合适的风险评估,需要执行风险评估以识别特定于您的应用程序的威胁和漏洞,以便适当的访问控制方法适合您的应用程序。

    基于角色的访问控制(RBAC)

    在基于角色的访问控制(RBAC)中,访问决策基于个人在组织或用户群中的角色和职责。

    定义角色的过程通常基于分析组织的基本目标和结构,并且通常与安全策略相关联。例如,在医疗机构中,用户的不同角色可能包括医生,护士,服务员,护士,患者等等。显然,这些成员需要不同级别的访问才能执行其功能,但也需要根据安全政策和任何相关法规(HIPAA,Gramm-Leach-Bliley等)。

    RBAC访问控制框架应该为Web应用程序安全管理员提供确定的“谁可以执行哪些操作,何时,从何处,以何种顺序以及在某些情况下在什么关系环境下“执行操作的能力。

    使用此方法的优点是:

    • 角色是根据组织结构分配的,重点是组织安全策略
    • 使用方便
    • 易于管理
    • 内置于大多数框架中
    • 符合职责分离和最低特权等安全原则

    使用此方法时可能遇到的问题:

    • 必须严格保持角色和访问的文档。
    • 除非有办法将角色与多租户功能要求相关联,例如Active Directory中的OU,否则无法有效实施多租户
    • 存在范围蔓延的趋势,例如可以给出比预期更多的访问和特权。或者,如果未执行适当的访问查看和后续撤销,则用户可能包含在两个角色中。
    • 不支持基于数据的访问控制

    使用RBAC时的注意事项是:

    • 必须使用严格的签名和流程来转让或委派角色。
    • 当用户将其角色更改为另一个角色时,管理员必须确保撤消先前的访问权限,以便在任何给定的时间点,仅在需要知道的基础上将用户分配给那些角色。
    • 必须使用严格的访问控制审查来执行RBAC保证。

    自由访问控制(DAC)

    自由访问控制(DAC)是一种基于用户身份和某些组成员身份限制对信息的访问的方法。访问决策通常基于授权给用户的授权,该授权基于他在认证时呈现的凭证(用户名,密码,硬件/软件令牌等)。在大多数典型的DAC模型中,信息所有者或任何资源都可以自行决定更改其权限 。

    DAC框架可以为Web应用程序安全管理员提供实现细粒度访问控制的能力。该模型可以作为基于数据的访问控制的实现的基础 。

    使用此模型的优点是:

    • 使用方便
    • 易于管理
    • 符合最小特权原则。
    • 对象所有者完全控制授予的访问权限

    使用此方法时可能遇到的问题:

    • 必须严格保持角色和访问的文档。
    • 除非有办法将角色与多租户功能要求相关联,例如Active Directory中的OU,否则无法有效实施多租户
    • 存在范围蔓延的趋势,例如可以给出比预期更多的访问和特权。

    使用DAC时的注意事项是:

    • 在给予信任的同时DAC保证必须使用严格的访问控制审查。

    强访问控制(MAC)

    强制访问控制(MAC)确保组织安全策略的实施不依赖于Web应用程序用户的合规性。MAC通过在信息上分配敏感标签并将其与用户操作的灵敏度级别进行比较来保护信息。MAC通常适用于极其安全的系统,包括多级安全军事应用或关键任务数据应用。

    使用此方法的优点是:

    • 对对象的访问权限取决于对象的敏感性
    • 严格遵守基于需要知识的访问,并且范围蠕变具有最小可能性
    • 只有管理员才能授予访问权限

    使用此方法时可能遇到的问题:

    • 实施起来困难且昂贵
    • 不灵活

    使用MAC时的注意事项是:

    • 在适当和务实的层面上进行分类和敏感性分配
    • 必须执行MAC保证以确保对象的分类处于适当的级别。

    基于权限的访问控制

    基于权限的访问控制中的关键概念是将应用程序操作抽象为一组权限。权限可以被简单地表示为一个基于名称的字符串,例如“读”。通过检查当前用户是否具有与所请求的应用程序动作相关联的许可来做出访问决定。

    用户和许可之间关系可以通过创建用户和权限(称为间接关系满足许可)来表示。在间接模型中,权限授予是指中间实体,例如用户组。当且仅当用户从用户组继承权限时,才将用户视为用户组的成员。间接模型可以更轻松地管理大量用户的权限,因为更改分配给用户组的权限会影响用户组的所有成员。

    在一些基于权限的提供细粒度域对象级访问控制的访问控制系统中,可以将权限分组到类中。假设系统中的每个域对象可以与确定与相应域对象的许可的类关联。在这样的系统中,可以用权限“READ”,“WRITE”和DELETE“定义”DOCUMENT“类;可以用权限”START“,”STOP“和”REBOOT“定义”SERVER“类。

    访问控制验证要求

    描述
    验证最小特权的原则:用户应仅能够访问函数、数据文件、URL、控制器、服务和其他资源,它们处理特定的授权,它们使应用程序免受欺骗和提权。
    验证对敏感记录的访问是否实施了保护措施,这样只有授权的对象或数据才允许访问(例如:防止用户篡改参数或更改其它用户账户)
    验证目录遍历是禁用的,除非故意为之。此外应用程序不应允许发现或泄露文件或目录元数据,例如:Thumbs.db、.DS_Store、.git或.svn
    验证访问控制是否以安全的方式显示失败处理。
    验证表示层访问控制规则是否在服务器端强制执行。
    验证访问控制使用的所有用户和数据属性、策略信息不能被终端用户操纵,除非特别授权。
    验证是否存在集中化机制(包括调用外部授权服务的库),以保护对每种受保护资源的访问。
    验证是否可以记录所有访问控制决定,并记录所有失败的决定。
    验证应用程序或框架是否使用强大的随机数(抵御CSRF令牌)或具有其他事务处理保护机制。
    验证系统能抵御对安全功能、资源或数据的持续访问。例如,考虑使用资源治理器来限制每小时编辑的数量,或阻止整个数据库被单个用户独占。
    验证应用程序是否具有针对较低价值系统的额外授权(例如,升级或自适应认证)或高价值应用程序的职责隔离,以根据应用程序和过去欺诈的风险执行反欺诈控制。
    验证应用程序是否正确强制执行了上下文相关的授权,以进制通过参数篡改进行未授权的操作。
    展开全文
  • x86系统cache locking的原理

    千次阅读 2020-04-04 21:52:49
    cmpxchg 本身不是原子的,需要加 lock 才是原子的,而 lock 是通过锁内存总线来实现原子性的。...一个元器件读内存就会占用总线,读完后再解除对总线的占用,其它元器件才能进总线继续访问内存,任何元器件不会在...
  • 1.程序访问局部性   计算机存储层次结构 为提高性能/价格,将各存储器组成一个金字塔式的层次结构,取长补短协调工作 ...•需从(向)存储器中取(存) 数,先访问cache;若在,取自cache •若不在cache...
  • 在信息按这种映射关系装入Cache后,CPU执行程序,会将程序中的主存地址变换成Cache地址,这个变换过程叫做地址变换。 Cache的地址映射方式有直接映射、全相联映射和组相联映射。假设某台计算机主存容量...
  • cache是小容量、高速缓冲存储器,由SRAM组成,速度几乎和CPU一样快。一般将cache和主存的存储空间都划分为若干大小相同的块
  • 降低Cache失效率--编译器优化

    千次阅读 热门讨论 2014-01-04 01:14:40
    (Compulsory miss): 第一次访问一个块,该块不在 Cache中, 需从下一级存储中调入 Cache, 这就是强制性失效。这种失效也称为 冷启动失效 ,或 首次访问失效 。(增加块大小,预取) (2). 容量失效 ...
  • tc表示命中cache访问时间,tm表示未命中的贮存访问时间,ta表示 cache/主存系统的平均访问时间 ta = h×tc + (1-h)×tm r表示主存慢于cache的倍率,r = tm/tc;e表示访问效率。 e = tc / ta ...
  • 如何提升 Cache 的性能

    2021-01-25 16:51:33
    如何提升 Cache 的性能如何提升 Cache 的性能1 Cache 的基本结构与原理2 评估 Cache 的性能3 通过降低失效率来提升 Cache 性能3.1 Cache 失效的原因有如下三种:3.2 通过适当调整块大小来降低失效率3.3 通过编译器...
  • Cache的特征

    2021-02-24 11:10:14
    Allocation 在CACHE中发现一个位置,并把新的cache数据存到这个位置的过程。...Capacity miss容量失效 因为cache的容量限制,导致不能包括一个程序的整个working set(工作集),从而造成cac...
  • Spring Cache扩展:注解失效时间... Spring Cache默认是不支持在@Cacheable上添加过期时间的,可以在配置缓存容器统一指定: @Bean public CacheManager cacheManager( @SuppressWarnings("rawtypes")...
  • 高并发之——Guava Cache

    千次阅读 2019-10-27 11:18:02
    最近需要用到缓存来存放临时数据,又不想采用Redis,Java自带的Map功能太少,发现Google的Guava提供的Cache模块功能很强大,于是选择使用它。 本地缓存 本地缓存作用就是提高系统的运行速度,是一种空间换时间的...
  • 浅谈ARM存储系统cache

    千次阅读 2018-03-03 15:12:11
    而一般的SDRAM的存储周期是很慢的,相对于CPU来说,这时,如果我们把程序和数据都存储在SDRAM中,那么CPU在读取指令和数据的时候,就会受到SDRAM速度的限制,大大地制约了整个系统的性能。那么有没有什么改善的办法...
  • ElasticSearch 查询需要占用 CPU、内存资源,在复杂业务场景,会出现慢查询,需要花费大量的时间。为了提高系统的性能,除了增加集群硬件配置这种...对一个或多个索引发送搜索请求,搜索请求首先会发送到ES集...
  • 缓存篇(二)- JetCache

    万次阅读 多人点赞 2018-09-28 19:27:25
    本文将由浅入深,从基本特性介绍,从简单demo使用,到JetCache源码分析,到Spring Aop的源码分析,到如何利用这些知识去自己尝试写一个自己的cache小demo,去做一个全面的概括。 *背景和特性 *用法demo *JetCache...
  • 【计算机系统结构】第5章 存储层次

    千次阅读 2018-06-15 20:52:19
     多级存储层次由若干个采用不同实现技术的存储器构成的存储器系统。各存储器处在离CPU不同距离的层次上。其目标是速度接近于离CPU最近的存储器的速度,容量达到离CPU最远的存储器的容量。 3. 命中率HCPU在第一级...
  • Cache与主存之间的全相联映射,直接映射和组相联映射的区别1.高速缓冲存储器的功能、结构与工作原理 高速...目的是提高CPU对存储器的访问速度。为此需要解决2个技术问题:一是主存地址与缓存地址的映象及转换; 二是
  • CPU | Cache 基本概念和基本原理

    千次阅读 2019-01-07 23:34:29
    一 、Cache的基本概念 Allocation  在cache中发现一个位置,并把新的cache数据存到这个位置的过程。这个处理过程可能包括 evicting(驱逐)cache中已存在的数据,从而为新的数据腾出空间。 Associativity 关联...
  • SpringBoot整合Spring Cache,简化分布式缓存开发

    千次阅读 多人点赞 2021-07-16 13:44:04
    这篇博文,我们介绍,SpringCache,以及SpringCache是如何来统一不同的缓存技术以高效便捷的方式接入到项目中,最后,深入讲解SpringCache是如何解决缓存击穿,缓存穿透,缓存雪崩的,还有哪些不足。
  • Linux内存之Cache

    千次阅读 2020-12-09 17:22:11
    Cache容量小但速度快,内存速度较低但容量大,通过优化调度算法,可以让系统的性能大大改善,感觉就像是又有了主存储器的内存,又有了Cache访问速度。 1.2、程序是如何运行的? 我们先思考一个问题:我们的程序是...
  • 第5章 存储层次 1. 单级存储器的主要矛盾是什么?通常采取什么方法来解决?...存储层次的平均每位价格、命中率或失效率、平均访问时间。 3. “Cache-主存”和“主存-辅存”层次的主要区别是什么? ...
  • 这里总结几个Linux文件缓存(page cache)使用情况、命中率查看的工具。perf-tools里面的cachestat来自于大名鼎鼎的Brendan Gregg的cachestat,已经被加到他的perf-toolshttp://...
  • Cache

    千次阅读 2020-04-08 18:27:31
    什么是Cache 高速缓存(Cache)存储器是一种位于CPU和...在一个较短时间间隔内,CPU对局部范围的存储器地址频繁访问,而对此地址范围之外的地址访问很少,这种现象被称为程序访问的局部性。 Cache的工作过程 C...
  • 今天小编带来一个超猛的好东西,可以提升电脑磁盘读写性能10-70倍不等 ...PrimoCache是一款缓存加速软件,可与系统内存、固态(SSD)硬盘和闪存盘等高速存储设备配合使用,以加速相对较慢的存储设备。 简单的原理说明

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 71,421
精华内容 28,568
关键字:

当访问cache系统失效时