JPA - Run sql NativeQuery of 'insert into' with special charters is failed - mysql

I'm using hibernate and mysql
when I run the following statement in mysql it works perfectly:
INSERT INTO table1 (name, is_visited) VALUES ('visit our site \'n\' days',true);
However, When I run with hibernate native query I get error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'days',true)' at line 1.
Here is the java code:
String query = "INSERT INTO table1 (name, is_visited) VALUES ('visit our site \'n\' days',true)";
Query nativeQuery = getEntityManager().createNativeQuery(query);
nativeQuery.executeUpdate();
When I change the query statement to
"INSERT INTO table1 (name, is_visited) VALUES ('visit our site \'n days',true)";
it works.
looks like there is an issue with \'n\'
any idea?

What is happening here is that the following query is correctly escaping the single quotes when run directly on MySQL:
INSERT INTO table1 (name, is_visited) VALUES ('visit our site \'n\' days', true);
This works on MySQL because one valid way to escape literal quotes on MySQL is to escape them with backslash. However, doing this inside a Java string means that the \' are not being passed to MySQL. Instead, Java consumes the single backslash, and just the single quotes make it across to the database. I suggest using the other method of escaping single quotes here, which is to double them up:
String query = "INSERT INTO table1 (name, is_visited) VALUES ('visit our site ''n''x days', true)";
While it might be possible to escape the backslashes from Java, that seems confusing to me, because it requires keeping track of escaping across both your Java and database layer.
As another general comment, if you used the Hibernate ORM layer to do the insert, or used a prepared statement, you wouldn't have to worry about this escaping problem.

Related

JMeter sql syntax error using parameters with insert

I'm working with JMeter to load test queries on a mySQL database (memsql server, mySQL syntax). I'm using a gui version of JMeter to create a test plan xml file and then go to another server and run that xml in non-gui mode.
I have two queries running, one that selects and one that inserts. Both queries use parameters taken from a csv file I made with a script.
My SELECT statement works just fine with parameters taken from a csv file but I run into syntax errors with my INSERT statement:
INSERT INTO customer_transactions_current (`column_name1`, ... , `column_name12`)
VALUES ((${r1},${r2},${r3},${r4},${r5},${r6},${r7},${r8},${r9},${r10},${r11},${r12}));
In the section of the query in the gui mode under 'CSV Data Set Config' I choose to delimit the data by ',' and the variable names are r1,..,r12.
Under the query itself I entered the parameter types and again the same names, just as I did for the working SELECT query.
When I run the query I run into a syntax error on the first column (which is of type datetime):
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '19:00:00,75400492,936988,56,1115,5,2156,8,2,3,909,3))' at line 2
The dates I'm entering are of the form: '2018-11-2 20:00:00' and in the csv file they are present without apostrophes.
It seems that the syntax error has something to do with the date and in the position where it holds a space. I tried entering the STR_TO_DATE function for that column but kept getting syntax errors.
BUT when I try to take some values from the file and manually run the query it works fine! So my thoughts are that it has something to do JMeter's conversion of spaces before sending out the query.
Is the problem with my configurations of JMeter? Since the query is OK manually.
Add apostrophes to insert and remove unnecessary parenthesis
INSERT INTO customer_transactions_current ('column_name1', ... , 'column_name12')
VALUES ('${r1}','${r2}','${r3}','${r4}','${r5}','${r6}','${r7}','${r8}','${r9}','${r10}','${r11}','${r12}');
If you have date issue see using STR_TO_DATE

MySQL code to insert a username and password into a table if a licencing key exists in that table

