Change Password by connecting to mysql in vb.net - mysql

When I click the button, it doesn't update the data in the database. I have 3 textboxes one is for the Enter Username, second is for enter old password and third is enter new password
Dim con As New MySqlConnection("host=localhost; username=root; password=; database=pawnshop")
Dim cmd As New MySqlCommand
Dim dr As MySqlDataReader
con.Open()
cmd.Connection = con
cmd.CommandText = " select password from login where password ='" & txtChange.Text & "'"
dr = cmd.ExecuteReader
If dr.HasRows Then
cmd.Connection = con
cmd.CommandText = " UPDATE login SET password ='" & txtConfirm.Text & "' where userid = '" & txtUser.Text & "'"
Else
MsgBox("Password is not correct")
End If

PASSWORD is a reserved word for MySql. If you have fields with this name you should remember to always put backticks around that word.
Said that your code needs a rewrite to avoid Sql Injection, parsing problems, resources leaking and also a bit improvement in performances.
Using con = New MySqlConnection(......)
Using cmd = New MySqlCommand()
con.Open()
cmd.Connection = con
cmd.CommandText = "select `password` from login where `password` =#oldp"
cmd.Parameters.Add("#oldp", MySqlDbType.String).Value = txtChange.Text
Dim result = cmd.ExecuteScalar()
if result IsNot Nothing then
cmd.Parameters.Clear()
cmd.CommandText = "UPDATE login SET `password` = #newp where userid = #uid"
cmd.Parameters.Add("#newp", MySqlDbType.String).Value = txtConfirm.Text
cmd.Parameters.Add("#uid", MySqlDbType.Int32).Value = txtUser.Text
cmd.ExecuteNonQuery()
Else
MsgBox("Password is not correct")
End If
End Using
End Using
Resource leaks - The Using statement ensures that every disposable object is correctly disposed also in case of exceptions
Sql Injection - Using string concatenation makes easy for an attacker to wreak havoc with your database (Here the example)
Parsing problems. - Again, string concatenation fails if one of your string values contains a single quote.
Performance - Creating a DataReader is troublesome for many reason. If you need to read just one column from one row then ExecuteScalar is faster and doesn't block the connection until you close the reader. (Your code cannot work because the reader keeps the connection busy and you cannot use the connection with the command until you close the reader
Another point to keep present is the clear text password problem. If you store the password of your users in clear text in the database, everyone that has access to the database with any kind of administrative tool (MySqlWorkbench, phpMyAdmin....) could easily learn the passwords of all your users. This is more complex matter and if you search this site you could find a lot of questions/answers about that

I don't see any cmd.ExecuteReader for your UPDATE command. Did you missed that or it's just missing from the post. You should execute the query saying
If dr.HasRows Then
cmd.Connection = con
cmd.CommandText = " UPDATE login SET password ='" & txtConfirm.Text & "' where userid = '" & txtUser.Text & "'"
dr = cmd.ExecuteReader // missing statement
Else
MsgBox("Password is not correct")
End If

Related

Checking if the user is already registered

