Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New detector for MET07-J #2467

Open
wants to merge 115 commits into
base: master
Choose a base branch
from

Conversation

NazirMuhammadZafarIqbal
Copy link
Contributor

I have implemented a checker named "FindHidingSubClass" for SEI CERT MET07-J

The checker proved to be effective in identifying potential vulnerabilities in Java code. By enforcing the declaration of methods that can be hidden as non-static or private. This checker helps reduce the risk of method hiding to avoid unexpected and misleading outcomes, especially when programmers expect it to be method overriding.

I have both White Box and Black Box Testing. For White Box Testing, I have created 11 compliant and 12 non-compliant test cases. My checker passes all of the test cases. For Black Box Testing, I tested the checker on the SpotBugs projects. I got 10 true positives and 0 false positives.

Results for spotbugs Project:
13.0_SBTestRepoLogicChanges.txt

Detections by MET03-J in SpotBugs:
13.0_SBTestRepoLogicChanges_filtered.txt


Make sure these boxes are checked before submitting your PR -- thank you!

  • Added an entry into CHANGELOG.md if you have changed SpotBugs code

Fixed typo - renamed GoodFindHidingSubClassTest class and file
Fixed the commented out lines.
Fixed the package naming convention in test cases and Junit test repo.
Added the correct argument checking for detecting entry point of the class.
Improved the checker logic to detect not only equality but also subSignature case.
Fixed messages.xml and findbugs.xml added lines as per standards.
Fixed whitespace issues.
Added comments in test cases.
Improved the messages.xml description by adding the suggested solutions to resolve the error.
Renamed one of the test cases. "GoodFindHidingSubClassTest2"
Implemented some new test cases.
…o track down the .class$(String) detections in the output of large test case repo: SpotBUgs
… signature for hiding. Dropped the idea of subSignature.
…ding the `OpcodeStackDetector` rather implements a more basic interface `Detector`. SO, now detector works at more low-level i.e. increasing efficiency.
@JuditKnoll
Copy link
Collaborator

@gtoison, @ThrawnCA you had some change request for this PR. I think all of them had been addressed. Can you please look at this PR once more, when you have time?

Method[] methods = subClass.getMethods();
//For each super class, I go through each method of the subclass
//and filter the non-private and static methods, as private methods can't be overridden.
for (JavaClass superClass : superClasses) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be a bit faster to invert the superClass and the method loops.
Here we're evalutating the method.isStatic() && !method.isPrivate() && !isMainMethod(method) test (as well as the following test) for every super class and every method.
We could do this instead:

for (Method method : methods) {
  if (method.isStatic() && !method.isPrivate() && !isMainMethod(method)) {
    if (isConstructor(method) || isHidingInnerClass(method) || isAutoGeneratedMethod(method)) {
       continue;
    }
  }

  for (JavaClass superClass : superClasses) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got your idea for efficiency ;)

Your suggestion has the problem we need to invert the outer conditional and keep the inner conditional in parallel to the outer conditional.

I have fixed the code accordingly.

}

