Findbugs not finding potential SQL injection vulnerability - java

I just installed the FindBugs plugin for Eclipse, with the hope that it will help me find SQL injection vulnerabilities in my code. However, it doesn't seem to be finding anything, even when I deliberately put some in.
In the following examples, assume staticFinalBaseQuery is declared as follows:
public static final String staticFinalBaseQuery = "SELECT foo FROM table where id = '";
and assume userInputfilterString is an argument to the method wrapping the example snippets. It comes direct from user input, and is not sanitized.
For example, the following snippet will not trigger a warning:
String query = staticFinalBaseQuery + userInputfilterString;
pstmt = dbConnection.prepareStatement(query);
Where staticFinalBaseQuery is a static final string, and userInputfilterString is a string direct from user input, available only at runtime, not scrubbed at all. Clearly, this is a vulnerability.
I expect the "A prepared statement is generated from a nonconstant String" warning to be triggered.
The following snippet also does not cause a warning (not surprising, since the compiled forms of these are probably identical):
pstmt = dbConnection.prepareStatement(staticFinalBaseQuery + userInputfilterString);
However, this will cause a warning:
pstmt = dbConnection.prepareStatement(staticFinalBaseQuery + userInputfilterString + "'");
If I append an empty string, or a space, no warning is triggered.
So, my question is, how can I get FindBugs to trigger on my first example? I am also curious why the first doesn't cause a warning, but the last does?
Thanks in advance!
EDIT: I submitted a bug to FindBugs's bug tracking system, as it seems this might be a bug. However, if anyone has any tips, I'd love to hear them.

It is hard to distinguish between safe code and unsafe code here. Sure, userInputfilterString may be unsafe, but it is impossible to determine this at compile time. However, the single-quote character in a string concatenation is a tell-tale sign of using inject-able code. That's why FindBugs is triggering on the line containing this character, but not on the line with mere string concatenation.
Basically, this isn't a bug, but a limitation of how much can be done by software to check for SQL injection. Since the string may contain anything (i.e. it could have the vulnerable concatenation in another function) it is impossible to have the tool determine with any certainty that a problem exists.

I don't think PMD or Checkstyle will catch it either, but you might give them a try (I use all 3 on a regular basis, good tools to use).
EDIT: PMD was the correct link, but I called it findbugs... findbugs on the brain I guess...

Consider upgrading to commercial software such as http://www.ouncelabs.com/ which will serve your purpose much better...

Related

FindsBug Warning:A prepared statement is generated from a nonconstant String

I'm getting the findsbug warning like "A prepared statement is generated from a nonconstant String".My Scenerio like
//My code
public static int updateSQL(String sql) throws StoreException {
PreparedStatement statement = null;
statement = connection.prepareStatement(sql); //shows violation here
}
I'm getting "sql" through argument of the method.how to rectify this warning?Kindly help me to fix this issue.
Well, in this case I'd suggest to ignore this warning. It has low priority. The low-priority reports for this particular bug pattern are actually mostly junk. To my opinion it should not be reported as FindBugs is capable to go step further and see whether the updateSQL method is always called with constant string (in this case you have no problems) or not (in this case the specific places where non-constant string is used will be reported). I filed a bug report to our tracker.
I think this is not a serious warning. I got the same warning while trying to use a SQL query which a part of it is dynamic(Changes with the occasion). There is not a proper way to avoid this scenario. So you can just avoid it.

PMD Rule for making comparisons against constants

I have a formal coding policy that when doing comparisons against constants, that the constant [non-primitive] should be compared to the object in question.
For example:
final String BEST_NAME = "Jim";
String myName = "Bob";
The comparison should be
BEST_NAME.equalsIgnoreCase(myName)
I can not seem to find the PMD specific rule for this... does it exist?
I guess you are looking for something similar to the PositionLiteralsFirstInCaseInsensitiveComparisons PMD rule.
The rule states that the constant value should be first in comparisons.
This works most of the time for inline (e.g. myName.equals("Jim")) cases, however it will never find the example you showed us (e.g. myName.equalsIgnoreCase(BEST_NAME)) because PMD cannot make reference to constant fields.
I would recommend the use of FaultHunter which can detect these kind of rule violations as well, and yet it still uses the familiar Position Literals First In Comparisons name for the rule, so it is very easy to adapt. You can see an example for yourself on this demo page.
I can not seem to find the PMD specific rule for this... does it exist?
It is highly unlikely that it does1, because such a rule is project (or maybe organization) specific. Indeed, for most people / projects / organizations, such a rule would be "just plain wrong". Use of case insensitive comparisons for all String constants is not normal / standard / best practice.
However, I did find this rule that is similar to what you are asking for:
PositionLiteralsFirstInCaseInsensitiveComparisons - which says, if you are comparing strings using equalsIgnoreCase THEN you should use the literal value as the target.
If you need to, you can write custom PMD rules for your project / organization ... if this is what you need.
Reference:
How to write a PMD rule.
1 - OK, it is possible someone else also has this requirement, and has already written such a PMD rule. However, it is probably more effort to track down the code and repurpose it, than it is to write the PMD rule from scratch ...

Avoid Literals In If Condition SonarQube error

