Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
<!--  /* Font Definitions */  @font-face 	{font-family:"Cambria Math"; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:0; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:-1610611985 1107304683 0 0 159 0;} @font-face 	{font-family:Cambria; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:0; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:-1610611985 1073741899 0 0 159 0;} @font-face 	{font-family:Calibri; 	panose-1:2 15 5 2 2 2 4 3 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:-1610611985 1073750139 0 0 159 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:""; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:10.0pt; 	margin-left:0in; 	mso-pagination:widow-orphan; 	font-size:11.0pt; 	font-family:"Calibri","sans-serif"; 	mso-fareast-font-family:Calibri; 	mso-bidi-font-family:"Times New Roman";} h2 	{mso-style-priority:9; 	mso-style-qformat:yes; 	mso-style-link:"Heading 2 Char"; 	mso-style-next:Normal; 	margin-top:12.0pt; 	margin-right:0in; 	margin-bottom:3.0pt; 	margin-left:0in; 	mso-pagination:widow-orphan; 	page-break-after:avoid; 	mso-outline-level:2; 	font-size:14.0pt; 	font-family:"Cambria","serif"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:major-latin; 	mso-fareast-font-family:"Times New Roman"; 	mso-fareast-theme-font:major-fareast; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:major-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:major-bidi; 	font-style:italic;} span.Heading2Char 	{mso-style-name:"Heading 2 Char"; 	mso-style-priority:9; 	mso-style-unhide:no; 	mso-style-locked:yes; 	mso-style-link:"Heading 2"; 	mso-ansi-font-size:14.0pt; 	mso-bidi-font-size:14.0pt; 	font-family:"Cambria","serif"; 	mso-ascii-font-family:Cambria; 	mso-ascii-theme-font:major-latin; 	mso-fareast-font-family:"Times New Roman"; 	mso-fareast-theme-font:major-fareast; 	mso-hansi-font-family:Cambria; 	mso-hansi-theme-font:major-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:major-bidi; 	font-weight:bold; 	font-style:italic;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:Calibri; 	mso-fareast-font-family:Calibri; 	mso-hansi-font-family:Calibri;} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.0in 1.0in 1.0in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;}  /* List Definitions */  @list l0 	{mso-list-id:498009851; 	mso-list-type:hybrid; 	mso-list-template-ids:-1150494584 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 	{mso-level-tab-stop:none; 	mso-level-number-position:left; 	text-indent:-.25in;} ol 	{margin-bottom:0in;} ul 	{margin-bottom:0in;} -->A A non-final class or method, which is not meant to be inherited, can be overridden by an attacker, if it is not declared as final \[3\].
\\

In case inheritance is to be limited to trusted implementations for a public, non-final class, then the class type should be confirmed before creating the instance at each place where an instance of the non-final class can be created. A SecurityManager check should be enforced on detecting a subclass (Chapter 6 of \[2\]).

A non-final class can be subverted simply by declaring a malicious class that inherits from the non-final class which implies that there is no need for reflection. However, reflection is necessary if the non-final class is private or otherwise inaccessible to the attacker.

h2. Non Compliant code example:

public class NonFinal {

 

&nbsp;&nbsp;&nbsp; // sole constructor

&nbsp;&nbsp;&nbsp; public NonFinal() {

 

{  &nbsp;  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // invoke java.lang.Object.getClass to get class instance  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class clazz = getClass();

 

  &nbsp;  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // continue

  &nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;


}

 

Here, an attacker can easily create an instance and override methods of the NonFinal class.

h2. Compliant Solution:

The compliant solution confirms the object's class type by examining the java.lang.Class instance belonging to that object since the instances are scoped by the class name and the class loader that defined the class.

public class NonFinal {

 

&nbsp;&nbsp;&nbsp; // sole constructor

&nbsp;&nbsp;&nbsp; public NonFinal() {

 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // invoke java.lang.Object.getClass to get class instance

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class clazz = getClass();

 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // confirm class type

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (clazz \!= NonFinal.class) {

 

{  &nbsp;  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // permission needed to subclass NonFinal  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; securityManagerCheck();

 ;  &nbsp;  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }\\

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // continue

&nbsp;&nbsp;&nbsp; }

 

&nbsp;&nbsp;&nbsp; private void securityManagerCheck() {

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;SecurityManager sm = System.getSecurityManager();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sm \!= null) {

{  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sm.checkPermission(...);

  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }\\

&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;


}

h2. Risk Assessment:

Allowing a non-final class or method to be inherited without checking the class instances, allows an attacker to exploit it.
|| Rule \\ || Severity \\ || Likelihood \\ || Remediation Cost \\ || Priority \\ || Level \\ ||
| OBJ33-J | high | probable \\ | high \\ | P3 \\ | L3 \\ | 



h2. Automated Detection

TODO

h2. Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website

h2. Reference:

# Secure Coding Guidelines      for the Java Programming Language [http://java.sun.com/security/seccodeguide.html]
# Li      Gong, Gary Ellison, and Mary Dageforde.
Inside Java 2 Platform Security. 2nd ed.
Boston, MA: Addison-Wesley, 2003.
# Joshua      Bloch. Effective Java Programming Language Guide.
1st ed. Addison-Wesley Professional, 2001.