I am trying to accomplish a simple licensing system in golang and have tried numerous ways to get it to work. Basically, I have input a couple of random licensing keys into my database and my golang program should check to see if the user-input key exists and if it does then add the user specified username and password into the database to login later.
This is the code that I have that hasn't been working:
"IF EXISTS (SELECT * FROM login WHERE LK = "+reglicenceEntry.Text()+") THEN
INSERT INTO `login` (`Username`, `Password`, `LK`) VALUES
('"+regusernameEntry.Text()+"', '"+regpasswordEntry.Text()+"', ''); "
This is the golang error:
Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS (SELECT * FROM login WHERE LK = '5qp515YHXEmSDzwqgoJh') THEN INSERT IN' at line 1
Thanks so much!
MySQL syntax doesn't support IF...THEN constructs except within stored routines and triggers and events. See https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-compound-statements.html
I suggest an alternative solution for your code:
INSERT INTO `login` (`Username`, `Password`, `LK`)
SELECT ?, ?, ''
FROM `login`
WHERE `LK` = ?
LIMIT 1
If your login table does not have the LK value, the SELECT above will return 0 rows, therefore it will not insert anything.
If your login table has the LK value, the SELECT above will return at least 1 row (and I limit it to 1), therefore it will insert a row. The row it inserts is comprised of your username and password, and a blank string for the LK.
I showed use of parameter placeholders. You should use parameters in SQL instead of concatenating variables into your query. This is good practice to avoid accidental SQL injection. See http://go-database-sql.org/prepared.html for examples.
The purpose of using parameters is to avoid SQL injection problems. See my answer to What is SQL injection? for an explanation of SQL injection.
Or my presentation SQL Injection Myths and Fallacies (or youtube video).
When using parameters, you do two steps.
The first step to prepare a query with placeholders (?) where you would otherwise concatenate variables into your SQL query.
The second step is to execute the prepared query, and this is the time you pass the variables to fill in the placeholders.
The point is to keep variables separate from your query, so if there's anything in the variable that could unintentionally change your SQL syntax (like imbalanced quotes), it is never combined with the SQL. After you do the prepare, the SQL has already been parsed by the MySQL server, and there's no way to change the syntax after that.
MySQL remembers which parts of the query need to be filled in, and when you pass variables during the execute step, MySQL fills in the missing parts of the query using your values — but this happens within the MySQL server, not in your application.
Thus the dynamic parts of the query — your variables — are kept separate from the SQL syntax and you avoid SQL injection problems.
For your task described in your question, it would look something like this (I have not tested this Go code, but it should put you on the right path).
stmt, err := tx.Prepare("INSERT INTO `login` (`Username`, `Password`, `LK`) SELECT ?, ?, '' FROM `login` WHERE `LK` = ? LIMIT 1")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
_, err = stmt.Exec(regusernameEntry.Text(), regpasswordEntry.Text(), reglicenceEntry.Text())
if err != nil {
log.Fatal(err)
}
The order of parameters is important. The variables you pass to Exec() must be in the same order that the ? placeholders appear in your prepared SQL statement. They are matched up, one for one, in the same order, by the MySQL server.
Do not put quotes around the placeholders in your prepared SQL statement. That will work as a literal string '?' in SQL. Use an unquoted ? character for a placeholder. When it gets combined by MySQL in the server, it will work as if you had put quotes around the value like a string — but with no risk of SQL injection even if that string value containing special characters.
Here's another site that gives more code examples: https://github.com/go-sql-driver/mysql/wiki/Examples
The Exec() function is for executing SQL that has no result set, like INSERT, UPDATE, DELETE. There are other functions in the Go SQL driver like Query() and QueryRow() that also accept parameter arguments. You'd use these if your SQL returns a result set.

Getting MySQL Error #1064 when trying to insert data

