I wanted to create a new database using the MySql.Data.MySqlClient with prepared statements. Unfortunately it shows me an error message "You have an error with your SQL syntax". Using "test" for the iv_name import value of the method.
When executing "CREATE DATABASE IF NOT EXISTS test;" directly in mysql server console, it works without any problems. When adding "'" to left and right of the #dbname a database will be created called #dbname in my mysql server.
public void CreateDatabase(string iv_name)
{
MySqlCommand lo_cmd = new MySqlCommand("CREATE DATABASE IF NOT EXISTS #dbname;", this._conn);
lo_cmd.Prepare();
lo_cmd.Parameters.AddWithValue("#dbname", iv_name);
lo_cmd.ExecuteNonQuery();
}
Here you can find a screen shot from the debuggin process
You cannot use parameters in data definition SQL statements like CREATE TABLE. Use string concatenation to create statements like that.
Be very careful with user-provided table names. Avoid punctuation and avoid reserved words like ‘select‘ and ‘table'. Your best bet is to reject any user input containing punctuation other than _, and to prefix user input with something like t_. So you reject table;droptable and turn mytable into t_mytable.
Related
In Microsoft documentation here: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/reserved-keywords-transact-sql?view=sql-server-2017, it documents the current Reserved Keywords.
My question is that, when I use one keyword "semanticsimilaritydetailstable" to create a table:
CREATE TABLE semanticsimilaritydetailstable (
column_name_1 int,
column_name_2 nvarchar,
);
Firstly, I execute the above code in sql server directly, there will be a SqlException: "Incorrect syntax near the keyword 'semanticsimilaritydetailstable'". It means I should add "[ ]"for table name, because I'm trying to use the sql keyword to build the table.
And then, I exceute the sql through EF core, like:
string sql = "CREATE TABLE semanticsimilaritydetailstable (
column_name_1 int,
column_name_2 nvarchar,
)";
xxDbContext.Database.ExecuteSqlRaw(sql);
The table named "semanticsimilaritydetailstable" will be created successfully. So, Why does this happen in EF croe ?(same in EF and ADO.NET)
It should be notice that, if the table is named for another reserved keyword, like WHERE, AND, COLUMN, creating the table in the above way will both throw the same exception "Incorrect syntax near the keyword 'xxx'";
The below image shows the the actual statement sent to the server when running EF query:
enter image description here
Does this design have any special use? Or maybe it's their potential bug?
Looking forward to your answer.
How to resolve : insert error column name or number of supplied values does not match table definition?
I have attempted to use the same data type used in the SQL database however when I run my program in visual studio C# I couldn't get the desired outcome I want
Try to specify the columns name you want to insert ("insert into yourTable (col1, col2) values (#para1, #para2);")
Also, I have never seem a paraneter being added like that. If the above doesn't work, try using Parameters.AddWithValue().
When dealing with connections, use:
using (var con = /*Connection declaration*/) {
con.Open();
// use connection here
}
This is important because, if you command fail, the connection will not be closed, meaning that soon, you server will be full of dead connections.
I want to learn how SQLInjection is working with the PostgresqlDb. I am using the Npgsql in C#.
So this is my Query, which is called, when I rename a folder:
cmd.CommandText = "UPDATE allfolder.folder SET folder_name = '" + foldernamenew + "'";
cmd.ExecuteNonQuery();
I now tried to pass the following value into the textfield:
abcdef; INSERT INTO allfolder.folder (id, folder_name) VALUES (56,"aaaaaaa");
Then AJAX is fired.
The output I assumed is, that all folders in the table has the folder_name "abcdef" and that I have a new folder with the id "56" called "aaaaaa". This is not the case, because the semicolon is not recognized as delimiter and so the name of each folder_name are "abcdef; INSERT INTO ....". I do not want to change it on DB side that multiqueries are allowed.
So my questions are:
How do I need to prepare the SQL statement, that I achieve a Injection?
Is an injection even possible, when you are not allowed to execute a second qry because the semicolon isn't recognized?
I am only talking about Npgsql and postgres.
As Laurenz mentioned above, this should work:
abcdef'; INSERT INTO allfolder.folder (id, folder_name) VALUES (56,'aaaaaaa'); -- test
Make sure, that you don't mix single and double quotes. A common mistake in SQL. You need the single quote before the semicolon, otherwise it is in the textstring, because you have no delimiter.
“Multiqueries” (several queries in one line, separated by semicolon) are always allowed in PostgreSQL.
Your problem are the multiple errors in your SQL:
Missing single quote after abcdef.
Double quotes instead of single quotes around aaaaaaa.
No single quote or line comment at the end of the statement.
Speaking pointedly: you have to learn SQL before you can learn SQL injection.
I have a problem with inserting into a MSSQL CE database,
locCon.Open();
SqlCeCommand locCmd = locCon.CreateCommand();
locCmd.CommandText = "INSERT INTO user (ID,FName,LName,Email) VALUES('"+this.id+"','"+this.fName+"', '"+this.lName+"','"+this.email+"')";
locCmd.ExecuteNonQuery();
When running this I get
There was an error parsing the query. [Token line number = 1, Token line offset = 13, Token in error = user]
Now i cant see anything wrong with the query although this is the firsr time ive used MS SQL of examples ive seen the syntax for mysql and msssql are identical well for inserts anyway. Is there soemthing obviously wrong with this?
Thanks
I think "user" is a reserved word in the database. Try replacing this:
INSERT INTO user (ID,FName,LName,Email) VALUES (
with this:
INSERT INTO [user] (ID,FName,LName,Email) VALUES (
(I think it' square brackets for MSSQL CE, since it is for other MSSQL engines.)
The square brackets basically tell the query engine, "This is an identifier for an object in the database." They're commonly used to wrap the names of database objects which contain spaces, since those otherwise wouldn't parse correctly. But it's also useful for objects which are reserved words.
You may have to put brackets around the user part like so:
INSERT INTO [user]
this is because user can be a reserved word. putting [] around reserved words in SQL allows them to be used as field and table names.
One other major point is that you are constructing your query from some text inputs. This exposes you to SQL injection attacks. To avoid this I would highly recommend that you use Sql Parameters instead which help to prevent this. See this link:
http://msdn.microsoft.com/en-us/library/ff648339.aspx
I have created a small survey web page on our company Intranet. This web page is not accessible from the outside.
The form is simply a couple of radio buttons and a comments box.
I would like to maintain good coding practices and would like to guard against SQL Injections.
Can SQL injections happen on a insert statement with comments from the textbox?
If so, how can I guard against it using .NET 2.0?
Injection can happen on any SQL statement not run properly.
For example, let's pretend your comment table has two fields, an integer ID and the comment string. So you'd INSERT as follows:
INSERT INTO COMMENTS VALUES(122,'I like this website');
Consider someone entering the following comment:
'); DELETE FROM users; --
If you just put the comment string into the SQL without any processesing this could turn your single INSERT in to the following two statements followed by a comment:
INSERT INTO COMMENTS VALUES(123,''); DELETE FROM users; -- ');
This would delete everything from your users table. And there are people willing to spend all day finding the right tablename to empty using trial and error and various tricks. Here's a description of how you could perform an SQL Injection attack.
You need to use parameterized SQL statements to prevent this.
And this isn't just for security reasons. For example, if you're creating your SQL statements naively the following comment:
I'm just loving this website
would cause an SQL syntax error because of the apostrophe being interpreted by SQL as a closing quote.
Use parameterized queries so that the text is automatically quoted for you.
SqlCommand command = connection.CreateCommand();
command.CommandText = "insert into dbo.Table (val1,val2,txt) values (#val1,#val2,#txt)";
command.AddParameterWithValue( "val1", value1 );
command.AddParameterWithValue( "val2", value2 );
command.AddParameterWithValue( "txt", text );
...
SQL injection can happen any time you pass a query back to the database. Here's a simple demonstration:
SQL Injection Explained
The key, within .NET, is to do as Dave Webb has given. It will prevent the injection attempt by encompassing the entire string as one parameter to be submitted, handling all characters that might be interpreted by SQL Server to change the query or append additional commands.
And it should be pointed out that SQL injection can occur on any application, not just web applications. And that an internal attack is usually the most costly to an organization. One cannot safely assume that an attack won't originate from within.
In addition to using prepared statements and parameters rather than concatenating strings into your SQL you should also do the following:
Validate and format user input on the server side. Client side validation and limits can easily be bypasses with tools like WebScarab, or by spoofing your form.
Configure appropriate permissions for the database user account. Web application should use a separate account or role in your database with permissions restricted to only the tables, views and procedures required to run your application. Make sure that user does not have select rights on the system tables
Hide detailed error messages from users, and use less common names for your objects. It amazes me how often you can determine the server type (oracle, mysql, sqlserver) and find basic schema information in an error message and then get information from tables called 'user(s)', 'employee(s)'. If you haven't set your permissions as in (2) and I can determine your server type you are open to statements like this for SQL Server
SELECT table_name FROM information_schema.table
EXECUTE sp_help foundTableName
Yes, they can happen. The easiest way to guard against this is to use prepared statements rather than building the SQL manually.
So, rather than this:
String sql =
String.Format("INSERT INTO mytable (text_column) VALUES ( '{0}' )",
myTextBox.Text); // Unsafe!
You would do something like this:
String sql = "INSERT INTO mytable (text_column) VALUES ( ? )"; // Much safer
Then add the text of the text box as a parameter to your DbCommand which will cause it to be automatically escaped and replace the "?" in the SQL.
Prevent SQL Injection by using prepared statement. The use of placehoder(?) totally eliminates sql Injection Vulnerability.
example
String sql=Select * from user_table where username='+request.getparameter("username")+';
statement.executeQuery(sql);
the above statement is vulnerable to sql injection.
To make it safe against sql injection.
Use following the snippet
String sql=Select * from user_table where username=?;
statement.setString(1,username);
Yes, it can. Let's say the client sends this:
OR 1 = 1
That can be very painfull for your
SELECT * FROM admin WHERE name = #name AND password = #password
You can prevent this with
using Parameter class from ADO.NET
using regexp
reading, reading: http://www.codeproject.com/KB/database/SqlInjectionAttacks.aspx
The easiest way to guard against that form of SQL injection, is to use parameters and stored procedures rather then building sql statements to run. (In C# or internally to SQL Server).
However I'm not entirely sure you should be spending time on this, unless of course it's your corporate policy, as the chances of it ever occuring internally are minimal at best, and if it did occur, I would hope you would know immediately who it is.