Sonar安全

 

1.Using Struts 1 ActionForm is security-sensitive

使用Struts1的ActionForm是安全敏感的。

All ActionForm's properties should be validated, including their size. Whenever possible, filter the parameters with a whitelist of valid values. Otherwise, escape any sensitive character and constrain the values as much as possible。

可能漏洞:

1).some parameters of the ActionForm might not have been validated properly.

    ActionForm傳遞的參數未經校驗就使用。

2).dangerous parameter names are accepted. Example: accept a "class" parameter and use the form to populate JavaBean properties .

接受危險的參數名稱。 示例:接受“class”類型參數並使用該表單填充JavaBean屬性。

3).there are unused fields which are not empty or undefined.

不要在ActionForm中添加未使用的字段。

安全編碼:

  1. .所有ActionForm中的屬性都應該被校驗,包括大小,是否爲空。過濾掉一些不合法的數據。
  2. .僅允許非安全敏感屬性,並將所有屬性加入白名單。
  3. .對未使用的字段加約束,爲空或未定義。

ActionForm:

ActionForm類是Struts框架的核心組件之一,是Struts的關鍵視圖組件。ActionForm的作用機理:
ActionForm本質上是一種JavaBean,是專門用來傳遞表單數據的DTD(Data Transfer Object,數據傳遞對象)。它包括用於表單數據驗證的validate()方法和用於數據復位的reset()方法 。

// Struts 1.1+
public final class CashTransferAction extends Action {

  public String fromAccount = "";
  public String toAccount = "";

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res) throws Exception {
    // usage of the "form" object to call some services doing JDBC actions
    [...]
    return mapping.findForward(resultat);
  }
}

參考:

https://www.aliyun.com/jiaocheng/321042.html 

https://blog.csdn.net/huihui870311/article/details/51023050

2.Using setters in Struts 2 ActionSupport is security-sensitive

在Struts 2中使用setter ActionSupport是安全敏感的

All classes extending com.opensymphony.xwork2.ActionSupport are potentially remotely reachable. An action class extending ActionSupport will receive all HTTP parameters sent and these parameters will be automatically mapped to the setters of the Struts 2 action class. One should review the use of the fields set by the setters, to be sure they are used safely. By default, they should be considered as untrusted inputs.

所有繼承ActionSupport的類都可以被遠程訪問的,通過HTTP發送過來的參數會自動匹配setters方法對應的屬性。需要校驗使用setter字段設置的字段,確保被安全使用。

可能漏洞:

  1. .the setter is needed. There is no need for it if the attribute's goal is not to map queries' parameter.

     如果不是一個映射查詢參數,不需要設置setter屬性時候設置了setter。

   2.the value provided to the setter is properly sanitized before being used or stored.

  前端傳入的參數未經校驗就使用了。

安全編碼:

  1. .不需要的屬性不要設置setter方法
  2. 用戶校驗用com.opensymphony.xwork2.ActionSupport的validate()方法來完成。
public class AccountBalanceAction extends ActionSupport {
  private static final long serialVersionUID = 1L;
  private Integer accountId;

  // this setter might be called with user input
  public void setAccountId(Integer accountId) {
    this.accountId = accountId;
  }

  @Override
  public String execute() throws Exception {
    // call a service to get the account's details and its balance
    [...]
    return SUCCESS;
  }
}

3.Using hardcoded IP addresses issecurity-sensitive

Attackers might be able to decompile the code and thereby discover a potentially sensitive address. They can perform a Denial of Service attack on the service at this address or spoof the IP address. Such an attack is always possible, but in the case of a hardcoded IP address the fix will be much slower, which will increase an attack's impact.

硬編碼IP是不安全的,攻擊者可以反編譯代碼獲取IP,可以對此地址的服務執行拒絕服務攻擊或欺騙IP地址。並且在硬編碼的情況下,修復會慢很多。

String ip = "192.168.12.42"; // Noncompliant
Socket socket = new Socket(ip, 6667);

改進:將 IP放入配置文件中。

4.Creating cookies without the "secure" flag is security-sensitive

The "secure" attribute prevents cookies from being sent over plaintext connections such as HTTP, where they would be easily eavesdropped upon. Instead, cookies with the secure attribute are only sent over encrypted HTTPS connections。

帶有secure屬性的cookies只能通過加密的HTTPS連接發送,可以防止通過純文本的HTTP連接發送數據。HTTP連接數據容易被竊取。

HTTP與HTTPS區別:

HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全,爲了保證這些隱私數據能加密傳輸,於是網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。

Cookie c = new Cookie(SECRET, secret);  // Noncompliant; cookie is not secure
response.addCookie(c);

改進:

Cookie c = new Cookie(SECRET, secret);
c.setSecure(true);
response.addCookie(c);