I'm trying to follow a tutorial on this website, but when I try to insert the below statement I get the following error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds
to your MySQL server version for the right syntax to use near
'`INSERT INTO login_admin (user_name, user_pass)
VALUES
(
‘admin’, SHA(‘a`' at line 7
INSERT INTO login_admin (user_name, user_pass)
VALUES
(
‘swashata’, SHA(‘swashata’)
)
INSERT INTO login_admin (user_name, user_pass)
VALUES
(
‘admin’, SHA(‘admin’)
)
You're trying to run two queries at once, not one. Each INSERT statement is a separate query. You have to separate queries with a delimiter (;).
In fact, unless you have some bad settings on your server (allowing multiple queries at once), you can't even do that and need to run them as two separate queries, or combine them using multiple VALUES lists.
Also, please note that you cannot use tick marks (‘) to indicate a string value. You need to use single quotes (') instead.
The best approach is to rewrite your queries as:
INSERT INTO login_admin (`user_name`, `user_pass`) VALUES
( 'swashata', SHA('swashata') ),
( 'admin', SHA('admin') )
Finally, I really hope you aren't using SHA to generate passwords. That's not secure. Use PHP's built-in password functionality.

SQL insertion protection using RMySQL

I am trying to implement SQL insertion protection to SQL select statements using RMySQL. I have been trying to prepend an escape character (i.e. a backslash) in front of each risk character - i.e. a quote (" or ') or backslash (\). I am using the RMySQL function, dbEscapeStrings which appears to be similar to PHP's mysql_real_escape_string function.
I suspect I am missing something very obvious but, as MySQL requires character strings in the WHERE statement to be enclosed by quotes, using dbEscapeStrings to apply escape characters to quotes in the select statement is throwing an error blocking all string queries, not just the injection attacks. For example,
user <- "'peter'"
tmp <- sprintf("select * from users where username = %s", user)
sql <- dbEscapeStrings(con, tmp)
dbGetQuery(con, sql)
dbEscapeStrings inserts a double backslash in front of each quote (i.e. the sql variable produced is "select * from users where username = \\'peter\\'") which throws a syntax error on the MySQL server when dbGetQuery is run.
Any suggestions appreciated on how to get the above to work or implement an alternative SQL insertion protection using RMySQL? Does RMySQL provide for using prepared statements that could prevent insertion attacks?
The safest (and easiest) way would be to use a parameterised query (this isn't available on the CRAN release, but is in the dev version)
dbGetQuery(myconnection, "SELECT * FROM users WHERE username = ?", list(user))

Insert SQL code into database in PHP/MySQL

I'm trying to write sql to insert a SQL code into one of the table's columns.
The table has these three columns: email, verification code, sql.
I try this code, and variations of it, playing around with the quotes and backslashing/escaping them, etc... but something's still wrong:
INSERT INTO pre_registration(email, verification_code, sql) VALUES('myemail#gmail.com', '8efb100a295c0c690931222ff4467bb8', '"INSERT INTO customer(title) VALUES(\'Mr.\')"')
It tells me there's an error in the SQL syntax:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sql) VALUES('myemail#gmail.com', '89f0fd5c927d466d6ec9a21b9ac34ffa', "INSER' at line 1
How to do it? I'm using PHP/MySQL.
MySQL considers sql as a keyword. You have to quote it:
INSERT INTO pre_registration(email, verification_code, `sql`) VALUES('myemail#gmail.com', '8efb100a295c0c690931222ff4467bb8', '"INSERT INTO customer(title) VALUES(\'Mr.\')"')
By the way double the quotes to escape them instead of using bakslashes. This is more SQL friendly.
INSERT INTO pre_registration(email, verification_code, `sql`) VALUES('myemail#gmail.com', '8efb100a295c0c690931222ff4467bb8', '"INSERT INTO customer(title) VALUES(''Mr.'')"')
Some insight into the exact SQL error would help. At first glance I'd say you need to apply spaces between the table name and the open parentheses and between values and the open parentheses.
Also, the Single quotes around the double quotes for the SQL portion may be creating an error though I am not certain. Whatever is between the single quotes is interpreted literally which should make the escape characters actually be slashes inside the stored data.
Also, sql is a reserved word that must be quoted for use.
Finally, depending on your situation there may be a more secure method of data entry using prepare and bound parameters:
try
{
$conn = new PDO ( "sqlsrv:server = $serverstringname; Database = $logindatabase", "$loginusername", "$loginpassword");
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch ( PDOException $e )
{
print( "Error connecting to SQL Server." );
die(print_r($e));
}
$email = 'myemail#gmail.com' //or some other way of setting the variable like $_POST
$verification_code = '#####' //or $_Post method
$sql = 'Put Query Here' //probably have to declare this explicitly
$sql_insert = "INSERT INTO pre_registration_info (email, verification_code, 'sql') VALUES (?,?,?)";
$stmt = $conn->prepare($sql_insert);
$stmt->bindValue(1, $email);
$stmt->bindValue(2, $verification_code);
$stmt->bindValue(3, $sql);
$stmt->execute();