Java代碼審計-訪問說明符操作 f.setAccessible(true);


 

 Java代碼說明:

    f.setAccessible(true)1、提高性能2、訪問私有private變量的時候

    Accessable屬性是繼承自AccessibleObject 類. 功能是啟用或禁用安全檢查 (實際上setAccessible是啟用和禁用訪問安全檢查的開關,並不是為true就能訪問為false就不能訪問的意思 )。

 

  A、提高性能

    由於JDK的安全檢查耗時較多.所以通過setAccessible(true)的方式關閉安全檢查就可以達到提升反射速度的目的 。使用了method.setAccessible(true)后,性能有了20倍的提升。

  B、訪問私有private變量的時候

    java代碼中,常常將一個類的成員變量置為private,在類的外面獲取此類的私有成員變量的value時,需要注意setAccessible(true)否則或報錯:can not access a member of.......

    一般情況下,我們並不能對類的私有字段進行操作,利用反射也不例外,但有的時候,例如要序列化的時候,我們又必須有能力去處理這些字段,這時候,我們就需要調用AccessibleObject上的setAccessible()方法來允許這種訪問,而由於反射類中的Field,Method和Constructor繼承自AccessibleObject,因此,通過在這些類上調用setAccessible()方法,我們可以實現對這些字段的操作。

 

代碼示例:

  Class cls = object.getClass();

  Field[] fields = cls.getDeclaredFields();

  //getDeclaredFields()返回Class中所有的字段,包括私有字段。//getFields  只返回公共字段,即有public修飾的字段。

  for (Field field : fields) {

    field.setAccessible(true);

    map.put(field.getName(), field.get(object));

  }

 

 代碼審計 解釋說明:

  JDK API中的解釋 :

  1、AccessibleObject 類是 Field、Method 和 Constructor 對象的基類。它提供了將反射的對象標記為在使用時取消默認 Java 語言訪問控制檢查的能力。

  2、對於公共成員、默認(打包)訪問成員、受保護成員和私有成員,在分別使用 Field、Method 或 Constructor 對象來設置或獲得字段、調用方法,或者創建和初始化類的新實例的時候,會執行訪問檢查。 

  AccessibleObject類 允許程序員繞過 由Java訪問說明符提供的 訪問控制(access control)檢查,特別是他讓程序員能夠允許 反射對象繞過 Java access control,並反過來更改私有字段或調用私有方法、行為,這些通常情況下都是不允許的

  個人覺得只要Field.setAccessible(true)之后,Class中所有的字段,包括私有字段也可以有訪問權限,這樣的反射會改變JAVA的結構,

        甚至你的代碼可維護性,你完全可以 改別的代碼里面的值 ,所以通過反射能做一些讓你無法想象的東西。最好可以避免這樣的設置,以增強代碼的安全性,減少其脆弱性及缺陷。

  

  ★ 修復建議:

       只能使用攻擊者無法設置的參數,通過有權限的類更改訪問說明符。所有出現的訪問說明符都應該仔細檢查。

 ————————————————

參考文章:

https://www.cnblogs.com/fanguangdexiaoyuer/p/6548171.html 

https://blog.csdn.net/kjfcpua/article/details/8496911 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM