I know that I am not storing my passwords in hash but for the purposes of this database, that doesn't matter.
The code references an SQL database that stores the passwords as plain text
Here's the code:
/*Checks to see if the username and password matcch the database
If it does, it lets you in, if not you displays an error message*/
string user = textBox1.Text.ToString();
string pass = textBox2.Text;
MySqlConnection conn = new MySqlConnection(ConnectionString);
MySqlDataAdapter sda = new MySqlDataAdapter("SELECT COUNT(*) from Employees WHERE UserName = '"+(user)+ "' and Password = '"+(pass)+"' collate Latin1_Genral_CS_AS", conn);
DataTable dt = new DataTable();
sda.Fill(dt);
if(dt.Rows[0][0].ToString() == "1")
{
HomeScreen home = new HomeScreen();
this.Hide();
home.ShowDialog();
}
else
{
MessageBox.Show("Incorrect Username or Password", "alter", MessageBoxButtons.OK, MessageBoxIcon.Error );
}
You can convert both the input values and table columns to lowercase or uppercase:
/*Checks to see if the username and password matcch the database
If it does, it lets you in, if not you displays an error message*/
string user = textBox1.Text.ToLower();
string pass = textBox2.Text.ToLower();
MySqlConnection conn = new MySqlConnection(ConnectionString);
MySqlDataAdapter sda = new MySqlDataAdapter("SELECT COUNT(*) from Employees WHERE LOWER(UserName) = '"+(user)+ "' and LOWER(Password) = '"+(pass)+"' collate Latin1_Genral_CS_AS", conn);
DataTable dt = new DataTable();
sda.Fill(dt);
if(dt.Rows[0][0].ToString() == "1")
{
HomeScreen home = new HomeScreen();
this.Hide();
home.ShowDialog();
}
else
{
MessageBox.Show("Incorrect Username or Password", "alter", MessageBoxButtons.OK, MessageBoxIcon.Error );
}
You can alter your database to use the collation you wish:
ALTER DATABASE DBNAME CHARACTER SET utf8 COLLATE utf8_general_ci;
However, this will only apply on new tables. You can alter a table column to use the collation of your preference:
ALTER TABLE table_name MODIFY column_name column_datatype COLLATE utf8_bin;
Related
I have the following code that is comparing a hash value and username to the corresponding hash value and username in a local database (App_Users3)
//-
SqlConnection con = new SqlConnection();
con.ConnectionString = ("Data Source=DESKTOP-PGHMM6M;Initial Catalog=LocalUsers;Integrated Security=True");
con.Open();
var cmd = new SqlCommand(#"SELECT Username, Hash FROM App_Users3 WHERE Hash = #Hash AND Username = #Username");
cmd.Connection = con;
// savedPasswordHash = cmd.ExecuteScalar() as string;
cmd.Parameters.Add("#Hash", SqlDbType.NVarChar, 50).Value = savedPasswordHash;
cmd.Parameters.Add("#Username", SqlDbType.NVarChar, 400).Value = AppUsername;
if (cmd.ExecuteNonQuery() > 0)
{
MessageBox.Show(" Query successful.. something matched.. ");
// change page.. load a profile?
}
It doesn't throw any errors but I don't understand why the messagebox isn't showing up.
ExecuteNonQuery returns the rows affected by modifying data statements (insert, update, delete). You should use ExecuteScalar for such select statements, and for example return the user's ID value. If you want to return more than one value (either multiple rows or multiple columns), you should use ExecuteReader.
Here is your code modified to return UserID of the matched user.
//-
SqlConnection con = new SqlConnection();
con.ConnectionString = ("Data Source=DESKTOP-PGHMM6M;Initial Catalog=LocalUsers;Integrated Security=True");
con.Open();
var cmd = new SqlCommand(#"SELECT UserId FROM App_Users3 WHERE Hash = #Hash AND Username = #Username");
cmd.Connection = con;
//savedPasswordHash = cmd.ExecuteScalar() as string;
cmd.Parameters.Add("#Hash", SqlDbType.NVarChar, 50).Value= savedPasswordHash;
cmd.Parameters.Add("#Username", SqlDbType.NVarChar, 400).Value = AppUsername;
if (cmd.ExecuteScalar() != null) {
MessageBox.Show(" Query successful..something matched.. ");
//change page.. load a profile?
}
}
I try am trying to build a function that populates a table when given the name of the table and what parameter to order it by.
I think I am just making a syntax error in my SQL command but I can't find it. Please help.
public DataTable populateTable(string tableName, string orderByParameter)
{
DataTable table = new DataTable();
string connString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
string cmdString = "SELECT * FROM (value = #tbl) ORDER BY (parameter = #obp) DESC";
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = cmdString;
cmd.Parameters.AddWithValue("#tbl", tableName);
cmd.Parameters.AddWithValue("#obp", orderByParameter);
using (SqlDataAdapter ad = new SqlDataAdapter(cmd))
{
ad.Fill(table);
}
}
try
{
GridView1.DataSource = table;
GridView1.DataBind();
return table;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return null;
}
}
}
You can't have variables in table name or in 'order by' clause.
You could build the query dynamically as:
string cmdString = "SELECT * FROM [" + tableName + "] ORDER BY " + orderByParameter +" DESC";
With this you won't need to add the parameters #tbl and #obp to the command.
Note that this runs into SQL injection related vulnerabilities. So you shouldn't do this unless you are absolutely certain that the table with given name exists, and the orderByParameter is a valid expression.
i am trying the below query but i am getting error like incorrect syntax at SqlDataReader reader = command.ExecuteReader .. please correct me where i am wrong
string querystring = "SELECT ImageName FROM dbo.ProfilePic WHERE UserName = #UserName & IsActive = 'Y' order by ID Desc";
SqlCommand command = new SqlCommand(querystring, con);
command.Parameters.AddWithValue("#UserName", Session["UserName"].ToString());
con.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(String.Format("{0}",
reader[0]));
ViewBag.ProfilePic = reader[0];
}
reader.Close();
updated with all suggested answers
SQL doesn't need the double equal signs.
SELECT ImageName FROM dbo.ProfilePic WHERE Username = #UserName
in SQL you don't need to use double equal sign to compare values and && is wrong, then this is wrong:
string querystring = "select ImageName from dbo.ProfilePic where UserName == #UserName && IsActive == 'Y' order by ID descending";
and this is true:
string querystring = "select ImageName from dbo.ProfilePic where UserName = #UserName AND IsActive = 'Y' order by ID desc";
string querystring = "select ImageName from dbo.ProfilePic where UserName =
#UserName AND IsActive = 'Y' order by ID DESC";
// on sql compare oprator not need to '==' sign
SqlCommand command = new SqlCommand(querystring, con);
command.Parameters.AddWithValue("#UserName", Session["UserName"].ToString());
con.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(String.Format("{0}",
reader[0]));
// when you assign reader value to any object you must assign while DataReader read not after DataReader close
ViewBag.ProfilePic = reader[0];
}
reader.Close();
EDIT
try
string querystring = "select ImageName from dbo.ProfilePic where UserName like '#UserName' AND IsActive = 'Y' order by ID DESC";
I am using the following SQL code in my VB in VS2013. I want to create a login form using a database of users stored into a UserList. However The query is not case sensitive. How do I change my query string to use COLLATE or any other case sensitive comparison
Dim Check As String = _
"SELECT COUNT(*) AS Expr1 FROM UserList HAVING (Username = '" & _
_UsernameTextBox.Text & "') AND ([Password]= '" & _PasswordTextBox.Text & _
"') AND (UserType = '" & User.ToString & "')"
With search
.CommandText = Check
.Connection = cn
If .ExecuteScalar() = 1 Then
Me.Hide()
If User = "Trader" Then
Trader.Show()
ElseIf User = "Broker" Then
Broker.Show()
ElseIf User = "Corporate" Then
Corporate.Show()
ElseIf User = "System" Then
SystemManager.Show()
End If
Else : MsgBox("IncorrectInput")
End If`
"SELECT COUNT(*) AS Expr1 FROM UserList
HAVING (Username = #username)
AND ([Password] COLLATE Latin1_General_CS_AS = #password)
AND (UserType = #usertype)
"
Apart from the fact that you don't have your password stored and compared with a slow salted cryptographic hash function (=non-reversible encryption), your query is also vulnerable to SQL-injection (when I use a username like "Jean le Rond d'Alambert" or just "d'Alambert".
Another bug is that when you save the password as plain text, say e.g. (n)varchar(32), I can enter a password that is longer than that (e.g. a sentence) ==> bug
Given you're writing a financial application ("broker", "corporate"), SQL-injection is an intolerable security risk.
You can for example MD5-hash your password (cheap & dirty):
master.dbo.fn_varbintohexstr(HashBytes('MD5', 'test'))
You have a "System.Data.SqlClient.SqlCommand",
there you can add a System.Data.SqlClient.SqlCommand
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
//
// Description of SQL command:
// 1. It selects all cells from rows matching the name.
// 2. It uses LIKE operator because Name is a Text field.
// 3. #Name must be added as a new SqlParameter.
//
using (SqlCommand command = new SqlCommand(
"SELECT * FROM Dogs1 WHERE Name LIKE #Name", connection))
{
//
// Add new SqlParameter to the command.
//
command.Parameters.Add(new SqlParameter("Name", dogName));
//
// Read in the SELECT results.
//
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
int weight = reader.GetInt32(0);
string name = reader.GetString(1);
string breed = reader.GetString(2);
Console.WriteLine("Weight = {0}, Name = {1}, Breed = {2}",
weight,
name,
breed);
}
}
}
If you do it right from the start, then you don't have to change anything later.
I am using VB.net and Sql server 2005.
I have GridView in Application where I have my CPUserID. There can be thousands records in GridView with different CPUserIDs.
Now I have a button "Allocate Token". But before allocating the token I want to check in my Token Table that if that CPUserID has already exists in table it should not allow user to allocate token and will return some message for that user.
For Each curRow As GridViewRow In GridView1.Rows
Dim cpuserid As Label = CType(curRow.Cells(1).FindControl("lblCPUserID"), Label)
Next
The TOKEN table structure is given below:
TokenID, CPUserID, StatusID (All Integer)
Please Suggest! with some example code
Perform a query on the Token table to see if there already exists a row in that table for the given id:
SELECT COUNT(*) FROM Token WHERE CPUserID = 5
for instance.
In order to do that in VB.NET, you'll have to use the SqlConnection and SqlCommand classes.
Also, be sure to make use of parameterized queries.
In C#, the code would look more or less like this:
SqlConnection conn = new SqlConnection ("here comes the connectionstring to the db.");
conn.Open();
try
{
SqlCommand cmd = new SqlCommand ();
cmd.Connection = conn;
cmd.CommandText = "SELECT COUNT(*) FROM Token WHERE CPUserId = :p_UserId";
cmd.Parameters.Add ("p_UserId", SqlDbType.Int32).Value = 5;
object result = cmd.ExecuteScalar();
if( Convert.ToInt32(result) > 0 )
{
MessageBox.Show ("Token already exists for user");
}
}
finally
{
conn.Close();
}
In order to improve performance, you will have to make sure that you create the correct indexes on the Token table.
An index on CPUserId would maybe help for this query.
First of all thanks to all of them who responded for this question.
I solved above issues with below solutions:
SQL Procedure:
I created one procedure in SQL server 2005
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[uspUpdateAllocateToken]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[uspUpdateAllocateToken]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[uspUpdateAllocateToken]
( #CPUserID INT)
AS
IF NOT EXISTS(SELECT TokenID FROM tblToken WHERE CPUserId=#CPUserID AND StatusID IN (41,47))
BEGIN
UPDATE tblToken
SET
CPUserID = #CPUserID,
StatusID=47
WHERE
tblToken.TOKENID = (SELECT TOP 1 TOKENID FROM TBLTOKEN WHERE CPUSERID IS NULL AND STATUSID = 40)
END
Further in my application on my Button Click. I write below code:
Protected Sub ibtnAllocateTokens_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ibtnAllocateTokens.Click
Try
Dim conString As String = WebConfigurationManager.ConnectionStrings("LocalSqlServer").ConnectionString
Dim con As New SqlConnection(conString)
con.Open()
Dim cmd As SqlCommand
For Each gvRow As GridViewRow In GridView1.Rows
cmd = New SqlCommand("uspUpdateAllocateToken", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#CPUserID", SqlDbType.Int).Value = CType(gvRow.Cells(1).FindControl("lblCPUserID"), Label).Text
cmd.ExecuteScalar()
lblAllocateTokenMessage.Visible = True
Next
Catch ex As Exception
ErrorHandler.WriteError(ex.Message)
End Try
End Sub
Please have a look and let me know if there seems any problem in this implementation.
Cheers!