5.using pseudorandom number generators (PRNGs) is security-sensitive

    PRNG是通過某一種確定性算法來生成隨機數。它們並不是真正的隨機數,而是看起來是隨機的。即可以通過我們所能找到的所有隨機性統計檢驗。由於這些數字有可重複性,所以它們是僞隨機的。

As the java.util.Random class relies on a pseudorandom number generator, this class and relating java.lang.Math.random() method should not be used for security-critical applications or for protecting sensitive data. In such context, the java.security.SecureRandom class which relies on a cryptographically strong random number generator (RNG) should be used in place.

由於java.util.Random類依賴於僞隨機數生成器,因此該類和相關的java.lang.Math.random()方法不應用於安全關鍵應用程序或保護敏感數據。 在這種情況下,應該使用依賴於加密強隨機數生成器(RNG)的java.security.SecureRandom類。

PRNG(僞隨機數):

僞隨機數, 計算機不能生成真正的隨機數,而是通用一定的方法來模擬隨機數。僞隨機數有一部分遵守一定的規律,另一部分不遵守任何規律。

RNG(隨機數):

隨機數是由“隨機種子”產生的,“隨機種子”是一個無符號整形數。

反例:

Random random = new Random(); // Questionable use of Random

byte bytes[] = new byte[20];

random.nextBytes(bytes);

正例:

SecureRandom random = new SecureRandom(); 
byte bytes[] = new byte[20];
random.nextBytes(bytes);

參考:

http://blog.51cto.com/mzhang/1276644

http://www.what21.com/sys/view/java_java-secure_1473229611366.html

6.Changing or bypassing accessibility is security-sensitive

private methods were made private for a reason, and the same is true of every other visibility level. Altering or bypassing the accessibility of classes, methods, or fields violates the encapsulation principle and could introduce security holes.

更改或繞過一個類的私有方法或屬性,違反了封裝原則,可能引發安全漏洞。

This rule raises an issue when reflection is used to change the visibility of a class, method or field, and when it is used to directly update a field value.

當通過反射修改一個類的私有屬性時,可能會引發安全問題。

 使用ClassLoaders和SecurityManagers來沙箱化任何不受信任的代碼並禁止訪問Reflection API。

安全編碼:

1.使用加密強大的隨機數生成器(RNG) 如“java.security.SecureRandom”代替此PRNG。

2.僅使用生成的隨機值一次。

3.您不應該公開生成的隨機值。 如果必須存儲它,請確保數據庫或文件是安全的。

public void makeItPublic(String methodName) throws NoSuchMethodException {

  this.getClass().getMethod(methodName).setAccessible(true); // Questionable
}

public void setItAnyway(String fieldName, int value) {
  this.getClass().getDeclaredField(fieldName).setInt(this, value); // Questionable; bypasses controls in setter
}

7.Delivering code in production with debug features activated is security-sensitive

生產環境代碼啓動debug模式是安全敏感的。

An application's debug features enable developers to find bugs more easily. It often gives access to detailed information on both the system running the application and users. Sometime it even enables the execution of custom commands. Thus deploying on production servers an application which has debug features activated is extremely dangerous.

應用的debug模式可以讓開發人員輕鬆找到bugs。但它也可以查看用戶的詳細信息,甚至可以執行自定義命令。

安全編碼:

1.生產環境代碼禁止啓用debug模式。

反例:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity(debug = true) // Noncompliant
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  // ...
}

正例:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity(debug = false) // Compliant
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  // ...
}

8.Hashing data is security-sensitive

  哈希數據是安全敏感的。

Cryptographic hash functions are used to uniquely identify information without storing their original form. When not done properly, an attacker can steal the original information by guessing it (ex: with a rainbow table), or replace the original data with another one having the same hash。

加密散列函數用於唯一地標識信息而不存儲其原始數據。操作不當攻擊者會通過猜測(彩虹表)竊取其原始數據,或者替換原始數據。

漏洞編碼:

1.the hashed value is used in a security context. 

將散列值用於安全上下文的憑證。

2.the hashing algorithm you are using is known to have vulnerabilities.

使用的哈希算法已知具有漏洞。

3.salts are not automatically generated and applied by the hashing function.

鹽不是通過hashing的方法來自動生成。

4.any generated salts are cryptographically weak or not credential-specific.

生成的鹽是弱加密或者不是憑證特定的。

安全編碼:

1.使用安全哈希算法。避免在安全上下文中完全使用MD5和SHA1等算法。

2.禁止自定義哈希算法或鹽算法,因爲可能是有缺陷的。

3.不使用計算太快的算法如SHA256,因爲它必須超越現代硬件功能來執行暴力破解和基於字典的攻擊。

4.將salt和哈希值保存在相關的數據庫記錄中。在將來的驗證操作中,可以從數據庫中檢索salt和hash。

反例:

