I'm trying to eliminate false-positives from an HP Fortify scan of a Java application.
This method causes a "Privacy Violation" issue (the PrintWriter is a servlet response)
private void writeOutput(String passwordRules, PrintWriter out) {
...
out.print(passwordRules);
...
}
This is because Fortify follows naming conventions, to decide that passwordRules contains private data. But my passwordRules is not private data -- it contains stuff like "Minimum 8 characters".
I can make the error go away by changing the name of the variable. However in principle I don't want to compromise the readability of my code, for the benefit of a source code analyser.
I expected this to fix it:
private void writeOutput(#FortifyNotPassword String passwordRules, PrintWriter out) ...
However it seems the annotation isn't written for that context:
The annotation #FortifyNotPassword is disallowed for this location.
I tried:
private void writeOutput(String passwordRules, PrintWriter out) {
...
#FortifyNotPassword String rules = passwordRules;
out.print(rules);
...
}
... but this doesn't remove the false-positive. (And it compromises my principle of not making code less readable).
I've also tried the above with #FortifyNotPrivate, with the same results.
So what's the right way to do this?
Fortify offers you two ways to deal with this situation: 1) suppress the issue, or 2) hide the issue. Which you select depends on what you believe will work best for you.
Suppressed issues. You can mark an issue as suppressed if you are sure that the specific vulnerability is not, and never will be, a concern. You might also want to suppress warnings for specific types of issues that might not be high priority or of immediate concern. For example, you can suppress issues that are fixed, or issues that - in your case - you do not plan to fix. Suppressed issues are not included in the group totals shown in the issues panel. This approach may be best when you want to eliminate awareness of the issue altogether.
Hidden issues. You can hide a group of issues temporarily to avoid distraction as you focus elsewhere. For example, you could hide all issues except those assigned to you. The individuals assigned to address the issues you have hidden in your view can still access them. The group totals displayed in the issues panel include hidden issues. If you find an issue in a folder list that you want to hide or direct to another folder, you can create a new filter using the filter wizard. The filter wizard displays all the attributes with matching conditions for the filter. P 29 of the document HP_Fortify_Audit_Workbench_User_Guide_4.30; this documentation is with your Fortify program files. This alternative might be preferable if you want others to be aware of the issues, even as you ignore it.
Removed issues. This alternative is not particularly relevant to your situation, but I present it for the sake of completeness. As multiple scans are run on a project over time, issues are often remediated or become obsolete. As it merges scan results, Static Code Analyzer marks issues that were uncovered in a previous scan, but are no longer evident in the most recent SCA analysis results as Removed. Removed issues are not included in the group totals shown in the issues panel. As you do not intend to "remediate" this issue, it will not become a "removed issue."
To show or hide suppressed, hidden, and removed issues, use the Option menu. Visibility filters show or hide issues.
Related
I work on a large legacy Java 8 (Android) application. We recently found a bug that was caused by an ignored result of method. Specifically a caller of a send() method didn't take the right actions when it the sending failed. It's been fixed but now I want to add some static analysis to help find if other existing bugs of the same nature exist in our code. And additionally, to prevent new bugs of the same nature from being added in the future.
We already use Find Bugs, PMD, Checkstyle, Lint, and SonarQube. So I figured that one of these probably already has the check I'm looking for, but it just needs to be enabled. But after a few hours of searching and testing, I don't think that's the case.
For reference, this is the code I was testing with:
public class Application {
public status void main(String[] args) {
foo(); // I want this to be caught
Bar aBar = new Bar();
aBar.baz(); // I want this to be caught
}
static boolean foo() {
return System.currentTimeMillis() % 2 == 0;
}
}
public class Bar {
boolean baz() {
return System.currentTimeMillis() % 2 == 0;
}
}
I want to catch this on the caller side since some callers may use the value while others do not. (The send() method described above was this case)
I found the following existing static analysis rules but they only seem to apply to very specific circumstances to avoid false positives and not work on my example:
Return values from functions without side effects should not be ignored (only for immutable classes in the Java API)
Method ignores exceptional return value (only for known methods like File.delete())
Method ignores return value (only for methods annotated with javax.annotation.CheckReturnValue I think...)
Method ignores return value, is this OK? (only when the return value is the same type as the type the method is invoked on)
Return value of method without side effect is ignored (only when the method does not produce any effect other than return value)
So far the best option seems to be #3 but it requires me to annotate EVERY method or class in my HUGE project. Java 9+ seems to allow annotating at the package-level but that's not an option for me. Even if it was, the project has A LOT of packages. I really would like a way to configure this to be applied to my whole project via one/few locations instead needing to modify every file.
Lastly I came across this Stack Overflow answer that showed me that IntelliJ has this check with a "Report all ignored non-library calls" check. Doing this seems to work as far as highlighting in the IDE. But I want this to cause CI fail. I found there's a way to trigger this via command line using intelliJ tools but this still outputs an XML/JSON file and I'll need to write custom code to parse that output. I'd also need to install IDE tools onto the CI machine which seems like overkill.
Does anyone know of a better way to achieve what I want? I can't be the first person to only care about false negatives and not care about false positives. I feel like it should be manageable to have any return value that is currently being unused to either be logged or have it explicitly stated that the return value is intentionally ignored it via an annotation or assigning to a variable convention like they do in Error Prone
Scenarios like the one you describe invariably give rise to a substantial software defect (a true bug in every respect); made more frustrating and knotty because the code fails silently, and which allowed the problem to remain hidden. Your desire to identify any similar hidden defects (and correct them) is easy to understand; however, (I humbly suggest) static code analysis may not be the best strategy:
Working from the concerns you express in your question: a CheckReturnValue rule runs a high risk of producing a cascade of //Ignore code comments, rule violationSuppress clauses, and/or #suppressRule annotations that far outnumber the rule's positive defect detection count.
The Java programming language further increases the likelihood of a high rule suppression count, after taking Java garbage collection into consideration and assessing how garbage collection effects software development. Working from the understanding that Java garbage collection is based on object instance reference counting, that only instances with a reference count of 0 (zero) are eligible for garbage collection, it makes perfect sense for Java developers to avoid unnecessary references, and to naturally adopt the practice of ignoring unimportant method call return values. The ignored instances will simply fall off of the local call stack, most will reach a reference count of 0 (zero), immediately become eligible for and quickly undergo garbage collection.
Shifting now from a negative perspective to positive, I offer alternatives, for your consideration, that (I believe) will improve your results, as well as your probability to reach a successful outcome.
Based on your description of the scenario and resulting defect / bug, it feels like the proximate root cause of the problem is a unit testing failure or an integration testing failure. The implementation of a send operation that may (and almost certainly will at some point) fail, both unit testing and integration testing absolutely should have incorporated multiple possible failure scenarios and verified failure scenario handling. I obviously don't know, but I'm willing to bet that if you focus on creating and running unit tests and integration tests, the quality of the system will improve at every step, the improvements will be clearly evident, and you may very well uncover some or all of the hidden bugs that are the cause of your current concern, trepidation, stress, and worry.
Consider keeping the gist of your current static code analysis research alive, but shift your approach in a new direction. The first time I read your question, I was struck by the realization that the code checks you would like to perform exist in multiple unrelated locations across the code base and are quickly becoming overly complex, the specific details of the checks are different in many section of code, and each of the special cases make the overall effort unrealistic. Basically, what you would like to implement represents a cross-cutting goal that falls across a sizable section of the code base, and the implementation details have made what is a fairly simple good idea ridiculously complex. Your question is almost a textbook example of a problem that is best implemented taking a cross-cutting aspect-oriented approach.
If you have the time and interest, please take a look at the AspectJ framework, maybe code a few exploratory aspects, and let me know what you think. I'd like to hear your thoughts, if you feel like having a geeky dev conversation at some point. I really hope this is helpful-
You may use the intelliJ IDEA's inspection: Java | Probable bugs | Result of method call ignored with "Report all ignored non-library calls" option enabled. It catches both cases provided in your code sample.
First of all I must say I'm new to both Android dev and Java.
I'm trying to find a list of the tags that are used for logging in Android studio.
The examples I've been researching include using:
Log.i(tag:"Info","message");
Log.i(tag:"Values","another message");
Log.i(tag:"Seekbar changed", "and another message");
I tried for the past couple of hours to find a document online, that has a table to describe the reserved tags for View objects, any help will be appreciated.
There is no fixed list of "reserved tags" one can use for logging in Android. You decide for yourself which tags you want to use and what additional information about the state of your objects or primitive types you want to display.
The Log class has six different log levels (debug, error, info, verbose, warn and wtf [What a Terrible Failure]) and corresponding (static) methods (Log.d, Log.e, Log.i, Log.v, Log.w and Log.wtf) each of which you call with two string parameters, one string parameter and one Throwable or two string parameters and one Throwable.
The most commonly used is probably the variant with two string parameters, one parameter for a tag (chosen by you) and one parameter for a message (also chosen by you). See this post for information about which level to choose.
During debugging I often use commands like this one:
Log.e(String.valueOf(myIntVariable), String.valueOf(myOtherVariable));
Let me explain the reason for using the Log class like this. I use the error level because it will give you red entries in the LogCat output (inside an IDE, e.g. Android Studio), and the same IDE will also let you filter out all logs below the error level. However, this is for debugging only; make sure to get rid of those log commands before your app enters production.
Instead of using logs in the way I do, you can also use breakpoints in the debug mode. I guess it is mainly a question of taste if you prefer one or the other. Toasts would be third option (with more boilerplate though).
If you use logs a lot in your code, it makes sense to use real tags. Either you define a string called TAG (or something else) in your class, or you put the name of the containing method as the first parameter. This will give you a sense of the order by which your methods are being called. You can also use other tags as well, and it doesn't have to follow a specific convention either (though you should have a system for it to make sense of it).
I like to add...
...
System.out.println(" *description* ");
...
... lines to my code blocks for debugging purposes (mostly to catch runtime and logic errors. I usually delete them, but lately I have been just adding "//" before them so that they stay there to prevent having to retype them, slash, to use them as a marker reminding myself that I've already debugged that part.
Is better to delete these "debug println's" rather than adding "//" before them, or if they would both have the same effect on the app runtime ?
Any insights appreciated.
No. By design comments are not used as part of the code (except with certain cases of javadocs appearing in jars).
The compiler which translates the source code into JVM bytecode will simply ignore the comments,
Comments and commented out code have no effect on runtime performance. None whatsoever. (Not even javadoc comments!!)
However, leaving "commented out" debug statements in your code is bad practice because it makes your code a lot harder to read. Obviously, this is not a concern while you are debugging ... but you shouldn't leave them there in the long term.
I recommend two alternatives:
Replace the println calls with use of a logging framework, and log those things at "debug" level. You need to be a bit careful because logging does have an impact on performance. But there are ways to minimize the impact ... depending on the framework you are using.
Use your version control history to keep a snapshot of the code with the debug statements active. Then delete them.
See also:
Commenting out System.out.println
I do use static code analysis on a project with more than 100.000 lines of Java code for quite a while now. I started with Findbugs, which gave me around 1500 issues at the beginning. I fixed the most severe over time and started using additional tools like PMD, Lint4J, JNorm and now Enerjy.
With the more severe issues being fixed, there is a huge number of low severity issues. How do you handle these low priority issues?
Do you try fixing all of them?
Or only in newly written code?
Do you regularly disable certain rules? (I found that I do on nearly any of the available tools).
And if you ignore or disable rules, do you document those? What do your managers say about "leaving some thousand low priority issues not fixed"? Do you use (multiple) tool specific comments in the code or is there any better way?
Keep in mind that static analysis is meant to generate a lot of false positives; this is the price you pay for generally avoiding false negatives. That is, they assume that you would much rather be told incorrectly that something looks suspicious (a false positive) instead of being told that something that's actually a problem is perfectly fine (a false negative).
So in general, you should be configuring these tools rather than accepting the out-of-the-box defaults, which generate a lot of noise.
Do you try fixing all of them?
On projects where I have technical control, my standard modus operandi is to encourage a culture where people review of all new static analysis defects from our CI system. If we decline to fix enough defects over a period of time that are of a specific kind, we disable that rule since it's become just noise. Every so often we'll look at the disabled rules to make sure that they're still relevant.
But once we've turned off the less effective rules, yes, we fix all the defects. If you think that something is a problem, you should fix it if the priority doesn't exceed that of other things you have to do. Ignoring it is damaging to your team's culture and sends the wrong message.
And if you ignore or disable rules, do you document those?
The rules file is part of our project, so a commit message is sufficient to document the fact that such-and-such rules were disabled in this commit.
What do your managers say about "leaving some thousand low priority issues not fixed"?
Nothing. We make sure that they understand what we're doing and why, but they're usually (rightfully so) focused on higher-level metrics, like velocity and overall project health.
What do your managers say about "leaving some thousand low priority issues not fixed"?
I expect managers to prioritize: to decide (or, be told) whether any task is high- or low-priority, and to be happy with people's spending time on high-priority instead of low-priority tasks.
If you were to look at the analogy of your bug tracking database, a good number of those reported are low priority bugs that you'll probably never get to. Sure, they are real bugs and you would like to fix them but most programmers work under very real constraints and don't have the time to address every concern. I wrote an article recently about the special nature of static analysis defects.
One important difference about addressing static analysis bugs though is that they are typically much easier to deal with than a regularly reported bug. Thus a quick scan of the defects to identify not only the high priority items to fix but also the ones that are easiest to fix can be useful. Static analysis defects after all are detected very early in the development process and the specific parts o the code in question are very plainly spelled out. Thus you'll likely catch quite a few low hanging fruit on the lower priority ones.
The various strategies I've seen used to make this successful include:
* First of all, make sure the analysis is tuned properly. Static analysis comes "out of the box" with factory settings and can't possibly understand all code. If you can't tune it yourself get some help (disclaimer, we provide some of that type of help). You'll lower the false positive rate and find more good bugs.
* Identify the characteristics that for the most part prioritize the defects (they could be specific categories, specific areas of the code, built-in prioritization scoring provided by the static analysis tool, etc.).
* Determine what level of threshold is important and possibly make it an acceptance criteria (e.g. all high and critical need to be addressed)
* Make sure that each defect that blocks the acceptance criteria is addressed (addressed meaning that it at least has to be looked at because some could be false positives)
* Make sure that the ones marked false positive are checked, either through a peer code review process or through a tail end audit process so you don't have any mismarking problems.
Bottom line: choose what to focus on, review what is necessary, don't fix everything unless your business requirements make you
Decide what rules you want to follow at your company and disable the rest. A lot of the rules that you can set up with those tools are subjective style issues and can safely be ignored. You should document what rules you are following once in a company style guide (so you don't clutter your code with that information).
I wouldn't make a change to old code just based on the recommendation of a static analysis tool. That code is already tested and presumably working. If I need to go into the code and make a change for any other reason, then I'll run the analysis and make any changes it recommends.
The key in.my mind is to at least review all the issues even if you decide in the end not to fix them. The reason is that bugs, like misery, love company. I can't enumerate ow many times I've found all kinds of nasty bugs that findbugs didn't report; but found them by looking at seemingly unimportant ones that it did report.
I personally find code analysis though useful but overrated.
I can't say for Java but with C# there is also such a thing as a code analysis. I agree it gives you a lot of smart ideas how to do thing better, but at times the recommendations are just annoying. Some suggestions are not based on common sense but are only a matter of style. After some time playing around with the code analysis, I stopped using it. The reason is that I happened to disagree with many warnings and didn't want to follow the proposals.
In general, I would recommend doing what the code analysis says. But up to a certain point. Whatever seems to be a matter of personal style of whoever write the rules definitions, can easily be ignored. You can add exceptions for rule 1, then 2, then three... until it gets old. Then you just deactivate the feature.
I am building a spring mvc web application.
I plan on using hibernate.
I don't have much experience with obfuscating etc.
What are the potential downsides to obfuscating an application?
I understand that there might be issues with debugging the app, and recovering lost source code is also an issue.
Are there any known issues with the actually running of the application? Can bugs be introduced?
Since this is an area I am looking for general guidance, please feel free to open up any issues that I should be aware of.
There are certainly some potential performance/maintenance issues, but a good obfuscator will let you get round at least some of them. Things to look out for:
an obvious one: if your code calls methods by reflection or dynamically loads classes, then this is liable to fail if the class/method names are obfuscated; a good obfuscator will let you select class/method names not to obfuscate to get round this problem;
a similar issue can occur if not all of your application is compiled at the same time;
if it deals directly at the bytecode level, an obfuscator can create code that in principle a Java compiler cannot create (e.g. it can insert arbitrary GOTO instructions, whereas from Java these can only be created as part of a loop)-- this may be a bit theoretical, but if I were writing a JVM, I'd optimise performance for sequences of bytecodes that a Java compiler can create, not ones that it can't...
the obfuscator is liable to make other subtle changes to performance if it significantly alters the number of bytecodes in a method, or in some way changes whether a given method/piece of code hits thresholds for certain JVM optimisations (e.g. "inline methods with fewer than X bytecodes").
But as you can see, some of these effects are a little subtle and theoretical-- so to some extent what you need to do is soak-test your application after obfuscation, just as you would with any other major change.
You should also be careful not to assume that obfuscation hides your code/algorithm (if that is your intention) as much as you want it to-- use a decompiler to have a look at the contents of the resulting obfuscated classes.
Surprised no one has mentioned speed - in general, more obfuscated = slower-running code
[Edit] I can't believe this has -2. It is a correct answer.
Shortening identifiers and removing unused methods will decrease the file-size, but have 0 impact on the running speed (other than the few nanoseconds shaved off the loading time). In the meanwhile, most of the obfuscation of the program comes from added code:
Breaking 1 method into 5; interleaving methods; merging classes [aggregation transformations]
Splitting 1 arithmetic expression into 10; jumbling the control-flow [computation transformations]
And adding chunks of code that do nothing [opaque predicates]
are all common obfuscation techniques that cause a program to run slower.
You may want to look at some of the comments here, to decide if obfuscating makes sense:
https://stackoverflow.com/questions/1988451/net-obfuscation
You may want to express why you want to obfuscate. IMO the best reasons are mainly to have a smaller application, as you can get rid of classes that aren't being used in your project, while obfuscating.
I have never seen bugs introduced, as long as you aren't using reflection, assuming you can find something, as private methods for example will have their names changed.
The biggest problem centers around that fact that obfuscating programs generally make a guarantee of not changing the behavior of their target program. In some cases it proves to be very hard to do this -- for example, imagine a program which checks the value of certain private fields via reflection from a string array. An obfuscator may not be able to tell that this string also needs to be updated correspondingly, and the result will be unexpected access errors that pop up at runtime.
Worse still, it may not be obvious that the behavior of a program has changed subtly -- then you may not know that there's a problem at all, until your customer finds it first and gets upset.
Generally, professional-grade obfuscation products are sophisticated enough to catch some kinds of problems and prevent them, but ultimately it can be challenging to cover all the bases. The best defense is to run unit tests against the obfuscated result and make sure that all your expected behavior continues to hold true.
1 free one you might want to check out is Babel. It is designed to be used on the command line (like many other obfuscators), there is a Reflector addin that will provide a UI for you.
When it comes to obfuscation, you really need to analyze what your goal is. In your case - if you have a web application (mvc) are you planning on selling it as a canned downloadable application? (if not and you keep the source on your web servers then you don't need it).
You might look at the components and pick only certain parts to obfuscate ... not the whole thing. In general ASP.Net apps break pretty easy when you try to add obfuscation after you developed them due to all the reflection used.
Pretty much everything mentioned above is true ... it all depends on how many features you turn on to make it hard to reverse your code:
Renaming of members (fields/methods/events/properties) is most common (comes in different flavors: simple renaming of methods from something like GetId() to a() all the way to unreadable characters and removal of namespaces). BTW: This is where reflection usually breaks. Your assembly file may end up being smaller due to smaller strings being used too.
String encryption: this makes it harder to reverse your static strings used in your code. BTW: this paired with renaming makes it difficult for you to debug your renaming problems ... so you might turn it on after you have that working. This also will have to add code to decrypt the string right before it is used in IL
Code mangling ... this is what BlueRaja was refering to. It makes your code look like spagetti code - to make it harder for someone to figure out. The CLR does not like this ... it can't optimize things as easy and your final code will mostlikely proccess slower due to the additional branching and something not being inlined due to the IL rewriting used for this option. BTW: this option really does raise the bar on what it takes to reverse you source code, but may come with a performance hit.
Removal of unused code. Some obfuscators offer you the option to trim any code that it finds not being used. This may make your assembly a little smaller if you have alot of dead code hanging around ... but it is just a free benefit obfuscators throw in.
My advice is to only use it if you know why you are using it and design with that end in mind ... don't try to add it after you've finished your code (I've done that and it's not fun)