概述
简述:入职菊厂第一周,没什么任务,正全力准备java安全编码考试,跟阿里规范类似,不过要多很多安全攻防的内容和一些之前没注意的知识点,所以记录分享自己学到的经验
命名规范
类似阿里规范,省略一万字...
编码规范
整数溢出
对于整数溢出问题,可以通过先决条件检测、使用Math类的安全方法.向上类型转换或者使用Biglnteger等方法进行规避。
除数不为0
对除数进行非0判断,然后再进行除法或取余运算。
浮点比较
考虑浮点数的精度问题,可在一定的误差范围内判定两个浮点数值相等。这个误差应根据实际需要进行定义
精度计算
涉及精确的数值计算〔货币、金融等),建议使用int , long .BigDecimal 等;在构造BigDecimal 时,使用浮点数容易导致精度损失,应该使用字符串格式的数值构造BigDecimal
字符串换行和分割
用做换行〈回车"r"、换行"n")、文件路径分隔《""、"/")的字符.在不同探作系统下是有区别的。使用Systerm.lineSeparalor()获攻运行时环境的换行符。文件骛径分割符可以使java.io.File中的separator和pathseparator静态属性。
字符和字节转换
当跨平台实现字符与宁节之间的转换,可能会导致乱码。所以字符与字节之间转换时要明确指定编码方式
包装类型数值运算
包装类型进行加减乘除,涉及拆箱,可能导致空指针
断言
对不可信源进行报错,对可信源进行断言
断言是否生效依赖运行时属性的状态,存在被禁用的场景
信息安全
异常泄露
程序抛出的异常中,可能会包含一些敏感信息,将这些异常直接记录到日志或反馈给用户,会导致敏感信息泄露风险。
应该把原生异常打印记录日志,而向用户抛出自定义异常信息。
日志攻击
直接将外部数据记录到日志中,可能存在以下风险:
·日志注入:恶意用户可利用回车.换行等字符注入一条与系统日志规格类似的伪日志;
·敏感信息泄露:当用户输入敏感信息时,直接记录到日志中可能会导致敏感信息泄露;
·垃圾日志或日志覆盖:当用户输入的是很长的字符串,直接记录到日志中可能会导致产生大量垃圾日志;
·当日志被循环覆盖时,这样还可能会导致有效日志被恶意覆盖。
防御手段:
·换行回车replace其他字符
·敏感信息加密后在打印日志
·截断较长字符串
安全管理器
所有的敏感操作必须经过安全管理器的检查,防止被不可信的代码调用
非法路径参数
文件路径来自外部数据时,必须对其合法性进行校验,否则可能会产生路径遍历(Path Traversal〉漏洞。
对文件路径的规范化处理必须使用getcanonicalPath0,禁止 用getAbsalutePatho〔该方法无法保证在所有的平台上对文件路径进行正碎的规范化处理}
非法解压
使用java.util.zip.ZiplnputStream解压zip文件时,可能会有两类安全风险:
·将文件解压到目标目录之外
压缩包中的文件名中如果包含..,可能导致文件被解压到日标日录之外,造成任意文件注入、文件恶
意篡改等风险。因此,压缩包中的文件在解压前,要先对解压的目标路径进行校验。如果解压目标路径不在预期目录之内,要么拒绝将其解压出来,要么将其解压到一个安全的位置
·解压的文件消耗过多的系统资源
zip压缩算法可能有很大的压缩比,可以把超大文件压缩成很小的zip文件〈例如可以将上G的文件压缩为几K大小,这样的文件解压可能会导致zip炸弹(zip bomb)攻击。所以zip文件解压时,需对解压
的实际文件大小进行检查,若解压之后的文件大小超过一定的限制,必须拒绝解压。具体的大小限制根据实际情况来确定。除此之外,解压时,还需要对解压出来的文件数量进行限制,防止zip压缩包中是数量巨大的小文件说明:在统计解压文件的大小时,不应该使用entry.getsize来统计文件大小, <entry.getSize:是从zip文件中的固定字股中渎取单个文件压缩前的大小,文件压缩前的大小可被恶意篡改。>
非法序列化
当序列化结果中含有敏感信息时,序列化结果在磁盘上存储、跨信任域传递等操作都存在敏感信息泄露风险
- 如果敏感信息必须序列化,需要先对越感信息迄行加密或对序列化结果进行加密,跨信任边界传递含敏感信良的序列化结果时要先签名后加密。
- 使用transient关键词修饰含敏感信息的属性,避免这些属性进行序列化
非法反序列化
当反序列化操作的数善是外部数据时,恶意用户可利用反序列化操作构造指定的对象、执行恶意代码、向应用程序中注入有害数据等。
- 对className进行白名单校验。如果反序列化的类不在白名单之中,直接抛出异常.
- 如果产品已经使用Java的安全管理器,建议使用Java安全管理器机制进行防护
安全随机数
不安全的随机数可能被部分或全部预测到,导致系统存在安全隐患,安全场景下使用的随机数必须是密码学意义上的安全随机数。
常见安全场景包括但不限于以下场景:
- 用于密码算法用途,如生成Ⅳ、盐值、密钥等;
- 会话标识〈sesslonld)的生成;
- 挑战算法中的随机数生成;·验证码的陆机数生成;
安全随机数产生方式:
- Linux操作系统的/devrandom没备接口(存在阻塞问题}.
- windows探作系统的CryptGenRandomn)接口
- Java中的SecureRandom是一种密码学安全的伪机数产生,对于使用非真随机数产生器产生随机数时,要使用少量真随机数作为种子
网络通信
必须使用SSLSocket代替Socket来进行安全数据交互。在数据非敏感,或数摇已加密的情况下,可以使用Socket进行传输,效率更高。
sql注入
SQL注入产生的根本原因是使用外部数据直接拼接SQL语句
防护手段:
·使用参数化查淘:最有效的防护手段,但对sQL语句中的表名、字段名等不适用;
·对外部数据进行白名单校验:适用于拼接SQL语句中的表名、字段名;
·对外部数据中的与SQL注入相关的特殊字符进行转义:适用于必须通过字符串拼接构造SQL语句的场景,转义仅对由引号限制的字段有效
命令注入
Runtime.exec()方法或java.lang.ProcessBuildier类被用来启动一个新的进程,在新进程中执行
命令。命令执行通常会有两种方式
·直接执行具体命令:例如Runtime.getRuntimel).exec "ping127.0.0.1"");
·通过shell方式执行命令: vindaws下使用cmd.exe、linux下通过sh方式执行命令,或通过脚本文件( *.bati*.sh)执行命令古接使用外部数据构造命令行,会存在以下凤险:
shell方式执行命令时,需要命令行解释器对命令字符串进行拆分,该方式可执行多条命令,存在命令注入风险;
·直接执行具体的命令时,可以通过空格、双引号或以-顽开头的字符串向命令行中注入参数,存在参数注入风险.
防御手段;
·避免直接执行命令,用其他类库函数代替·对外部数据进行白名单([O-9A-Za-z@]+〕校验
·对外部数据进行转义(如果输入校验不能禁止有风险的特殊宁符,需先外部输入进行转义处理,转义后的字段拼接命令行可有效防止命令注入的产生)
XML注入
使用未经校验的数据来构造XML会导致XML注入漏洞
防御手段:
·白名单校验w
·使用安全的xml库(dom4j)
·转义
XXE攻击(XML External Entity外部实体攻击)
XML实体包括内部实体和外部实体。外部实体格式: <!ENTITY实体名SYSTEM URI"">或者
<!ENTITY实体名PUBLIC"public_ID""URI""> . Java中引入外部实体的协议包括http. https、ftp. file. jar. netdoc. mailto等。XXE漏洞发生在应用程序解析来自外郁的XML数据或文件时没有禁止外部实体的加裁,造成任意文件读取、内网端口扫描、内网网站攻击,DoS攻击等危害
防御手段:
- 禁止DTDs
- 白名单校验
XEE攻击(XML Entity Expansion内部实体拓展攻击)
XMIL内部实体格式:<!ENTITY实体名""实体的值"">。内部实体攻击比较常见的是XML EntityExpansion攻击,它主要试图通过消耗目标程序的服务器内存资源导致DoS攻击。例如,解析下面的XML时,因为内部实体lo9是一个非常大的字符串,所以解析<lolz>节点时,会占用大量服务器内存资源,导致拒绝服务攻击。
防御手段;
禁止DTDs
限制实体数量
并发多线程
data race数据竞争
两个线程对一个非volatile的共享变量进行访问操作,其中至少一个是写操作,且两个操作之间没有happends-before关系,就是datarace
通过建立happends-before消除data race.建立happends-betore需要远取合适的同步机制:
- 消息队列iexecutor. future)
- synchronize或volatile
happend-before原则
- 单线程按原代码顺序执行- unlock发生于lock之前
- volatile变量特性:对此变睑过的写操作发生于读操怍之前isynchronized没有happends-before}
- 线程启动特性; start先于此线程任何一个动作
- 线程中断特性:interrupt先于中断事件检测的代码发生
- 线程终止特性:线程的所有操作都先于终止检测的代码发生
- 对象络结特性:一个对象的初始化完成都先于其finalize发生开始
实例锁无法同步静态共享变量
锁对象并不是static,但共亨变量是static时,锁代码同步效果失效。
- 把锁对象也声明为static即可。
错用共享对象锁
如果锁对象是同一个引用内存,容易出现不同的共享变量依赖相同的锁。
eg:private final String lock = "lock"// 或者 = Boolean.TRUE
最后
以上就是闪闪白云为你收集整理的Java编码安全规范命名规范编码规范信息安全并发多线程的全部内容,希望文章能够帮你解决Java编码安全规范命名规范编码规范信息安全并发多线程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复