I'm trying to create a register for using mysql table as if username and pass is already added it output a msgbox saying you are already registered but what happen is that it always add it even if it already exists ..
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim cn As New SqlConnection
Dim cmd As New SqlCommand
Dim cmd2 As New SqlCommand
Dim dr As SqlDataReader
cn.ConnectionString = "Server=localhost;Database=test;Uid=sa;Pwd=fadyjoseph21"
cmd.Connection = cn
cmd.CommandText = "INSERT INTO test2(Username,Password) VALUES('" & TextBox1.Text & "','" & TextBox2.Text & "')"
cmd2.CommandText = cmd.CommandText = "SELECT username, password FROM test2 WHERE username = '" & TextBox1.Text & "' and password = '" & TextBox2.Text & "'"
cn.Open()
MsgBox("Registered")
cmd.ExecuteNonQuery()
dr = cmd.ExecuteReader
If dr.HasRows Then
MsgBox("You're already registered")
End If
End Sub
End Class
You never actually check to see if the username exists.
You define a query here:
cmd2.CommandText = cmd.CommandText = "SELECT username, password FROM test2 WHERE username = '" & TextBox1.Text & "' and password = '" & TextBox2.Text & "'"
But never execute that query. Instead, you just execute the INSERT query:
dr = cmd.ExecuteReader
So the INSERT is always performed. And since an INSERT doesn't return rows, you don't see the message box.
First thing's first, fix your SQL injection vulnerability. (Personal policy, I don't like writing SQL-injectable code in an answer.) Use query parameters instead of directly concatenating user input as code:
cmd2.CommandText = "SELECT * FROM test2 WHERE username = #Username"
cmd2.Parameters.Add("#Username", SqlDbType.VarChar, 50).Value = TextBox1.Text
dr = cmd2.ExecuteReader
If dr.HasRows Then
MsgBox("You're already registered")
Return
End If
Note a couple of things here:
The use of a query parameter. I had to guess on the type and size of the column in the database, adjust that as necessary.
Only executing this one query. Don't try to execute both queries at the same time, perform the first one and then perform the second one.
You don't need, or even want, to include the password in this query. You're checking if the username already exists, that's all.
Return after showing the message, so the rest of the function doesn't execute.
Then, after that is done, you can perform the INSERT operation:
cmd.CommandText = "INSERT INTO test2(Username,Password) VALUES(#Username,#Password)"
cmd.Parameters.Add("#Username", SqlDbType.VarChar, 50).Value = TextBox1.Text
cmd.Parameters.Add("#Password", SqlDbType.VarChar, 50).Value = TextBox2.Text
cmd.ExecuteNonQuery()
This will perform the INSERT operation. So if the Return above was never encountered then the username is unique and can be inserted.
Also: You should not be storing user passwords in plain text. This is grossly irresponsible to your users and exposes their private data to attackers. Instead, obscure the password with a one-way hash so that it can't be read in its original form.
A couple other things:
Use meaningful variable names. The whole reason you were having this problem was because you were getting confused between cmd and cmd2. If your variable names carry semantic meaning, your code is a lot easier to read and understand.
Make use of the Using block when you have disposable resources, such as a database connection. In general you want to open, use, and close a database connection in as small a scope as possible. Leaving open connections hanging around is a Bad Thing.
Add unique key constraint on username and hence when it already exist it will throw duplicate entry exception.
Secondly, never save plain text password in Database, it must be hasheh and encrypted. I would suggest to better use Bcrypt of atleast level 10 to generate hashed password and also use Bcrypt dynamic salt which is mostly preferred now.
Thirdly, always use parameterized query to avoid your program from mysql injection.
For example:-
Normal:
SELECT * FROM customers WHERE username = 'timmy'
Injection:
SELECT * FROM customers WHERE username = '' OR 1''

MySQL inserting a column into a variable

I'm working on a project that needs to prevent double username inserted in a database my code looks like this:
Command = New MySqlCommand("Select * From userscanner", Connection)
Command.ExecuteNonQuery()
Dim dr As MySqlDataReader
dr = Command.ExecuteReader
With dr
.Read()
Dim check As String = .Item(1)
.Close()
If check = txtbox_username.Text Then
MsgBox("Username Already Taken")
Exit Sub
My problem is it only gets 1 column or is there any other way to prevent double username in my database?
I need all column in my username column. I'm using VB and MySQL.
You should ask your database if a particular user name exists or not.
This could be done with a WHERE clause
Dim sqlText = "SELECT 1 FROM userscanner WHERE username = #name"
Using Command = New MySqlCommand(sqlText, Connection)
Command.Parameters.Add("#name", MySqlDbType.VarChar).Value = txtbox_username.Text
Dim result = Command.ExecuteScalar()
if result IsNot Nothing Then
MsgBox("Username Already Taken")
End If
End Using
Here I assume that your database table named userscanner has a field named username (the field retrieved by your code with Item(1)) where you store the user names. Adding a WHERE condition and a simple return of 1 if there is a record allows to use the simple ExecuteScalar that returns the value 1 if there is a matching record to your textbox value or Nothing if there is no record
I found an answer to the question on my own.
Command = New MySqlCommand("Select * From userscanner WHERE Username = '" & txtbox_username.Text & "'", Connection)
Command.ExecuteNonQuery()
Dim dr As MySqlDataReader
dr = Command.ExecuteReader
dr.Read()
dr.Close()
If dr.HasRows Then
MsgBox("Username Already Taken")
Thanks for the help guys

String from Database set as public string

