• 代码质量管理-安全问题


    自动化持续代码质量监测工具SonarQube,有关安全问题相关代码示例。

    1、Use a logger to log this exception.

    错误代码:

    try {
         saveGeographicInfo(geographicInfo, gisConfig);
     } catch (Exception e) {
         e.printStackTrace();
         //Use a logger to log this exception.
     }
    

    Reason:

    • 不应调用Throwable.printStackTrace(…)
    • printStackTrace(…)将抛出及其堆栈跟踪打印到某个流。默认情况下,该stream System.Err可能会无意中公开敏感信息。

    应该使用记录器来打印一次性文件,因为它们有许多优点:

    • 用户可以轻松地检索日志。
    • 日志消息的格式是统一的,允许用户轻松浏览日志。
    • 如果使用printStackTrace时没有参数,即堆栈跟踪打印到默认流时,此规则会引发问题。

    Solution:

    错误案例:

    //Noncompliant Code Example
    try {
      /* ... */
    } catch(Exception e) {
      LOGGER.log("context", e);
    }
    try {
      /* ... */
    } catch(Exception e) {
      e.printStackTrace();        // Noncompliant
    }
    

    推荐案例:

    //Compliant Solution
    try {
      /* ... */
    } catch(Exception e) {
      LOGGER.log("context", e);
    }
    

    2、Add password protection to this database

    错误代码:

    try {
      /* 建立连接 */
      conn = DriverManager.getConnection(URL, username, password);
      //Add password protection to this database。
      }
    

    Reason:

    • 数据库应始终受密码保护,但使用密码为空的数据库连接清楚地表明数据库未受保护。

    用空密码标记数据库连接。

    Solution:
    错误案例:

    //Noncompliant Code Example
    Connection conn = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true", "AppLogin", "");
    Connection conn2 = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=");
    

    推荐案例:

    //Compliant Solution
    DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=password");
    
    DriverManager.getConnection("jdbc:mysql://address=(host=myhost1)(port=1111)(key1=value1)(user=sandy)(password=secret),address=(host=myhost2)(port=2222)(key2=value2)(user=sandy)(password=secret)/db");
    
    DriverManager.getConnection("jdbc:mysql://sandy:secret@[myhost1:1111,myhost2:2222]/db");
    
    String url = "jdbc:postgresql://localhost/test";
    Properties props = new Properties();
    props.setProperty("user", "fred");
    props.setProperty("password", "secret");
    DriverManager.getConnection(url, props);
    

    3、Make this “public static map” field final

    错误代码:

    public static Map<String, String> map;
    

    Reason:
    没有充分的理由在不声明字段“final”的情况下声明字段“public”和“static”。大多数情况下,这是一个在多个对象之间共享状态的错误。但是使用这种方法,任何对象都可以对共享状态执行它想要的任何操作,例如将其设置为空。

    Solution:
    错误案例:

    //Noncompliant Code Example
    public class Greeter {
      public static Foo foo = new Foo();
      ...
    }
    

    推荐案例:

    //Compliant Solution
    public class Greeter {
      public static final Foo FOO = new Foo();
      ...
    }
    

    Make map a static final constant or non-public and provide accessors if needed.

    公共类变量字段不尊重封装原则,有三个主要缺点:

    • 无法添加其他行为,如验证。
    • 内部表示是公开的,以后不能更改。
    • 成员值可能会在代码中的任何地方发生变化,并且可能不符合程序员的假设。

    通过使用私有属性和访问器方法(set和get),可以防止未经授权的修改。
    Solution:
    错误案例:

    //Noncompliant Code Example
    public class MyClass {
      public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked
      public String firstName;                       // Noncompliant
    }
    

    推荐案例:

    //Compliant Solution
    public class MyClass {
    
      public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked
    
      private String firstName;                      // Compliant
    
      public String getFirstName() {
        return firstName;
      }
    
      public void setFirstName(String firstName) {
        this.firstName = firstName;
      }
    
    }
    

    例外情况:
    因为它们不可修改,所以此规则忽略公共final字段。

    4、‘PASSWORD’ detected in this expression, review this potentially hard-coded credential.

    错误代码:

    private static final String DBPASSWORD = "xxxxxx";// 数据库密码
    

    Reason:

    • 由于从已编译的应用程序中提取字符串很容易,因此不应硬编码凭据。这样做,它们几乎肯定会落入攻击者手中。这对于分布式应用程序尤其如此。

    凭据应存储在代码之外的受强保护的加密配置文件或数据库中。
    建议使用其他凭据字(如“oauthToken”、“secret”、。。。

    Solution:
    错误案例:

    //Noncompliant Code Example
    Connection conn = null;
    try {
      conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
            "user=steve&password=blue"); // Noncompliant
      String uname = "steve";
      String password = "blue";
      conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
            "user=" + uname + "&password=" + password); // Noncompliant
    
      java.net.PasswordAuthentication pa = new java.net.PasswordAuthentication("userName", "1234".toCharArray());  // Noncompliant
    

    推荐案例:

    //Compliant Solution
    Connection conn = null;
    try {
      String uname = getEncryptedUser();
      String password = getEncryptedPass();
      conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
            "user=" + uname + "&password=" + password);
    

    4.1 Remove this hard-coded password.

    错误代码:

    try {
        Class.forName(DBDRIVER);// 注册驱动
        conn = DriverManager.getConnection(DBURL,DBUSER, DBPASSWORD);// 获得连接对象
    

    解决方案同4。

  • 相关阅读:
    斯坦福机器学习实现与分析之二(线性回归)
    理解Kalman滤波的使用
    浅谈程序优化
    2014年,我学到了什么
    运动目标跟踪中kalman滤波器的使用
    图像水波纹特效原理分析和实现
    Redis与memached的区别
    Freemarker讲解
    Java基础知识总结
    Java中GC的工作原理
  • 原文地址:https://www.cnblogs.com/aixing/p/13327203.html
Copyright © 2020-2023  润新知