I am getting error like Avoid Literals In If Condition in sonarqube , and unable to find the proper solution to it.
SingleWrapper singleWrapper=null;
:
:
singleWrapper=createWrapper();
:
private void wrap(){
if(singleWrapper != null){ //Here i am getting error.
//do Something
}
}
I know this question seems to be repeated one but its not,because previously asked for String .
Thanks for any help.
It is because your static code analysis tool detects null as a hardcoded literal, which, rigorously, is true.
The recommended behavior is to declare a constant object like
final static Object NULL = null;
and use it like
if(singleWrapper != NULL)
But I haven't still met a developer doing this. In this case, I think you're OK and you can ignore the code check warnings. That's my 2 cents.
The description for the PMD rule reads:
Avoid using hard coded literals in conditional statements, declare those as static variables or private members.
While in most cases it is relevant (you don't want to have arbitrary hard coded string or numerical literals), in this case it is (IMHO) a bit too zealous, for checking against null is so widely used that it should probably be ignored by this rule.
Since this rule comes from PMD (not SQ internal engine), you could ask for an upstream fix - or just remove it from your profile if it really bugs you.
Note that this rule is part of the Controversial Rules set.

How verify user input in command line arguments for higher security?

I am getting a String into Java program from a user via command line arguments.
The question is what kind of checks I should perform to prevent possible attacks and vulnerabilities?
I am not expert in security area, but as far as I know
In C too long line specified by user and handled improperly could lead to buffer overflow
In PHP line containing ` characters and handled improperly could lead to SQL injection
For now I can not think about any specific format of a String to apply some regex to check. It can be arbitrary, but if is looks harmful I want to quit immediately. The string might to send to a Java server with network, there it might be used for an SQL query.
if (args.length > 0) {
String arg0 = args[0];
if (!isValidString(arg0)){
System.exit(1);
}
}
public boolean isValidString (String str) {
if (str == null) return false;
//TODO: many more checks here
return true;
}
I am sure Java is much more secure than C or early PHP, but what should I be aware about?
If this main class does nothing other than passing its argument to somewhere else, then it's not its responsibility to validate the string.
If this string finally goes to a class which uses it in a SQL query, then it's the responsibility of this class to use a prepared statement and thus make sure no SQL injection attack is possible.
If this string ends up being part of a generated HTML page, then it's the responsibility of the HTML generator to HTML-escape the string.
A string, by itself, is never harmful. If you have to validate it, then you need to know when it is valid, and when it's not. And it depends on the context.
It all depends on what you are doing with the string, as in what inputs you are expecting obviously always double check those before you use them.
If you are worried about SQL injection from users you can use prepared statements to help prevent against SQL Injection as the statement is compiled before it is used and the query plan stored for further use so the parameters do not become part of the executable SQL.
If you are worried about user input appearing on web pages etc then you should escape it for a webpage:
Recommended method for escaping HTML in Java
The escaping / validating you should do depends entirely on your use for the string.
I'm afraid, that this question is far-fetched problem.
In worst case, I think, (I can't imagine how it could be reproduced) you could have a deal with OutOfMemory exception if a String array passed into main() method will be enough large.

Why does the Java compiler only report one kind of error at a time?

I've a snippet
class T{
int y;
public static void main(String... s){
int x;
System.out.println(x);
System.out.println(y);
}
}
Here there are two error, but on compilation why only one error is shown?
The error shown is:
non-static variable y cannot be referenced from a static context
System.out.println(y);
^
But what about the error
variable x might not have been initialized
System.out.println(x);
^
The Java compiler compiles your code in several passes. In each pass, certain kinds of errors are detected. In your example, javac doesn't look to see whether x may be initialised or not, until the rest of the code actually passes the previous compiler pass.
#Greg Hewgill has nailed it.
In particular, the checks for variables being initialized, exceptions being declared, unreachable code and a few other things occur in a later pass. This pass doesn't run if there were errors in earlier passes.
And there's a good reason for that. The earlier passes construct a decorated parse tree that represent the program as the compiler understands it. If there were errors earlier on, that tree will not be an accurate representation of the program as the developer understands it. (It can't be!). If the compiler then were to go on to run the later pass to produce more error messages, the chances are that a lot of those error messages would be misleading artifacts of the incorrect parse tree. This would only confuse the developer.
Anyway, that's the way that most compilers for most programming languages work. Fixing some compilation errors can cause other (previously unreported) errors to surface.
The Dragon Book ("Compilers: Principles, Techniques, and Tools" by Aho, Sethi, and Ullman) describe several methods that compiler writers can employ to try to improve error detection and reports when given input files that don't conform to the language specification.
Some of the techniques they give:
Panic mode recovery: skip all input tokens in the input stream until you have found a "synchronizing token" -- think of ;, }, or end statement and block terminators or separators, or do, while, for, function, etc. keywords that can show intended starts of new code blocks, etc. Hopefully the input from that point forward will make enough sense to parse and return useful error messages.
Phrase level recovery: guess at what a phrase might have meant: insert semicolons, change commas to semicolons, insert = assignment operators, etc., and hope the result makes enough sense to parse and return useful error messages.
Error productions: in addition to the "legitimate" productions that recognize allowed grammar operators, include "error productions" that recognize mistakes in the language that would be against the grammar, but that the compiler authors recognize as very likely mistakes. The error messages for these can be very good, but can drastically grow the size of the parser to optimize for mistakes in input (which should be the exception, not the common case).
Global correction: try to make minimal modifications to the input string to try to bring it back to a program that can be parsed. Since the corrections can be made in many different ways (inserting, changing, and deleting any number of characters), try to generate them all and discover the "least cost" change that makes the program parse well enough to continue parsing.
These options are presenting in the chapter on parsing grammars (page 161 in my edition) -- obviously, some errors are only discovered after the input file has been parsed, but is beginning to be converted into basic blocks for optimization and code generation. Any errors that occur in the earlier syntactic levels will prevent the typical compiler from starting the code optimization and generation phases, and any errors that might be detected in these phases must wait for fixed input before they can be run.
I strongly recommend finding a copy of The Dragon Book, it'll give you some sympathy and hopefully new-found respect for our friendly compiler authors.
The whole point of an error is that the compiler doesn't know how to interpret your code correctly. That's why you should always ignore errors after the first one, because the compiler's confusion may result in extra/missing errors.

Categories

Resources