Ok from the answer from the previous question the reasoning still applies here but this time A different issue. There is a login system (Loginvb.vb) that I got for the launcher I was creating and was wondering 2 things:
Is there a better way to do the Login check with the database (as in
more secure) (the login style will have a web based registration
setting via PHP script)?
Is there a way to take a certain column (labled as access) in the database and put it
as a public string so I can check if it will equal 1 2 or 3 in a
different form labeled as Main.vb
Here is the current login check:
Public Sub login_Click(sender As Object, e As EventArgs) Handles login.Click
If txtuserName.Text = "" Or txtpassWord.Text = "" Then
MsgBox("You cannot progress until you login....(moron =p)")
Else
'Connects To the Database
Dim connect As MySqlConnection
connect = New MySqlConnection()
connect.ConnectionString = "server=127.0.0.1;user id=sc;Password=derp;database=sclaunch" 'not the actual login ;)
Try
connect.Open()
Catch myerror As MySqlException
MsgBox("Error Connecting to Database. Please Try again !")
End Try
'SQL Query To Get The Details
Dim myAdapter As New MySqlDataAdapter
Dim sqlquerry = "Select * From login where username = '" + txtuserName.Text + "' And password= '" + txtpassWord.Text + "'"
Dim myCommand As New MySqlCommand()
'My fail attempt at what I am trying to do :(
Dim sql22 As MySqlConnection
sql22 = New MySqlConnection()
sql22.ConnectionString = "Select * From login where access ="
'End of fail attempt
myCommand.Connection = connect
myCommand.CommandText = sqlquerry
'Starting The Query
myAdapter.SelectCommand = myCommand
Dim mydata As MySqlDataReader
mydata = myCommand.ExecuteReader
'To check the Username and password and to validate the login
If mydata.HasRows = 0 Then
MsgBox("Invalid Login")
Else
'fail testing xD
Label3.Text = sql22
MsgBox("You are now Loged In!")
End If
End If
End Sub
Still basically learning more and more as I am coding all this got to love trial and error and the moments where you get stuck =/ (Sorry to the admins or whatever for fixing tag issues still new to the site xD)
Assuming that the same table login that contains the credentials contains also the access column that you want to retrieve, then I have changed a lot of your code
Dim sqlquerry = "Select * From login where username = #name AND password=#pwd"
Dim myCommand As New MySqlCommand(sqlquery, connect)
myCommand.Parameters.AddWithValue("#name", txtuserName.Text)
myCommand.Parameters.AddWithValue("#pwd", txtpassWord.Text)
Dim mydata = myCommand.ExecuteReader
If mydata.HasRows = False Then
MsgBox("Invalid Login")
Else
' the same record that contains the credentials contains the access field'
mydata.Read()
Label3.Text = mydata("access").ToString()
MsgBox("You are now Loged In!")
End If
What I have changed:
Removed the string concatenation and added the appropriate parameters
Removed myAdapter and every references to it (not needed, you don't
fill DataTable/DataSet)
Removed sql22 and every references to it. It's a Connection and you
try to use like a Command
Fixed the check on HasRows (Returns a boolean not an integer. Are you
using Option Strict Off?)

MySQL Data NOT Deleting from table VB.NET

