I am developing java code where sql query is already, but it it leads to sql injection, I am using setString method to avoid sql injection. But the setstring is adding single quotes for parameter values, so my query is failing. How can I remove single quotes for setString methods.
I have tried to use replaceAll method, but it does not work for preapred statements.
String X="where IP ?";
String Y=" group by user";
String Z="order by descend";
query="select appname,user,IP from xyz "+X+" "+Y+Z; --> this is existing query.
I am changing query as below
query="select appname,user,IP from xyz ? ? ?";
Object=connectionObj.prepareStatement(query);
Object.setString(1,X);
Object.setString(2,Y);
Object.setString(3,Z);
but here setString method is adding single quoes for the values so my query is failing as syntax error.I tried replceAll("'"," ") method but it only works for strings not for prepared statements.I am stuck with syntax error.Please help me out to solve this issue in JAVA.
What you are trying to do is also SQL injection. Where are the values of X, Y, and Z coming from? Code your program to build up the SQL based on your business needs, adding the fragments of SQL using StringBuilder from within your program. If you have control over the fragments, it is not SQL injection. You should only be using parameters (?) for values compared with the data within your tables. You could also consider a tool like myBatis if you have a need to dynamically create SQL.
This is what I did, I hope it will benefit someone:
List<String> temp = new ArrayList<>();
String placeholder = "";
while(rst.next()){
temp.add(rst.getString("ISSN"));
placeholder += "?,";
}
placeholder = placeholder.replaceAll(",$", "");
ps=con.prepareStatement("select * from BOOKS where ISSN in "+ "("+placeholder+")");
for (int i=1; i<=temp.size(); i++){
ps.setString(i, temp.get(i-1));
}
rs =ps.executeQuery();
Related
I'm having issues dealing with the single quote while using it in a prepared statement in JAVA via Oracle JDBC.
Let's say we have a table Restaurant with a column restaurant_name with 1 value : Jack's Deli
I want to use a simple prepared statement query like this:
String result = "Jack\'\'s Deli"
String sqlStatement = "select * from Restaurant where restauraunt_name like ? escape '\\' ";
PreparedStatement pStmt = conn.prepareStatement(sqlStatement);
pstmt.setString(1, result);
The result shows 0 returned values, however when I directly search the query in the database (ORACLE) it works fine and retrieves the result. (Oracle uses two single quotes as an escape for the first)
I am thinking that the value is not being passed properly to the database. Or there is some other formatting issue.
The point of prepared statements is that you don't need any escaping.
.setString(1, "Jack's Deli") will get it done.
I was wondering if there was any way to specify returned column names using prepared statements.
I am using MySQL and Java.
When I try it:
String columnNames="d,e,f"; //Actually from the user...
String name = "some_table"; //From user...
String query = "SELECT a,b,c,? FROM " + name + " WHERE d=?";//...
stmt = conn.prepareStatement(query);
stmt.setString(1, columnNames);
stmt.setString(2, "x");
I get this type of statement (printing right before execution).
SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'
I would, however, like to see:
SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
I know that I cannot do this for table names, as discussed
here, but was wondering if there was some way to do it for column names.
If there is not, then I will just have to try and make sure that I sanitize the input so it doesn't lead to SQL injection vulnerabilities.
This indicates a bad DB design. The user shouldn't need to know about the column names. Create a real DB column which holds those "column names" and store the data along it instead.
And any way, no, you cannot set column names as PreparedStatement values. You can only set column values as PreparedStatement values
If you'd like to continue in this direction, you need to sanitize the column names (to avoid SQL Injection) and concatenate/build the SQL string yourself. Quote the separate column names and use String#replace() to escape the same quote inside the column name.
Prepare a whitelist of allowed column names. Use the 'query' to look up in the whitelist to see if the column name is there. If not, reject the query.
For MySQL prepared statements with NodeJS (mysqljs/mysql), what you need to know is that ? is for values, but if you need to escape column names, table names etc, use ?? instead.
Something like this will work:
SELECT ??, ??, ?? FROM ?? WHERE ?? < ?
Set values to ['id', 'name', 'address', 'user', 'id', 100]
I think this case can't work because the whole point of the prepared statement is to prevent the user from putting in unescaped query bits - so you're always going to have the text quoted or escaped.
You'll need to sanitize this input in Java if you want to affect the query structure safely.
Use sql injection disadvantage of Statement Interface as advantage.
Ex:
st=conn.createStatement();
String columnName="name";
rs=st.executeQuery("select "+ columnName+" from ad_org ");
public void MethodName(String strFieldName1, String strFieldName2, String strTableName)
{
//Code to connect with database
String strSQLQuery=String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
st=conn.createStatement();
rs=st.executeQuery(strSQLQuery);
//rest code
}
Below is the solution in java.
String strSelectString = String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
Imagine I would like to search my database for one or a combination of fields. Now I do not know how many of these fields I have. So I made a function which takes them all as argument but empty Strings for the ones which are not applicable (or 0 for ints)
findSometing(int serial, String att1, String att2, String att3)
Now when I'm making the query SELECT * FROM TableName WHERE I cannot determine where to put my AND commands. Does anyone have a good solution to this problem? I can do it with a lot of if statements but thats messy.
Just to add I HAVE to use JDBC.
String query = "SELECT * FROM TableName WHERE 1=1";
if(a!=null)
query+="AND a=?";
if(b!=null)
query+="AND b=?";
PreparedStatement stmt ...
I can't find the correct syntax of the following query in java,please help me.
String st = "SELECT COUNT('"+id+"') FROM '"+selected_table+"' ";
String st = "SELECT COUNT('"+id+"') FROM '"+selected_table+"'";
I think that the mistake is how to end the query...
Since I got the error Check the manual that corresponds to your MySQL server version for the right syntax to use near ''Customer'' at line 1
when I choose Customer table
You want to use backticks instead of single quotes around your object names.
String st = "SELECT COUNT(`"+id+"`) FROM `"+selected_table+"` ";
Table names should be surrounded by tick marks (`), not single quotes (')
String st = "SELECT COUNT('"+id+"') FROM `"+selected_table+"`";
^ use tick marks ^
What are the values of id and selected_table? What is the actual query string that is sent to the database?
Also, it's rarely a good idea to manually build a query like this using string concatenation. This makes it very easy for a bug to result in a gaping security hole, and it's a lot more difficult (and risky) to try to secure this approach than it is to just do it right.
Looks from your query that you are enclosing your id and selected_table in single quotes... For example, SELECT COUNT('ID') FROM 'CUSTOMER' which is wrong. should be in backtics `` or nothing...
I was wondering if there was any way to specify returned column names using prepared statements.
I am using MySQL and Java.
When I try it:
String columnNames="d,e,f"; //Actually from the user...
String name = "some_table"; //From user...
String query = "SELECT a,b,c,? FROM " + name + " WHERE d=?";//...
stmt = conn.prepareStatement(query);
stmt.setString(1, columnNames);
stmt.setString(2, "x");
I get this type of statement (printing right before execution).
SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'
I would, however, like to see:
SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
I know that I cannot do this for table names, as discussed
here, but was wondering if there was some way to do it for column names.
If there is not, then I will just have to try and make sure that I sanitize the input so it doesn't lead to SQL injection vulnerabilities.
This indicates a bad DB design. The user shouldn't need to know about the column names. Create a real DB column which holds those "column names" and store the data along it instead.
And any way, no, you cannot set column names as PreparedStatement values. You can only set column values as PreparedStatement values
If you'd like to continue in this direction, you need to sanitize the column names (to avoid SQL Injection) and concatenate/build the SQL string yourself. Quote the separate column names and use String#replace() to escape the same quote inside the column name.
Prepare a whitelist of allowed column names. Use the 'query' to look up in the whitelist to see if the column name is there. If not, reject the query.
For MySQL prepared statements with NodeJS (mysqljs/mysql), what you need to know is that ? is for values, but if you need to escape column names, table names etc, use ?? instead.
Something like this will work:
SELECT ??, ??, ?? FROM ?? WHERE ?? < ?
Set values to ['id', 'name', 'address', 'user', 'id', 100]
I think this case can't work because the whole point of the prepared statement is to prevent the user from putting in unescaped query bits - so you're always going to have the text quoted or escaped.
You'll need to sanitize this input in Java if you want to affect the query structure safely.
Use sql injection disadvantage of Statement Interface as advantage.
Ex:
st=conn.createStatement();
String columnName="name";
rs=st.executeQuery("select "+ columnName+" from ad_org ");
public void MethodName(String strFieldName1, String strFieldName2, String strTableName)
{
//Code to connect with database
String strSQLQuery=String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
st=conn.createStatement();
rs=st.executeQuery(strSQLQuery);
//rest code
}
Below is the solution in java.
String strSelectString = String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);