基于安全的一些思考--竞态条件
来源:互联网 发布:阿里云 健康管理平台 编辑:程序博客网 时间:2024/06/10 18:27
竞态条件(race condition)是最常见的一类软件错误,只可能出现在多线程或者进程同时发生并有潜在交互的环境下(或其他异步处理,如UNIX信号量)
控制机器资源的额攻击者可以通过降低机器的运行速度来增加利用竞争条件的机会
以下给出一个java servlet程序:
import java.io.*
import java.servlet.*
import java.servlet.http.*
public class Counter extends HttpServlet{
intcount = 0;
publiccoid doGet(HttpServletRequest in,HttpServletResponseout)
throwsServletException{
out.setContentType("text/plain");
Printwriterp = out.getWriter();
count++;
p.println(count+ "hits so far");
}
}
包含了竞争条件,因为java servlet是多线程的。
假设A、B几乎同时访问,A在前,此时count是1,A在运行println之前B使count变为2,则A打印出了2
这个漏洞窗口不大,最多是几分之一秒
即使将计数器的增加语句放进打印语句中如:
p.println(++count+”hits si far”);
也无济于事,因为调用println以及给参数赋值都要花费时间
要想保证可靠,实现的主要策略是使相关的代码和数据“原子化”:原子化,就是指关联代码的执行是一个整体,操作执行时不会有其他事情发生。竞态条件发生的情况是程序员假设某些操作是原子的方式发生的。
将一个操作原子化,我们通常使用加锁原语,尤其是在多线程环境。
例如,修复前面代码的方法是 ,通过synchronized keyword使用servlet上的对象锁。Synchronized关键字阻止其控制的对象同时被多线程调用。例如,在一个java类中有10个synchronized方法,任何时候都只有一个线程能运行其中的一个方法。JVM的实现负责实施synchronized关键字的语义。
修改如下:
import java.io.*
import java.servlet.*
import java.servlet.http.*
public class Counter extends HttpServlet{
intcount = 0;
publicsynchronized void doGet(HttpServletRequest in,HttpServletResponse out) throwsServletException,
IOException{
out.setContentType("text/plain");
Printwriterp = out.getWriter();
count++;
p.println(count+"hitsso far");
}
}
本例中一个时间段只能有一个线程运行servlet,以为doGet是程序的入口。这种方案影响效率。所以我们要使原子化的代码(通常称为临界区(criticalsection))尽可能小
可以看到,当两个或多个事件发生时,并且后一个操作依赖于前一个操作,竞争条件的情况就有可能出现
当涉及可利用的文件系统的竞争条件时,一下几个条件必须要成立:
首先,攻击者必须能访问本地机器,无论是否合法,其次,有竞争条件的程序必须以root的EUID运行,第三,程序必须在竞争条件存在的时间内保持这个EUID
避免TOCTOU的一个方法是,避免直接使用文件名的系统调用,而是代之以使用文件句柄或文件描述符的调用。使用文件描述符或文件指针,可以保证对文件的操作在第一次处理它之后不会被暗中改变
- 基于安全的一些思考--竞态条件
- 基于安全的一些思考--缓冲区溢出
- 基于安全的一些思考--总览
- 基于安全的一些思考--访问控制
- 基于安全的一些思考--随机性与密码学
- 对线程安全的一些思考
- 关于MongoDB安全事件的一些思考
- 基于BroadCast Receiver的一些思考
- 关于基于成本定价的一些思考
- 关于工控系统信息安全的一些思考
- 基于当下对 互联网产品 的一些思考
- 安全态势感知:一些哲学思考
- 互斥锁与条件变量(基于控制输出面试题的思考)
- 数据结构——基于粗粒度锁和条件变量的线程安全队列
- 软件工程的一些思考
- FacadeLayer的一些思考
- 软件设计的一些思考
- 软件工程的一些思考
- 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
- 用for双重循环打印100-200之间的质数
- Spring集成redis问题(一)
- Windows静态库和动态库的调用方法汇总
- API文档生成工具——Doxygen
- 基于安全的一些思考--竞态条件
- 邮件
- C++ 的MFC 和ATL 及COM 是什么?
- Django学习03---urls.py路由用法与实例
- git 上传命令
- Ice系列——HelloIce
- 等差数列 2,5,8,11,14。。。。 输入:正整数N >0 输出:求等差数列前N项和
- 基于安全的一些思考--随机性与密码学
- Python学习随笔四:使用str,dic和set