Why won't this delete the data in my MySQL database!?
Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
Dim dbCon As MySqlConnection
Dim strQuery As String = ""
Dim SQLCmd As MySqlCommand
Dim DR As MySqlDataReader
Try
dbCon = New MySqlConnection("Server=Localhost;Database=myusers;Uid=root;Pwd=Mypassword")
strQuery = "DELETE settings FROM settings WHERE user=" & Me.loginuser.Text
'* FROM settings WHERE user = "Testuser"'
SQLCmd = New MySqlCommand(strQuery, dbCon)
' OPEN THE DB AND KICKOFF THE QUERY
dbCon.Open()
DR = SQLCmd.ExecuteReader
While DR.Read
req1.Text = "" And exlink.Text = ""
End While
' DONE! Close DB
DR.Close()
dbCon.Close()
Catch ex As Exception
TextBox8.Text = ("Fail" & vbCrLf & vbCrLf & ex.Message)
End Try
Here is a picture of my database:
Alternatively I could somehow make it replace what is already in the database, in which case please help me with that.
Try
strQuery = "DELETE FROM settings " _
& " WHERE user = '" & Me.loginuser.Text & "'"
but as was stated earlier, you should be using parameterized queries. If you had a user named O'Brien then your query (as composed above) would fail because of the embedded single quote. When you use DELETE, you are deleting entire records and you already specify the table name in the FROM clause.
I will try to change your code in this way
Using con = New MySqlConnection("Server=.....")
con.Open()
Dim sqlText = "DELETE * FROM settings WHERE user = #ulogin"
Using cmd = new MySqlCommand(sqlText, con)
cmd.Parameters.AddWithValue("#ulogin", Me.loginuser.Text)
cmd.ExecuteNonQuery()
End Using
End Using
First and foremost, do not use string concatenation to create command texts to pass to the database engine. In that way you risk Sql Injections, also, if the user name contains a single quote (i.e. O'Hara) your code will fail with a syntax error (Same problems arise for date formatting, parsing numeric decimals and other globalization issues). Instead a parametrized query like the one in code above will avoid all of these problems.
In a parametrized query, the text of the query doesn't contains the actual value for the search condition or the update or insert data. Instead it contains placeholders ( in our case it is called #ulogin). The correct value to insert at the placeholders position is specified using one or more MySqlParameter added to the Parameters collection of the MySqlCommand. In this case I have used the AddWithValue method that derives the correct datatype directly from the datatype of the value. Because Me.loginuser.Text is a string value then the parameter will be treated as a string value replacing incorrect single quotes and removing extraneus characters usually used to Mount Sql Injections Attacks. The engine will do the rest inserting the correct value at the placeholder at execution time
EDIT: Seeing your comment about the MySql connector used, I will try to update my answer to show a semi-equivalent version for NET 1.
Try
Dim con As MySqlConnection = New MySqlConnection("Server=.....")
con.Open()
Dim sqlText as String = "DELETE * FROM settings WHERE user = #ulogin"
Dim cmd As MySqlCommand = new MySqlCommand(sqlText, con)
Dim par As MySqlParameter = New MySqlParameter("#ulogin", MySqlDbType.VarChar)
par.Value = Me.loginuser.Text
cmd.Parameters.Add(par)
cmd.ExecuteNonQuery()
Finally
con.Close()
End Try
I am not sure if the connector 1.0.10 supports the parameter name with the # prefix or just the : prefix
i dont think you can use double quotes in mysql, i think its single quotes only. try
Query = "DELETE * FROM settings WHERE user = '" & Me.loginuser.Text & "'"

MySql query statement syntax error

I am getting a syntax error for the code below.
I am trying to create a user in the mysql database and add their information to a datagrid control all in one button click using two statements; one to create the actual user, and one to add the user and their additional information to a table on the database and then refresh the datasource which will display the new user's information in the datagrid control.
If anyone knows where i went wrong please feel free to critique my code and let me know; or simply offer more efficient alternatives to what im hoping to achieve.
For those of you that must know, i am running the latest version of MySql server, MySql Workbench, and Visual Basic 2010 Express on a windows 7 based laptop. I'm writing this program in VB.net.
Thanks!
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
Dim sqluser As MySqlCommand = New MySqlCommand(
"CREATE USER " & txtuser.Text & "#" & frmLogin.txtserver.Text & " IDENTIFIED BY '" & txtpass.Text & "';", con)
Dim sqlinfo As MySqlCommand = New MySqlCommand(
"INSERT INTO employee(Name ,Title) VALUES('" & txtname.Text & "','" & txttitle.Text & "';", con)
Try
con.Close()
con.Open()
sqluser.ExecuteNonQuery()
MessageBox.Show("User Account successfully created!!")
sqlinfo.ExecuteNonQuery()
' retrieving the administration table.
DataAdapter1.SelectCommand = sqladmin
DataAdapter1.Fill(ds, "stratos")
DataGrid1.DataSource = ds
DataGrid1.DataMember = "stratos"
con.Close()
MessageBox.Show("User Information successfully created!!")
Catch myerror As MySqlException
MessageBox.Show("Error Setting Up Account: " & myerror.Message)
End Try
End Sub
You are missing a ')' at the end of your insert statement.
Dim sqlinfo As MySqlCommand = New MySqlCommand("INSERT INTO employee(Name ,Title ) VALUES('" & txtname.Text & "','" & txttitle.Text & "');"
I would also like to point out that this code will fail if the text has an apostrophe in it, and that it is wide open to SQL Injection. Please read up.
I think you may also need apostrophes around the username and host.
CREATE USER '" & txtuser.Text & "'#'" & frmLogin.txtserver.Text & "' IDENTIFIED BY '" & txtpass.Text & "';"
As for SQL Injection, I would recommend you consider reworking your code to use prepared statements like this. Replace those first two lines with this instead. Basically, you put in little placeholders in your query, and let the database driver handle all of the complex escaping and quoting of things for you. I'm not 100% sure this will work, but I think it's close.
Dim sqluser As MySqlCommand = New MySqlCommand("CREATE USER ?user#?host IDENTIFIED BY ?pass;", con)
sqluser.Parameters.Add("?user", txtuser.Text)
sqluser.Parameters.Add("?host", frmLogin.txtserver.Text)
sqluser.Parameters.Add("?pass", txtpass.Text)
sqluser.Prepare()
Dim sqlinfo As MySqlCommand = New MySqlCommand("INSERT INTO employee(Name ,Title) VALUES( ?user, ?title );", con)
sqlinfo.Parameters.Add("?user", txtuser.Text)
sqlinfo.Parameters.Add("?title", txttitle.Text)
sqlinfo.Prepare()
It has been ages since I did any VB, so this is mostly based on this page. Try to look here if this doesn't quite work. Documentation on Prepare