import com.google.common.hash.Hashing; 
void foo() {
        Hashing.md5(); // Questionable
        Hashing.sha1(); // Questionable
        Hashing.sha256(); // Questionable
        Hashing.sha384(); // Questionable
        Hashing.sha512(); // Questionable
    }

注:使用Hashing(import com.google.common.hash.Hashing)mad5()方法或者sha*()方法會引發安全問題。

反例:

// === MessageDigest ===
import java.security.MessageDigest;
import java.security.Provider;

class A {
    void foo(String algorithm, String providerStr, Provider provider) throws Exception {
        MessageDigest.getInstance(algorithm); // Questionable
        MessageDigest.getInstance(algorithm, providerStr); // Questionable
        MessageDigest.getInstance(algorithm, provider); // Questionable
    }

注:關於SecretKeyFactory。 將優先使用以“PBKDF2”開頭的參數調用SecretKeyFactory.getInstance(“...”)。 請參閱OWASP指南,android上的標準算法和算法列表。

參考:http://www.owasp.org.cn/owasp-project/secure-coding

9.Configuring loggers is security-sensitive

日誌文件的配置是安全敏感的

漏洞編碼:

1.Logs are also a target for attackers because they might contain sensitive information. Configuring loggers has an impact on the type of information logged and how they are logged.

日誌文件也是攻擊者的目標,因爲它們可能包含敏感信息。日誌文件的配置會影響記錄的信息類型以及記錄方式。

2.the logs contain sensitive information on a production server. This can happen when the logger is in debug mode.

當日志級別爲debug時,有可能會把生產服務器上有一些敏感的數據暴露出來

安全編碼:

  1.  檢查生產環境日誌級別是否爲debug模式,它可能會暴露一些敏感信息。
  2. 生產環境日誌文件位置設爲只有管理員權限才能訪問。
  3. 日誌文件配置打印所有warnings, info and error級別信息。
  4. 設置日誌文件大小限制,防止利用日誌信息填充磁盤。

反例: 

// === Logback ===
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.Appender;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.*;

class M {
    void foo(Logger logger, Appender<ILoggingEvent> fileAppender) {
        System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, "config.xml"); // Questionable
        JoranConfigurator configurator = new JoranConfigurator(); // Questionable

        logger.addAppender(fileAppender); // Questionable
        logger.setLevel(Level.DEBUG); // Questionable
    }
}

10.Using Sockets is security-sensitive

Socket的使用是安全敏感的

漏洞編碼:

1.sockets are created without any limit every time a user performs an action.

用戶毫無限制的創建Socket連接。

2.input received from sockets is used without being sanitized.

在使用socket接受的數據時沒有對數據檢查。

3.sensitive data is sent via sockets without being encrypted.

使用socket發送未加密的敏感數據

安全編碼:

  1. 不要使用用戶自定義socket,使用庫裏面的或者現有的協議。
  2. 敏感數據發送前加密。
  3. 對從socket讀取的數據進行校驗。
  4. 限制用戶創建的socket數量。儘可能關閉用戶創建的。

反例:

// === java.net ===
import java.net.Socket;
import java.net.InetAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import javax.net.SocketFactory;

class A {
    void foo(SocketFactory factory, String address, int port, InetAddress localAddr, int localPort, boolean stream,
            String host, Proxy proxy, int backlog, InetAddress bindAddr)
            throws Exception {
        new Socket(); // Questionable.
        new Socket(address, port); // Questionable.
        new Socket(address, port, localAddr, localPort); // Questionable.
        new Socket(host, port, stream); // Questionable.
        new Socket(proxy); // Questionable.
        new Socket(host, port); // Questionable.
        new Socket(host, port, stream); // Questionable.
        new Socket(host, port, localAddr, localPort); // Questionable.

        new ServerSocket(); // Questionable.
        new ServerSocket(port); // Questionable.
        new ServerSocket(port, backlog); // Questionable.
        new ServerSocket(port, backlog, bindAddr); // Questionable.

        factory.createSocket(); // Questionable
    }
}

abstract class mySocketFactory extends SocketFactory { // Questionable. Review how the sockets are created.
    // ...
}

 參考:https://blog.csdn.net/lucyxu107/article/details/74530966

11.Handling files is security-sensitive

文件處理是安全敏感的

Any access to the file system can create a vulnerability. Exposing a file's content, path or even its existence or absence is dangerous. It is also extremely risky to create or write files without making sure that their permission and content is safe and controlled. Using a file path or reading a file content must be always done with caution as they could have been tampered with.

文件系統的任何訪問都可能產生漏洞。保證文件路徑位置的安全

The file system is a resource which can be easily exhausted. Opening too many files will use up all file descriptors, preventing other software from opening files. Filling the storage space will also prevent any additional write from happening.

