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.
Related
In case I am handling passwords in my application, is it absolutely necessary that I use char array instead of a String object? If my application is configured to write no logs or anything and memory dumps are least expected, will it be too imprudent to use a String object?
It would be beneficial if I could use a String object because I would then be able to use a library (jBCrypt) which I otherwise will not be able to use.
It depends on how much security you want your application to have. In most circumstances, I imagine you'll be fine using a String. Especially if you're not dumping out any output that could contain this String.
However, this does make your application slightly less secure. See this post for more information: Why is char[] preferred over String for passwords?
Background: I have started a project using JDBC and MYSQL to simulate a bookstore, all local. To connect to the database, I started out using a Statement but I began to read that when using a query multiple times that just changes its parameters, it can be more efficient to use a PreparedStatement for those queries. However, the thing advantage I read the most about was how PreparedStatements could prevent SQL injection much better.
Sources:
Answers on this thread here
Google
Professors
My Question:
How do PreparedStatements prevent SQL injection better, or even different for that matter, than Statements when dealing with parametrized queries? I am confused because, if I understand correctly, the values still get passed into the SQL statement that gets executed, it's just up to the the programmer to sanitize the inputs.
You're right that you could do all the sanitation yourself, and thus be safe from injection. But this is more error-prone, and thus less safe. In other words, doing it yourself introduces more chances for bugs that could lead to injection vulnerabilities.
One problem is that escaping rules could vary from DB to DB. For instance, standard SQL only allows string literals in single quotes ('foo'), so your sanitation might only escape those; but MySQL allows string literals in double quotes ("foo"), and if you don't sanitize those as well, you'll have an injection attack if you use MySQL.
If you use PreparedStatement, the implementation for that interface is provided by the appropriate JDBC Driver, and that implementation is responsible for escaping your input. This means that the sanitization code is written by the people who wrote the JDBC driver as a whole, and those people presumably know the ins and outs of the DB's specific escaping rules. They've also most likely tested those escaping rules more thoroughly than you'd test your hand-rolled escaping function.
So, if you write preparedStatement.setString(1, name), the implementation for that method (again, written by the JDBC driver folks for the DB you're using) could be roughly like:
public void setString(int idx, String value) {
String sanitized = ourPrivateSanitizeMethod(value);
internalSetString(idx, value);
}
(Keep in mind that the above code is an extremely rough sketch; a lot of JDBC drivers actually handle it quite differently, but the principle is basically the same.)
Another problem is that it could be non-obvious whether myUserInputVar has been sanitized or not. Take the following snippet:
private void updateUser(int name, String id) throws SQLException {
myStat.executeUpdate("UPDATE user SET name=" + name + " WHERE id=" + id);
}
Is that safe? You don't know, because there's nothing in the code to indicate whether name is sanitized or not. And you can't just re-sanitize "to be on the safe side", because that would change the input (e.g., hello ' world would become hello '' world). On the other hand, a prepared statement of UPDATE user SET name=? WHERE id=? is always safe, because the PreparedStatement's implementation escapes the inputs before it plugs values into the ?.
When using a PreparedStatement the way it is meant to be used - with a fixed query text with parameter placeholders, no concatenation of external values -, then you are protected against SQL Injection.
There are roughly two ways this protection works:
The JDBC driver properly escapes the values and inserts them in the query at the placeholder positions, and sends the finished query to the server (AFAIK only MySQL Connector/J does this, and only with useServerPrepStmts=false which is the default).
The JDBC driver sends the query text (with placeholders) to the server, the server prepares the query and sends back a description of the parameters (eg type and length). The JDBC driver then collects the parameter values and sends these as a block of parameter values to the server. The server then executes the prepared query using those parameter values.
Given the way a query is prepared and executed by the server, SQL injection cannot occur at this point (unless of course you execute a stored procedure, and that stored procedure creates a query dynamically by concatenation).
The framework , Sql driver makes sure to escape the input. If you use string Statements and escape properly - will achieve same result. But that is not recommended as Preparend statements seem like more lines of code but lead to more structured code as well. Instead of a soup of long sql lines.
Plus since we set each parameter separately and explicitly the underlying driver class can escape them correctly depending on the data base in use. Meaning you could change the data base by config, but no matter the driver takes care of escaping. So one data base might need slashes escaped and another might want two single quotes ...
This also leads to less code as you do not need to bother about this. Simply put you let the framework / common classes one level below the app code take care of it.
In Java I have a method:
private boolean testFunction(int x){
// codes goes here..
}
Now I have a expression written in file something like:
if(testFunction(10)){ return "ok"; }else{ return null;}
I am storing this in a String variable inside java program and want to execute it like it should execute as Java code:
if(testFunction(10)){ return "ok"; }else{ return null;}`
Is it possible?
The thing is I have a web application where there are 10+ different kind of form having different kind of fields i.e in some form X,Y,Z is there and X,Y is required....in some form A,B,C is there and C is only required like this.
So instead of writing validation code for each form i wanted to write a expression in XML file and at the time evaluation these expression will execute by single java method and return some value. So in this way I will just have to write expression in XML file.
No. Java is a compiled language, it is not interpreted.
There are ways of generating bytecode dynamically in Java, but they are highly involved, and aren't anywhere close to the concept of eval(String code)
If you want dynamic validation for form entries, I'd suggest using RegExp expressions which can be evaluated and matched against form input at runtime.
Unfortunately your OP was a bit vague as to what you're actually trying to achieve.
To get you started: RegExp Pattern class
I've heard that using exceptions for control flow is bad practice. What do you think of this?
public static findStringMatch(g0, g1) {
int g0Left = -1;
int g0Right = -1;
int g1Left = -1;
int g1Right = -1;
//if a match is found, set the above ints to the proper indices
//...
//if not, the ints remain -1
try {
String gL0 = g0.substring(0, g0Left);
String gL1 = g1.substring(0, g1Left);
String g0match = g0.substring(g0Left, g0Right);
String g1match = g1.substring(g1Left, g1Right);
String gR0 = g0.substring(g0Right);
String gR1 = g1.substring(g1Right);
return new StringMatch(gL0, gR0, g0match, g1match, gL1, gR1);
}
catch (StringIndexOutOfBoundsException e) {
return new StringMatch(); //no match found
}
So, if no match has been found, the ints will be -1. This will cause an exception when I try to take the substring g0.substring(0, -1). Then the function just returns an object indicating that no match is found.
Is this bad practice? I could just check each index manually to see if they're all -1, but that feels like more work.
UPDATE
I have removed the try-catch block and replaced it with this:
if (g0Left == -1 || g0Right == -1 || g1Left == -1 || g1Right == -1) {
return new StringMatch();
}
Which is better: checking if each variable is -1, or using a boolean foundMatch to keep track and just check that at the end?
Generally exceptions are expensive operations and as the name would suggest, exceptional conditions. So using them in the context of controlling the flow of your application is indeed considered bad practice.
Specifically in the example you provided, you would need to do some basic validation of the inputs you are providing to the StringMatch constructor. If it were a method that returns an error code in case some basic parameter validation fails you could avoid checking beforehand, but this is not the case.
I've done some testing on this. On modern JVMs, it actually doesn't impact runtime performance much (if at all). If you run with debugging turned on, then it does slow things down considerably.
See the following for details
(I should also mention that I still think this is a bad practice, even if it doesn't impact performance. More than anything, it reflects a possibly poor algorithm design that is going to be difficult to test)
Yes, this is a bad practice, especially when you have a means to avoid an exception (check the string length before trying to index into it). Try and catch blocks are designed to partition "normal" logic from "exceptional" and error logic. In your example, you have spread "normal" logic into the exceptional/error block (not finding a match is not exceptional). You are also misusing substring so you can leverage the error it produces as control flow.
Program flow should be in as straight a line as possible(since even then applications get pretty complex), and utilize standard control flow structures. The next developer to touch the code may not be you and (rightly)misunderstand the non-standard way you are using exceptions instead of conditionals to determine control flow.
I am fighting a slightly different slant on this problem right now during some legacy code refactoring.
The largest issue that I find with this approach is that using the try/catch breaks normal programmatic flow.
In the application I am working on(and this is different from the sample you have applied), exceptions are used to communicate from within a method call that a given outcome(for instance looking for an account number and not finding it) occurred. This creates spaghetti code on the client side, since the calling method (during a non-exceptional event, or a normal use-case event) breaks out of whatever code it was executing before the call and into the catch block. This is repeated in some very long methods many times over, making the code very easy to mis-read.
For my situation, a method should return a value per it's signature for all but truly exceptional events. The exception handling mechanism is intended to take another path when the exception occurs (try and recover from within the method so you can still return normally).
To my mind you could do this if you scope your try/catch blocks very tightly; but I think it is a bad habit and can lead to code that is very easy to misinterpret, since the calling code will interpret any thrown exception as a 'GOTO' type message, altering program flow. I fear that although this case does not fall into this trap, doing this often could result in a coding habit leading to the nightmare that I am living right now.
And that nightmare is not pleasant.
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...