I'm thinking the problem here is with my SQL Syntax, but I'm not sure and need a fresh pair of eyes to check it out. This is the code I'm using to connect to and then insert into the DB:
OdbcConnection datConn = CreateDataConn();
datConn.Open();
OdbcCommand comm = new OdbcCommand();
comm.CommandText = "INSERT INTO userdata (key, secretkey, uid) VALUES ('" + token + "', '" + secret + "', '" + twitterid + "');";
comm.Connection = datConn;
comm.ExecuteNonQuery();
datConn.Close();
And here is the CreatDataConn() method:
private OdbcConnection CreateDataConn()
{
OdbcConnection dbConn = new OdbcConnection();
dbConn.ConnectionString = "Dsn=MySQL;database=twittertest;option=0;port=0;server=localhost;uid=root;pass=Red!4jedi";
return dbConn;
}
I created a DSN to the database, which is hosted on my machine.
When I run the application I get this error:
ERROR [42000] [MySQL][ODBC 3.51 Driver][mysqld-5.1.51-community]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 'key, secretkey, uid) VALUES ('127090765-i3aZl71LPSVUCPZs9kHSYeBli0vWpbq0BaM1roYC' at line 1
But for the life of me I can't figure out what's wrong with my syntax...It's prolly something simple, but again, I need a pair of fresh eyes to look at this.
key is a probably a reserved word. in MySQL, you can get around this by adding backticks (`) around a column name (so '`key`'instead of 'key'), but you should try not to have reserved words as entity names.
Related
I'm getting this error when I'm trying to update a record:
ERROR [HY000] [Microsoft][ODBC Microsoft Access Driver]
Operation must use an updateable query
However when I add a new record, it would add just fine.
I did some searching and found out that the problem is because The ASP.NET worker process does not have permission to update the database. But how am I being able to insert a new record (Isn't inserting updating the database!) but not update (set a record to a different value).
OdbcConnection DbConnection = new OdbcConnection("DSN=inv");
DbConnection.Open();
try
{
string newPassword = password1.Text;
OdbcCommand DbCommand = new OdbcCommand("UPDATE Users" + " SET [Password] = '" + newPassword + "'" + " Where Name = '" + Session["LoginId"] + "'" + ";", DbConnection);
DbCommand.ExecuteNonQuery();
Server.Transfer("Default.aspx", true);
}
You will often get that error if you don't have a primary key declared on that table.
Your code is also pretty ugly, at the very least you should be using a parameterized query:
OdbcCommand DbCommand = new OdbcCommand("UPDATE Users SET [Password] = #Password Where Name = #Name", DbConnection);
var param = DbCommand.Parameters.Add("#Password", OdbcType.Text);
param.Value = passWord;
param = DbCommand.Parameters.Add("#Name", OdbcType.Text);
param.Value = Session["LoginId"];
And I hope this isn't anything more than a toy/demo app -- storing passwords in the clear is bad. Storing passwords in access in the clear is a double bad.
I have the following code snippet.
SqlCommand cmd = new SqlCommand("SELECT FName,LName FROM EMPLOYEE_TABLE WHERE EmployeeID = '" +TextBox1.Text + "' AND Password = '"+ TextBox2.Text +"'", con);
SqlDataReader x = cmd.ExecuteReader();
try
{
if (x.Read())
{
name = (string)x["FName"] +' '+ (string)x["LName"];
Session["NAME"] = name;
Session["ID"] = TextBox1.Text;
Response.Redirect("sample.aspx?action=On_Click");
}
else
{
errormsg.Text = "login failed.Please enter Valid UserID and Password";
errormsg.ForeColor = System.Drawing.Color.Red;
}
}
catch (Exception exp)
{
errormsg.Text = "Sorry,You dont have access to this portal.";
}
finally
{
x.Close();
con.Close();
}
Now, when i use a valid id (that exists) and password as abc' or 'x'='x then it logs in into the first account of the table in the database. Till this it's fine.
However when I try to debug the code, it throws an error Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack..
Also if it is throwing an error then why is it logging into this 1st account of the database. Note: the first account of the database has a different userid than that which i m providing.
Note: I am the developed of this application. So I'm not doing anything illegal. :)
Look at this part of your SQL:
"' AND Password = '"+ TextBox2.Text +"'"
With your password, it's
"' AND Password = ''x'='x'"
which is not the SQL you want.
Even if you are trying to do SQL injection, you have to result in valid SQL. Usually, it's by ending the statement with a semi-colon after closing the quote. See this:
http://xkcd.com/327/
OK, to provide an answer based on the primary issue you've got (as you've stated, you're new to the SQL Injection issue).
SQL Injection is caused by dynamically building a SQL query using user input as part of the construction. The simplest solution to this in .Net is to create a parameterized query.
I think Jeff Atwood has the most complete yet concise article providing an explanation and complete example here
Quoted from above link:
SqlConnection conn = new SqlConnection(_connectionString);
conn.Open();
string s = "SELECT email, passwd, login_id, full_name " +
"FROM members WHERE email = #email";
SqlCommand cmd = new SqlCommand(s);
cmd.Parameters.Add("#email", email);
SqlDataReader reader = cmd.ExecuteReader();
The issue at hand:
The reason it's still logging into the account is because the query is still "valid".
The statement will still be executed, and the relevant record will still be returned from the database, no exception will be thrown.
The only way you will stop the login process when invalid data is provided is to validate the input before executing the query. You should always validate user input before sending it off to the database. If the user were to provide:
username'; drop table users;--
as the username, you would be in a LOT of trouble.
The error you're encountering is a debugging error, not an actual program exception. That's why it works when you run it normally.
To remedy the error, I'd first make sure that everything is running with a Debug build. Also, make sure you're currently debugging in the function of the variable you want to inspect. Try stepping (F10) a few times past your breakpoint to refresh the context. There are a slew of other suggestions on the internet for that particular error, so if you're still having problems you might have to do some googling.
i have a code that retrieve some content and enter it the database :
MySqlConnection conn = new MySqlConnection(#"connection string");
MySqlCommand cmd = new MySqlCommand("INSERT INTO copy (id) VALUES ('" + Page.User.Identity.Name + "')", conn);
MySqlCommand cmd2 = new MySqlCommand("INSERT INTO copy (cv) VALUES ('" + mainEditor.Content.Replace("'", "''") + "')",conn);
conn.Open();
cmd.ExecuteNonQuery();
cmd2.ExecuteNonQuery();
conn.Close();
it connects and enters the data fine but it enters the data in two not one (it creates two rows instead of one)
i am using asp.net 3.5 and mysql 5.0
what am i doing wrong, thanks.
It's inserting two rows because you're executing two INSERT statements. Each time you run an INSERT it does just that: inserts a row.
I'm guessing you wanted to create a single row with both the id and cv fields populated. The SQL syntax for that is INSERT INTO copy (id, cv) VALUES ('x', 'y');
So:
MySqlCommand cmd = new MySqlCommand("INSERT INTO copy (id) VALUES ('" + Page.User.Identity.Name + "', '" + mainEditor.Content.Replace("'", "''") + "')",conn);
It's because two separate inserts are running. You can insert more than one value, try this:
MySqlCommand cmd = new MySqlCommand("INSERT INTO copy (id, cv) VALUES ('" + Page.User.Identity.Name + "', '" + mainEditor.Content.Replace("'", "''") + "')", conn);
You can comma separate the fields, and the values so it inserts into one record. Executing 2 insert commands will always create 2 records.
You didn't say which driver you're using so I'll use the documentation I found for dotConnect. I would try to use something along these lines (explanation of code below)
using( var conn = new MySqlConnection(#"connection string"))
using( cmd = new MySqlCommand("", conn) ){
cmd.CommandText = #"
INSERT INTO copy (id, cv)
VALUES (:name, :userContent)";
cmd.Parameters.Add("name", MySqlType.[correct type]]).Value = Page.User.Identity.Name;
cmd.Parameters.Add("userContent", MySqlType.[correct type], [column size]).Value = mainEditor.Content;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
The use of the using construct is because MySqlConnection and MySqlCommand classes both implement the IDisposable interface so they need to be disposed of when you're done using them to avoid possible resource leaks.
The :name and :userContent is what I found in documentation for creating parametrized queries. This will allow the database driver to take care of escaping all of the special characters out of user input to avoid SQL injection attacks. This part is actually really important, there are some REALLY sophisticated SQL injection attacks out there, so there's a good chance simply escaping ' (as you were doing) isn't enough.
I am new to asp.net development and using enterprise library in my application in the following way.
Database db = DatabaseFactory.CreateDatabase();
DbCommand cmd = db.GetStoredProcCommand("sp_MakePayment");
db.AddInParameter(cmd, "#BillGenID", System.Data.DbType.Int32);
db.SetParameterValue(cmd, "#BillGenID", billgenID);
db.AddInParameter(cmd, "#PayDate", System.Data.DbType.String, 50);
db.SetParameterValue(cmd, "#PayDate", mypaydate.Text);
db.AddInParameter(cmd, "#TransNo", System.Data.DbType.String, 50);
db.SetParameterValue(cmd, "#TransNo", transno.Text);
db.AddInParameter(cmd, "#AmtToPay", System.Data.DbType.Double);
db.SetParameterValue(cmd, "#AmtToPay", Convert.ToDouble(paidamount.Text));
////Execute Stored Procedure
int i = 0;
i = db.ExecuteNonQuery(cmd);
Now I am in a situation where i need to run this inlnie query using the same method to get the count of records and read in a variable. for example following query to find existing bill.
string bill_id = "1234";
string dofpayment = "11/03/2011";
mysql = "Select count(*) from payments where bill_id = " + bill_id + " and payment_date = " + dofpayment ;
Now how to incorporate the above lines using the enterprise library block.
thanks
If you enterprise library supports text commands alongside with stored procedures, then you should write a code which creates a text command and then passes your bill_id and dofpayment as parameters to it.
Otherwise, you need to create a stored procedure with these two parameters and then call that in similar way shown in your code example for stored procedure.
I hope this helps!
string sSql = "SELECT CustomerID, CompanyName, City, Country" + " FROM Customers WHERE Country = #sCountry"; Database db = DatabaseFactory.CreateDatabase(); DBCommandWrapper cmd = db.GetSqlStringCommandWrapper(sSql); cmd.AddInParameter("#sCountry", DbType.String, sCountry); DataSet ds = new DataSet(); db.LoadDataSet(cmd, ds, "Customers");
please read the msdn reference
Thank you for your response.
I am using Powerbasic (www.powerbasic.com) as my compiler and SQLTools as a third party tool to access ADS through ODBC.
I must stat that this error also appers when I take other actions like Update, Delete, Find, etc. But I don't
get this error when I am using MS Access.
Here is my save routine:
Local sUsername As String
Local sPassword As String
Local sStatus As String
Local sSQLStatement1 As String
sUsername = VD_GetText (nCbHndl, %ID_FRMUPDATEUSERS_TXTUSERNAME)
If Trim$(sUsername) = "" Then
MsgBox "Please, enter Username", %MB_ICONINFORMATION Or %MB_TASKMODAL, VD_App.Title
Control Set Focus nCbHndl, %ID_FRMUPDATEUSERS_TXTUSERNAME
Exit Function
End If
sPassword = VD_GetText (nCbHndl, %ID_FRMUPDATEUSERS_TXTPASSWORD)
If Trim$(sPassword) = "" Then
MsgBox "Please, enter Password", %MB_ICONINFORMATION Or %MB_TASKMODAL, VD_App.Title
Control Set Focus nCbHndl, %ID_FRMUPDATEUSERS_TXTPASSWORD
Exit Function
End If
sStatus = VD_GetText (nCbHndl, %ID_FRMUPDATEUSERS_CBOSTATUS)
sSQLStatement1 = "INSERT INTO [tblUsers] (Username, Password, Status) " + _
"VALUES ('" + sUsername + "','" + sPassword + "','" + sStatus +"')"
'Submit the SQL Statement to the database
SQL_Stmt %SQL_STMT_IMMEDIATE, sSQLStatement1
'Check for errors
If SQL_ErrorPending Then
SQL_MsgBox SQL_ErrorQuickAll, %MSGBOX_OK
End If
Best regards,
I am not familiar with Powerbasic and have had trouble attempting to find a trial version. However, I have been thinking about this. You noted that the issue occurs with update and delete as well as this insert statement. This leads me to believe that perhaps an attribute is being set to indicate the statement should return a cursor when it does not. However this is more of a wild guess.
Does an ODBC trace shed any light as to the options that were changed?