讀寫文件是很消耗系統資源的。防止惡意軟件頻繁讀取文件,導致系統崩潰。

漏洞編碼:

1.the file or directory path you are using is coming from a user input or could have been tampered with.

使用的文件路徑來自於用戶輸入。

2."Unauthorized" error when the file/directory exists but the person can't perform an action.

可能使用錯誤的權限創建文件或目錄。

3.the code exposes to an unauthorized person the paths of files and/or directories, for example by listing the content of a directory and displaying the output.

代碼向未經授權的人公開文件和/或目錄的路徑,例如通過列出目錄的內容並顯示輸出。

4.a file is read and its content is used without being validated.

讀寫文件並使用其內容而不進行驗證。

安全編碼:

  1. 不應公開文件和目錄名稱。它們可以包含敏感信息。
  2. 確保任何攻擊者都不能讀取到敏感的文件信息。
  3. 給文件和目錄加授權驗證。只有通過權限驗證的用戶才能訪問文件。
  4. 對用戶寫入文件系統的信息進行校驗。
  5. 添加讀寫文件記錄,修改文件後應該向授權用戶公開。
  6. 使用文件監控系統監控文件系統使用情況。
  7. 不允許不受信任的代碼訪問文件系統。
// ===  org.apache.commons.io.FileUtils ===
import org.apache.commons.io.FileUtils;

class A {
    void foo() {
        FileUtils.getFile("test.txt"); // Questionable
        FileUtils.getTempDirectory(); // Questionable
        FileUtils.getUserDirectory(); // Questionable
    }
}

 

// === java.io.File ===
import java.io.File;

class A {
    void foo(String strPath, String StrParent, String StrChild, String prefix, String suffix, java.net.URI uri) throws Exception {

        // Questionable: check what is done with this file
        new File(strPath);
        new File(StrParent, StrChild);
        new File(uri);
        File.createTempFile(prefix, suffix);
    }
}

12.Executing SQL queries is security-sensitive

執行sql查詢是安全敏感的,如果查詢語句書寫不當會造成SQL注入

SQL injection is still one of the top 10 security vulnerabilities. Applications that execute SQL commands should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that changes the query so that unintended commands are executed, or sensitive data is exposed. Instead of trying to sanitize data by hand, SQL binding mechanisms should be used; they can be relied on to automatically perform a full sanitization.

SQL注入仍然是十大安全漏洞之一。 執行SQL命令的應用程序應該拒絕任何外部提供的SQL命令。 如果不這樣做,攻擊者可能會改變更改查詢條件,以便執行非預期的命令,或者暴露敏感數據。

安全編碼

1.避免使用拼接Sql語句查詢。

2.使用PreparedStatement預編譯語句集處理sql,它內置了處理SQL注入的能力。

3.使用Hibernate、mybatis等ORM框架,如果使用正確,可以降低注入風險。

4.使用低權限的數據庫賬戶來減少攻擊。

反例:

public User getUser(Connection con, String user) throws SQLException {

  Statement stmt1 = null;
  Statement stmt2 = null;
  PreparedStatement pstmt;
  try {
    stmt1 = con.createStatement();
    ResultSet rs1 = stmt1.executeQuery("GETDATE()"); // Compliant; parameters not used here

    stmt2 = con.createStatement();
    ResultSet rs2 = stmt2.executeQuery("select FNAME, LNAME, SSN " +
                 "from USERS where UNAME=" + user);  // Noncompliant; parameter concatenated directly into query

    pstmt = con.prepareStatement("select FNAME, LNAME, SSN " +
                 "from USERS where UNAME=" + user);  // Noncompliant; parameter concatenated directly into query
    ResultSet rs3 = pstmt.executeQuery();

    //...
}

public User getUserHibernate(org.hibernate.Session session, String userInput) {

  org.hibernate.Query query = session.createQuery(  // Compliant
            "FROM students where fname = " + userInput);  // Noncompliant; parameter binding should be used instead
  // ...
}

正例:

public User getUser(Connection con, String user) throws SQLException {

  Statement stmt1 = null;
  PreparedStatement pstmt = null;
  String query = "select FNAME, LNAME, SSN " +
                 "from USERS where UNAME=?"
  try {
    stmt1 = con.createStatement();
    ResultSet rs1 = stmt1.executeQuery("GETDATE()");

    pstmt = con.prepareStatement(query);
    pstmt.setString(1, user);  // Compliant; PreparedStatements escape their inputs.
    ResultSet rs2 = pstmt.executeQuery();

    //...
  }
}

public User getUserHibernate(org.hibernate.Session session, String userInput) {

  org.hibernate.Query query =  session.createQuery("FROM students where fname = ?");
  query = query.setParameter(0,userInput);  // Parameter binding escapes all input
  // ...

 

參考:https://www.cnblogs.com/baizhanshi/p/6002898.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章