/**
* This method checks either the argument is String array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either -> whether ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

<![CDATA[
<p>
Hiding happens when a sub class defines a static method
with same header (signature plus return type) as any of its super classes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"with same" -> "with the same"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

<p>
Hiding happens when a sub class defines a static method
with same header (signature plus return type) as any of its super classes.
In case of method hiding, the invoked method is determined based on the specific qualified name or
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"In case of" -> "In the event of"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

method invocation expression used at the calling site.
The results are often unexpected, although the Java language provides unambiguous rules for method invocation for method hiding.
Moreover, method hiding and method overriding is often confused by programmers.
Consequently, programmers must avoid the method hiding.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a "should" rather than "must".

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote must because if the programmer has mistaken the method hiding as method overriding, then he is receiving wrong results. So he must fix it.

I still adopt your suggestion in case the programmer is aware of the difference and he is using the method of hiding carefully. Then he does not need to fix the code.

The results are often unexpected, although the Java language provides unambiguous rules for method invocation for method hiding.
Moreover, method hiding and method overriding is often confused by programmers.
Consequently, programmers must avoid the method hiding.
Programmer should declare the respective methods non-static or restrict it as private to eradicate the problem.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"methods" -> "method"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -0,0 +1,31 @@
package findhidingsubclasstest;

class SuperBadInEqualMultipleMethod {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what this class name means.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the SUPERclass for a non-compliant (BAD) test case, with MULTIPLE METHODs declared in both super and sub classes. But the number methods is INEQUAL. So Super.

}

/**
* This test case is a complaint test case with multiple methods declared in both super and sub classes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"complaint" -> "compliant"?

}

/**
* This test case is a complaint test case with multiple level inheritance.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"complaint" -> "compliant"?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}

/**
* This test case is a complaint test case with multiple level inheritance.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"complaint" -> "compliant"?

}

/**
* This test case is a complaint test case with multiple methods declared in both super and sub classes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"complaint" -> "compliant"?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.



/**
* This test case is a complaint test case with multiple methods declared in both super and sub classes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"complaint" -> "compliant"?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@Midya-ELTE
Copy link

I suggest the name of the checker be (FindHiddenMethod) instead of (FindHiddenSubClass).

* Please see @see <a href="https://wiki.sei.cmu.edu/confluence/display/java/MET07-J.+Never+declare+a+class+method+that+hides+a+method+declared+in+a+superclass+or+superinterface">SEI CERT MET07-J</a>
* @author Nazir, Muhammad Zafar Iqbal
*/
public class FindHidingSubClass implements Detector {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be more descriptive if you name the class FindHiddenMethod instead.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pointing out the miss-naming. I have renamed the checker now. I have also changed it at all the relevant places.

@@ -1320,4 +1324,5 @@
<BugPattern abbrev="PI" type="PI_DO_NOT_REUSE_PUBLIC_IDENTIFIERS_METHOD_NAMES" category="BAD_PRACTICE"/>
<BugPattern abbrev="PI" type="PI_DO_NOT_REUSE_PUBLIC_IDENTIFIERS_LOCAL_VARIABLE_NAMES" category="BAD_PRACTICE"/>

<BugPattern abbrev="HSBC" type="HSBC_HIDING_SUB_CLASS" category="CORRECTNESS"/>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be more descriptive if you change the type to HSM_HIDING_METHOD, and the abbrev will be HSM in this case.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

CHANGELOG.md Outdated
@@ -16,6 +16,9 @@ Currently the versioning policy of this project follows [Semantic Versioning v2.

- tbd

### Added
- New detector `FindHidingSubClass` for bug type `HSBC_HIDING_SUB_CLASS`. This bug is reported whenever a subclass method hides the static method of super class. (See [SEI CERT MET07-J] (https://wiki.sei.cmu.edu/confluence/display/java/MET07-J.+Never+declare+a+class+method+that+hides+a+method+declared+in+a+superclass+or+superinterface)).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot to edit the changelog after changing the name of the detector, thank you for all the changes!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it just slipped out of my mind. I have fixed it now. Thank you for your prompt review :))


for (JavaClass superClass : superClasses) {
Method[] superMethods = superClass.getMethods();
//I check either the subclass method is hiding the superclass method. If yes I report the bug.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having trouble following this grammar. "I check either the subclass method" doesn't make sense to me. Did you mean "I check if"?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant "whether".

CHANGELOG.md Outdated Show resolved Hide resolved
spotbugs/etc/messages.xml Outdated Show resolved Hide resolved
@@ -9014,6 +9025,25 @@ Using floating-point variables should not be used as loop counters, as they are
]]>
</Details>
</BugPattern>
<BugPattern type="HSM_HIDING_METHOD">
<ShortDescription>Method hiding must be avoided.</ShortDescription>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Should" rather than "must".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

private final String BUG_TYPE = "HSM_HIDING_METHOD";

@Test
void testBadFindHiddenMethodTest() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the "bad" testcases, there could be an assert for the number of the found buginstances as well.

@hazendaz hazendaz dismissed gtoison’s stale review March 4, 2024 02:09

User fixed issue, so this is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants