Why this simple query breaks? [closed] - asp.net

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a asp.net application, which save some users data using post form. For that I have a simple query listed below.
"UPDATE myTable SET LastUpdatedOn='"
+ DateTime.UtcNow + "', Completed='1'
WHERE ID='" + requestid + "'"
This fails some times. But I think there are no issue with it. So please let me know why it happens.

You should familiarize yourself with parameterized queries, and start using them to protect your system from SQL Injection attacks.
using (var cmd = conn.CreateCommand()) {
cmd.CommandText =
"UPDATE myTable SET LastUpdatedOn=#Time, Completed='1' WHERE ID=#Id";
cmd.Parameters.AddWithValue("#Time", DateTime.UtcNow);
cmd.Parameters.AddWithValue("#Id", requestid);
var count = cmd.ExecuteNonQuery();
if (count != 1) {
Console.Error.WriteLine(
"Warning: Cannot update myTable for ID {0}", requestid
);
}
}
As an added benefit, this approach eliminates all possible data formatting issues, and speeds up your queries by letting SQL Server cache query plans. But the main benefit is thwarting the attempts of "Bobby Tables" of the world to gain unauthorized access to your system.

DateTime.UtcNow is not likely parseable to a datetime for the query. Try:
DateTime.UtcNow.ToString('yyyy-MM-dd hh:mm:ss')
(also, I may have screwed up my "m's", so double check it)

I'm not exactly sure why this would break. We would need to see the schema of the table to get a better idea of what could be going wrong. On another note, I would suggest that you use parameterized queries instead of simply concatenating your query. Your current query could be vulnerable to SQL injection depending on where the inputs come from. Try changing your code to something like this to see if it alleviates the error (this will also mitigate the SQL injection risk):
SqlCommand cmd = new SqlCommand("UPDATE myTable SET LastUpdatedOn = #LastUpdatedOn, Completed = #Completed WHERE ID = #RequestId", sqlConnectionObject);
cmd.Parameters.AddWithValue("#LastUpdatedOn", DateTime.UtcNow);
cmd.Parameters.AddWithValue("#Completed", 1);
cmd.Parameters.AddWithValue("#RequestId", requestid);
cmd.ExecuteNonQuery();

insted of using DateTime.UtcNow consider to use getdate() if Sql Sevrer or simmilar function in whatever database you are using
"UPDATE myTable SET LastUpdatedOn= getdate(), Completed='1' WHERE ID='" + requestid + "'"

Related

how to add wild card?

Hi i am new programmer asp.net and vb.net. I wanted using wild card to search engine.
i am puzzled put wild card (%).
Protected Sub search()
Dim ds As New DataSet
Dim cls As New Class1
ds = cls.returndataset("select * from student where Nama_Depan like '" & nama.Text & "' ")
viewatt.DataSource = ds
viewatt.DataBind()
End Sub
Thanks in advance for any help, and I'm really sorry if this has been asked before.
As others have already pointed out
select * from student where Nama_Depan like '%" & nama.Text & "%'
is the correct way to use wildcards
Here is a link to the W3Schools tutorial on SQL wildcards: http://www.w3schools.com/sql/sql_wildcards.asp
I would suggest you have a quick read through, the W3schools articles are usually really good.
This however is a really bad way to execute SQL commands from your code, someone could quite easily inject some SQL code into your textbox and when your query is executed it could destroy your database.
As an exaple if someone entered '; DROP TABLE * -- into your textbox, this would allow your first query to run, then it would drop all your tables.
It is really easy to get around this by using parameterised queries or stored procedures. Personally I would favour using Stored Procedured and you can do so like this.
CREATE PROCEDURE MyProc
(
#param1 VARCHAR(50)
)
AS
BEGIN
select * from student where Nama_Depan like '%"'+#param1+'%'
END
You would then just need to edit your VB code to call the stored procedure rather than executing the SQL command.
The other advantage of using a stored procedure is that they perform slightly faster and are more efficient, this is because when you pass some SQL to the database it has to compile it into a sql command to execute, stored procedures are already stored on the database and so do not need to do this.
There are also some added security benefits to using a stored procedure rather than just transmitting a SQL statement, If anyone were to intercept your SQL statement on its way across the network / internet they could gain some insight into your database structure. With a stored procedure all they could possibly intercept is the procedure name and some parameters.
Try this.
Protected Sub search()
Dim ds As New DataSet
Dim cls As New Class1
ds = cls.returndataset("select * from student where Nama_Depan like '%" & nama.Text & "%' ")
viewatt.DataSource = ds
viewatt.DataBind()
End Sub

How can I make a prepared statement in classic asp that prevents sql injection?

I have this which works:
sqlString = "SELECT * FROM employees WHERE lastname = '" & last_name & "'"
Set cmd = Server.CreateObject("ADODB.Command")
Set cmd.ActiveConnection = dbConn
cmd.CommandText = sqlString
cmd.Prepared = True
Set recs = cmd.Execute
The problem I have is that above the dynamic part of sqlString is before the prepared statement command. I don't think what I have above is protecting me.
Don't I have to fix this sqlString before I do the prepared statement? Reading this made me think that: How can prepared statements protect from SQL injection attacks?:
"While in case of prepared statements we don't alter our program, it remains intact
That's the point.
We are sending program to the server first
$db->prepare("SELECT * FROM users where id=?");
where the data is substituted by some variable called "placeholder"
and then we're sending the data separately:
$db->execute($data);
so, it can't alter our program and do any harm.
Quite simple - isn't it?"
But I don't know how to make my query correct. I also don't know how he got from prepare to $data. Was hoping for guidance. Thanks.
Why not use ADO command parameters?
var oCmd = Server.CreateObject("ADODB.Command");
oCmd.CommandText = "SELECT * FROM employees WHERE lastname = ?";
oCmd.Parameters.Append(oCmd.CreateParameter(undefined,202, 1, 50,"last name"))//adVarWChar
Here's a good blog on how to prevent sql injection using classic asp.
http://blogs.iis.net/nazim/archive/2008/04/28/filtering-sql-injection-from-classic-asp.aspx
The easiest is using stored procedures in SQL and using Commands that way.. Otherwise, you have to escape out certain characters being gathered from the Request object, like single quotes and double hyphens, etc.

Making then displaying in a table a new SQL row using ASP

How can I, using asp.net and HTML, use a form to create a new table row in an SQL Table?
Would I use javascript to retrieve the HTML? Should I directly submit SQL or should I create a stored procedure? Essentially, I want to know how to get the data from a form to my SQL.
Take a look at the example provided in the documentation for the SqlCommand class.
In here they provide a basic example for connecting to a database, executing a query and processing the results. Here is a slightly modified version for doing an insert:
string queryString =
"INSERT INTO MyTable (Column1) Values ('test');";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
command.ExecuteNonQuery();
}
Make sure that you use a Parameterized Query when you use insert values from your web page into your database or you will be vulnerable to SQL Injection attacks.
There are several other methods for doing this such as LINQ-to-SQL, but feel this is the most straight forward for beginners.
Check out this for adding data: http://www.w3schools.com/ado/ado_add.asp
And check out this for updating data: http://www.w3schools.com/ado/ado_update.asp
You should use stored procedures to prevent security risks.
I strongly suggest you read:
ASP.NET Data Access to understand the basics, and then part 2 of step by step mySQL data access using ASP.NET

How to check a SQL database table to see if a record exists

I have a SQL database that creates a record for every document uploaded by the user to the server. I want to check this table before a user uploads a document to ensure they don't upload a file with name that already exists.
I know how to make the connection and make the SqlCommand to query the table for an existing record. But I don't know how to check the record count from the sqlCommand I made.
Does that make sense?
Using myConnectionCheck As New SqlConnection(myConnectionStringCheck)
Dim myCommandCheck As New SqlCommand()
myCommandCheck.Connection = myConnectionCheck
myCommandCheck.CommandText = "SELECT * FROM Req_Docs WHERE Doc_Name =" & DocName
myConnectionCheck.Open()
myCommandCheck.ExecuteNonQuery()
End Using
Thanks in advance,
Anthony
use if exists for this issue
create procedure isDocExists
#DocName varchar(255),
#isExists bit output
as
set #isExists = 0
if exists (SELECT Doc_Name FROM Req_Docs WHERE Doc_Name =#DocName)
begin
set #isExists=1
end
to check where record is there or not
So many things wrong here:
Race condition between when you check and when you upload
Multiple Documents should legitimately be allowed to have the same name. Use tags, folders, timestamps, or other means to distinguish them.
Sql Injection vulnerability on the name parameter
ExecuteNonQuery() on a SELECT query.
I'll give you the benefit of the doubt on the first two points that you're still gonna allow the upload, and this is just so you can ask the user how they want to relate the documents. Given that, here's how you fix the other two:
Using cn As New SqlConnection(myConnectionStringCheck), _
cmd As New SqlCommand("SELECT COUNT(*) FROM (SELECT TOP 1 1 FROM Req_Docs WHERE Doc_Name= #DocName) t", cn)
cmd.Parameters.Add("#DocName", SqlDbTypes.VarChar, 255).Value = DocName
cn.Open()
Return CInt(cmd.ExecuteScalar())
End Using
ExecuteNonQuery is a function, that returns an integer equal to the number of rows affected by the query.
However, it's usually used for updates.
You might consider ExecuteScalar, which returns the first column of the first row in the result set.
So if you change the query to select count(*) from..., the result of ExecuteScalar will be the number of rows, which you can then test.
if you want count:
SELECT COUNT(*) as count FROM Req_Docs WHERE Doc_Name = 'DocName'

Integer variable is acquiring a string value of "ad" somewhere along the line, can anyone see where?

Here is my code:
I should get output of the department id (did) as an integer and the templatefilename (result) that is required.
The errors I get are: Conversion from string "ad" to type 'Integer' is not valid. I'm fairly new to asp.net and cannot see where the did variable picks up the "ad" string.
Any help would be greatly appreciated.
Thanks
When you construct the query to the table departmentsgroupings, you're changing the value of sql, but you aren't creating a new SqlCommand. This means that cmd still contains the old SQL statement (the query to the Modules table) which, when executed, returns "ad".
To fix this, change your code as follows:
sql = ("select departmentsid from departmentsgroupings where groupingid =" & pageid & "")
Set cmd = New SqlCommand(sql, conn)
did = (cmd.ExecuteScalar)
You may have expected the change you made to sql to get passed on automatically to the SqlCommand -- but it doesn't work that way.
Edit: Your code, as written, is vulnerable to SQL injection attacks. If you don't know what these are, you need to read the first answer to this:
How does the SQL injection from the "Bobby Tables" XKCD comic work?
To protect yourself against these kinds of attacks, use parameterized queries.
The mistake is in these lines:
sql = ("select departmentsid from departmentsgroupings where groupingid =" & pageid & "")
did = (cmd.ExecuteScalar) <---- Wrong command executed here.
You presumably meant to execute the code in sql, not cmd again.

Resources