阿里巴巴规约扫描、奇安信扫描bug修改建议

目录

命名规范和注释

1.Exceptional return value of java.io.File.delete() ignored

2.Result of integer multiplication cast to long

3.Return value of Throwable.getMessage() ignored, but method has no side effect

4.Dead store to local variable

5.Redundant nullcheck of lineB, which is known to be non-null

6.Exception is caught when Exception is not thrown

7.循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。

8.关于基本数据类型与包装数据类型的使用标准如下:

9.Found reliance on default encoding: String.getBytes()(发现对默认编码的依赖:String.getBytes())

10.Map遍历时候entryset比keyset效率高

11.未使用的局部变量

12.May expose internal representation by returning reference to mutable object

13.Possible null pointer dereference of List

14.使用浮点数进行精确计算

15.解析Double类型数据的漏洞

16.路径遍历

17.比较Locale相关的数据未指定适当的Locale

18.使用==或!=比较基本数据类型的包装类

19.日志伪造

20.配置文件中的明文密码

21,资源未释放:流

22.敏感信息泄漏

23.XSS漏洞

24.直接使用线程类

25.系统信息泄露:标准错误流

26.拒绝服务:StringBuilder或者StringBuffer*

27.密码管理:硬编码加密密钥

28.在JAVA EE程序中直接使用Socket进行通信容易出错。

29.二级类:有风险的资源使用

30.一级类:代码质量 二级类:使用equals()来判断字符串是否为空

31.硬编码文件分隔符

32.有风险的SQL查询:MyBatis

33.byte数组转String时未指定编码

34.非同步方法覆盖同步方法

35.Optional没有在调用isPresent()后访问值

36.http响应

37.服务器端请求伪造

38.过于宽松的CORS策略

39.请使用System.currentTimeMillis()代替new Date().getTime()

40.事务场景中,抛出异常被catch后,如果需要回滚,一定要手动回滚事务。

41.使用DNS名称作为安全性的依据

42.输入验证:重定向

43.代码注入:HTTP响应截断


命名规范和注释

