1. 数据校验
对外部输入进行校验入参的合法性,
防止内存越界,命令注入,SQL注入,格式化字符串漏洞
校验长度,范围,输入校验采用白名单形式
校验前做归一化处理,使用java.text.Normalizer的normalize()方法, 防止字符转义绕过校验。
禁止直接使用外部输入来拼接SQL,推荐使用preparedstatement ,存储过程,或对外部输入转义
禁止直接使用外部输入开拼接XML,推荐使用正则表达式对输入进行校验
在对路径进行验证前先对其做标准化,如路径中的.和.. 相对路径,不要使用f.getabsolutepath,推荐使用f.getcanonicalpath
对zipinputstream中的条目做大小限制
2. 异常
禁止在异常中暴露敏感信息
3. IO操作
临时文件用完及时删除
禁止将buffer类中的wrap或duplicate创建的buffer暴露给不受信任的代码,推荐使用asreadonlybuffer()获取只读视图
禁止在单个输入流inputstream上创建多份bufferedinputstream,推荐将bufferedinputstream作为类变量(静态变量)
避免在共享目录操作文件
创建文件时指定合理的访问权限 posixfilepermission
4. 序列化
敏感数据发送出信任区域要先签名再加密,objectoutputstream 对象输出流,又叫序列化流,objectinputstream对象输入流,又叫反序列化流。
禁止序列化未加密的敏感数据,推荐通过transient关键字保证敏感数据不被序列化,也可以通过自定义writeobject()方法,不将敏感字段写到序列化流中。
防止序列化和反序列化被利用来绕开安全管理,java 序列化方法writeobject(),反序列化方法readobject()
避免依赖和信任环境变量,不要使用system.getenv,推荐使用system.getproperty
禁止在日志中保存口令,密钥
使用安全的标准的加密算法,禁用私有算法或弱加密算法(如DES SHA),推荐的对称加密算法 AES 128位,推荐的非对称加密算法RSA 2048位,DSA 1024位, 摘要算法SHA256
使用强随机数,securerandom
6 命名
所有标识符仅使用ASCII字母和数字 匹配正则\w{2,64}
注释
排版
文件不超过2000刚(非空非注释行)
一个类或接口的声明部分应当按照类(静态)变量,实例变量,构造器,方法的顺序出现
对于块状结构,左大括号放在行尾
每行限长120个窄字符
禁止C风格的数组声明,使用string[] args
switch语句要有default分支,即使不包含任何代码
变量
谨慎使用静态成员变量
不能用float浮点数作为循环变量
需要精确计算时不要使用float 和double,建议使用int,long,bigdecimal
方法不超过50行
方法的代码块嵌套不要超过4层
不要直接把入参作为临时变量
方法的参数个数不应超过5个
对于返回数组或容器的方法,应返回长度为0的数组或者容器,代替返回null
类和接口
覆写 ---- 子类与父类,一个实例方法可以覆写其在超类中可访问到(非private)的实例方法(非static),与父类同名同参,返回类型一致
重载----类内部,同名不同参,返回类型等其他无要求。
覆写equal方法时应同时覆写hashcode方法
接口定义中,属性已缺省具有public static final 修饰词,方法已缺省具有 public abstract 修饰词
方法抛出的异常应该与本身的抽象层次相对应
在finally块中不要使用return break 使finally块非正常结束
一个方法不应抛出超过5个异常
记录异常不要使用exception.getmessage,而要用exception.tostring
运行时异常不需要throws
日志工具logger类的实例应声明为 private static final
多线程并发
volatile ,提供轻量级的同步机制,和synchronized不同,只能修饰变量,声明一个可能被多线程访问的变量,共享变量。
volatile并不保证原子性,而synchronized修饰的方法或代码块,保证了锁住的代码可以全部执行,不被中断
不要在for each循环里进行元素的remove add,删除元素使用removeif 或iterator
大量字符串相加如果有线程安全要求应该使用stringbuffer,不涉及线程安全应使用stringbuilder
从流中读取一个字符或字节,使用int类型的返回类型