类、类属性、类方法的注释必须使用javadoc规范,使用/*内容/格式,不得使用//xxx方式和/xxx/方式

,除常用方法(如getXxx/isXxx)等外,不要在条件判断中执行复杂的语句,

方法内部单行注释,在被注释语句上方另起一行,所有的抽象方法(包括接口中的方法)必须要用javadoc注释、除了返回值、参数、异常说明外

1.Exceptional return value of java.io.File.delete() ignored

问题原因:java.io.File.delete()返回值未接受

规范写法:接受返回值并判断是否操作成功

2.Result of integer multiplication cast to long

问题原因:上面那行代码存在溢出风险在java中,int * int的结果还是int类型,不会自动转换为long类型,而long * int的结果是long类型,结果不会溢出

规范写法:将int * int换成long * int结果不会溢出

long size = quotaSize * 1024 * 1024;
换成
long size = quotaSize * 1024L * 1024;

3.Return value of Throwable.getMessage() ignored, but method has no side effect

问题原因:抛异常不合规范

规范写法:改为logger.error

4.Dead store to local variable

问题原因:局部变量的死存储,调用的方法有返回值并接受但是没有使用

规范写法:改为只调用方法不接受返回值

5.Redundant nullcheck of lineB, which is known to be non-null

问题原因:行C的冗余空检查,已知为非空

规范写法:多余的空判断去掉

 

数据库查询返回的list和set时查询结果为空也会不返回null
所以无需进行list != null 或 set != null 判断

6.Exception is caught when Exception is not thrown

问题原因:try{}catch(){}代码块中没有需要catch的Exception 类

规范写法:根据需要将代码的逻辑中不需要的try{}catch(){}去掉

7.循环体内,字符串的联接方式,使用StringBuilder的append方法进行扩展。

原因:下面代码,反编译出得字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作最后通过toString()方法返回String对象,造成资源的浪费

String str = "string"
for(int i = 0; i < 10; i++){
    str = str + "string";
}
//反编译之后大致这样子
String str = "string"
for(int i = 0; i < 10; i++){
    str = (new StringBuilder()).append(str).append("string").toString();
}
//string对象不可变,这里是在不断地创建StringBuilder对象,然后又调用tostring方法转成string对象。也就是在StringBuilder和string当中不断转化,这个过程是一个消耗。主要是当循环次数比较多的时候,就会在内存中创建很多StringBuilder对象,虽然会自动gc,但是这也增加了GC次数,然后就会有stop the world。减少吞吐量,增加了延时。

规范写法:使用StringBuild的append拼接字符串

String str = "string"
StringBuilder strb = new StringBuilder(str);
for(int i = 0; i < 10; i++){
    strb.append("string");
}
str = strb.toString();

8.关于基本数据类型与包装数据类型的使用标准如下:

 1) 所有的POJO类属性必须使用包装数据类型。  2) RPC方法的返回值和参数必须使用包装数据类型。

原因:POJO 类属性没有初值是提醒使用者在需要使用时,必须自己显式地进行赋值,任何 NPE 问题,或者入库检查,都由使用者来保证。数据库的查询结果可能是 null,因为自动拆箱,用基本数据类型接收有 NPE 风险。

 3) 所有的局部变量推荐使用基本数据类型。

原因:Java中共有三种变量,分别是类变量、成员变量和局部变量。他们分别存放在JVM的方法区、堆内存和栈内存中。 其中局部变量的作用域只在方法内部。那么,既然是一个作用域只在方法内的变量,不需要考虑那么多,怎么性能高就怎么定义。

在Java语言中,new一个对象是存储在堆里的,我们通过栈中的引用来使用这些对象。所以,对象本身来说是比较消耗资源的。

对于经常用到的类型,如int等,如果我们每次使用这种变量的时候都需要new一个Java对象的话,就会比较笨重。而基本数据类型的变量不需要使用new创建,它们不会在堆上创建,而是直接在栈内存中存储,因此会更加高效。

9.Found reliance on default encoding: String.getBytes()(发现对默认编码的依赖:String.getBytes())

原因:对默认编码依赖会因为对系统的默认编码不可预期而出现问题

改正:避免出现问题最好还是还是将默认编码指定好,如

String.getBytes("GBK");

10.Map遍历时候entryset比keyset效率高

原因:因为使用keySet遍历时,当使用key值取得Map中的Value时,Map又遍历了一遍。而EntrySet时,由于EntrySet本身就是key-value结构,所以直接将Map的key-value给取出来了,自然速度就要快上一些,使用迭代器会更快一些。

改正:使用entryset替换keyset

//keyset使用for循环遍历
for(String key : map.keySet()){
    map.get(key);
}
//keyset使用迭代器遍历
Iterator<String> ito = mapInfo.keySet().iterator();
while(ito.hasNext()){
    String key = it,next();
    map.get(key);
}
//entryset替换后的for循环遍历
for(Map.Entry<String, String> entry : map.entrySet()){
    entry.getValue();
}
//entryset替换后的迭代器遍历
Iterator<Map.Entry<String, String>> ito = map.entrySet();
while(ito.hasNext()){
    Map.Entry<String, String> entry = ito.next();
    entry.getValue();
}

11.未使用的局部变量

原因:局部遍历未使用,资源浪费

改正:删除

public int test(){
    //变量a未使用对功能无影响可以直接删除
    int a = 1;
    int b = 3, c= 2;
    return b + c;
}

12.May expose internal representation by returning reference to mutable object

原因:返回对存储在对象字段中的可变对象值的引用,将公开对象的内部表示形式。如果实例由不受信任的代码访问,并且对可变对象的未经检查的更改将损害安全性或其他重要属性,则需要采取不同的措施。在许多情况下,返回对象的新副本是更好的方法。(引用类型的可变对象都会有这种风险)

改正:方法如下

//修改前的实体类(lombok的@Data也是这种get和set的写法)
public class clonecc {
    private Date date;
    private List list;
    public clonecc(Date date, List list) {
        this.date = date;
        this.list = list;
    }
    public List getList() {
        return list;
    }
​
    public void setList(List list) {
        this.list = list;
    }
​
    public Date getDate() {
        return date;
    }
​
    public void setDate(Date date) {
        this.date = date;
    }
​
}
//修改前的测试类
public class testr {
    public static void main(String[] args) throws Exception {
        Date date = new Date();
        String string = "aaaa";
        ArrayList<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        clonecc clonecc = new clonecc(date,list,string);
        clonecc.setDate(date);
        System.out.println(clonecc.getDate());
        date.setTime(6);
        System.out.println(clonecc.getDate());
        clonecc.setList(list);
        System.out.println(clonecc.getList());
        list.add("3");
        System.out.println(clonecc.getList());
​
    }
}
结果:修改list和date影响实体类中属性的值了在代码中是存在风险的
Thu Dec 08 17:34:22 CST 2022
Thu Jan 01 08:00:00 CST 1970
[1, 2]
[1, 2, 3]
//修改后的实体类
public class clonecc {
    private Date date;
    private List list;
    public clonecc(Date date, List list) {
        if(date != null) {
            this.date = (Date) date.clone();
        }else {
            this.date = null;
        }
        this.list = list;
    }
    public List getList() {
        return list;
    }
​
    public void setList(List list) {
        this.list = list;
    }
​
    public Date getDate() {
        if(this.date != null) {
            return (Date) date.clone();
        }else {
            return null;
        }
​
    }
​
    public void setDate(Date date) {
        if(date != null) {
            this.date = (Date) date.clone();
        }else {
            this.date = null;
        }
    }
//修改后的测试方法
public class testr {
    public static void main(String[] args) throws Exception {
        Date date = new Date();
        String string = "aaaa";
        ArrayList<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        clonecc clonecc = new clonecc(date,list,string);
        clonecc.setDate(date);
        System.out.println(clonecc.getDate());
        date.setTime(6);
        System.out.println(clonecc.getDate());
        clonecc.setList((List) list.clone());
        System.out.println(clonecc.getList());
        list.add("3");
        System.out.println(clonecc.getList());
​
    }
}
结果:修改list和date没有影响实体类的属性
Thu Dec 08 17:28:54 CST 2022
Thu Dec 08 17:28:54 CST 2022
[1, 2]
[1, 2]

13.Possible null pointer dereference of List

问题原因:在编程中使用方法返回的list或者声明的list进行流处理等操作时要对其判空处理否则会报NEP异常(

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值