This scripts selects an account form my MySQL database with the userID 1:
$_SESSION['user_id'] = 1;
If my MySQL account has id 1 then it will change that account.
I wonder how you can change the = 1; so it automatically looks up which account you are on at the moment? Right now it only works with the account with userID 1.
MySQL database name for my userid is "userID".
Usually you would say something like
SELECT * FROM user_profiles WHERE user_id=1 in MySQL.
Also, I would recommend that you use PDO and properly escape the user input using
htmlspecialchars($_SESSION['user_id'])
in your PHP file since the user_id input most likely can be manipulated by the user.
You are using Session so it can not change the userID unless you destroy that session by using this PHP function:
session_destroy();
And if you want to know your current userID:
echo $_SESSION['user_id'];
Related
(Massively edited because the responses were focusing on the wrong thing, which means I didn't formulate the question properly.)
I have a MySQL table with id, username and password fields. The password is encrypted. Part of the encryption uses the id of the record, specifically (in PHP):
md5 (md5('id') . $formPasswordCleaned)
To a validate a login form, I do the following (pseudo-code):
query database for the email address from login form
if num_rows > 0, $row = fetch_array
use $row['id'] to encrypt the password provided in the login form.
compare encrypted password with the one found in $row 4.
But, what I'd really like to do is one single SELECT command, that looks for a match on both email address and the encrypted password. But, since the password was encrypted using the row's id.....
Question: is it possible to write a SELECT statement that uses part of the forthcoming result as some of the arguments? Something like: SELECT * from users where email=$email and password=md5(md5($futureResult['id]).$password)
I realise it's self-referential, but I know just the basics of database usage and so I don't know what to search for (google or here) to find out if it's possible or how to do it, if it is indeed possible.
I am attending a free online course at Pentesterlab and today I am getting comfortable with SQL Injections.
However I don't get the instructions and as it could be a huge (technical) difference I would want to know how it works.
The stuff I am talking about:
https://www.pentesterlab.com/exercises/web_for_pentester/course
Please scroll down more than the half to "SQL Injections" --> "Example 1".
In the example we found out, that the (My)SQL-Table should work like this pattern:
SELECT * FROM users WHERE name='[INPUT]';
As I understand this, all I am providing through the URL is the "INPUT", the quotes (') before and after the input, and the semicolon (;) is added by SQL automatically.
However, the instruction says:
?name=root' and '1'='1: the quote in the initial query will close the
one at the end of our injection.
I don't get it. I thought the quote (') after root ends the first part, but there's still the other part '1'='1 , isn't it?
Maybe it's a misunderstanding of the language, however I am not sure if I understood it .
Imo the SQL should look like this (for example 1, first "code"):
SELECT * FROM users WHERE name=' root' and '1'='1 ';
At the second try at Example 1 it's getting stranger:
?name=root' and '1'='1' # (don't forget to encode #): the quote in the initial query will be commented out.
Wait what? I thought the quote provided by SQL automatically gets commented out.
Imo the SQL should look like this (for example 1, second "code"):
SELECT * FROM users WHERE name=' root' and '1'='1' # ';
Hope someone can clear it out, if I understand it right and it's just to hard for me explained or if I am messing up something.
Thank you guys :)
Mysql does not addanything automatically to your query. If you are not providing a single quote, then it will not be there. Period.
SELECT * FROM users WHERE name='[INPUT]';
The application will contain the above sql statement template in its own code and will substitute the parameter received from the user in place of the [INPUT] placeholder.
If you provide a single name, as you are supposed to, then the query executed will be:
SELECT * FROM users WHERE name='root';
However, if you provide root' and '1'='1 as an input, then the sql code being executed will be
SELECT * FROM users WHERE name='root' and '1'='1';
The single quote before root and after the 2nd 1 are part of the sql statement template within the application.
I haven't read the course, so let's assume the logic will check the user exists in database only.
Original SQL
SELECT * FROM users WHERE name = 'admin'
(1 row affected)
By SQL injection, you can input something after that to make this SQL always return records
by input user name as [root' and '1' = '1]
SELECT * FROM users WHERE name = 'root' and '1' = '1'
(20 rows affected)
However, let's assume this SQL will also check the password
SELECT * FROM users WHERE name = 'admin' and pwd = 'abc'
(1 row affected)
by input user name as [root' and '1' = '1]
SELECT * FROM users WHERE name = 'root' and '1' = '1' and pwd = 'invalid'
(0 row affected)
We need to bypass the password, what need to do is comment out the rest of SQL
by input user name as [root' and '1' = '1'#]
SELECT * FROM users WHERE name = 'root' and '1' = '1'#' and pwd = 'abc'
(20 rows affected)
With this SQL, it will comment out the password checking, and it will grant access even you don't have the correct user name and password
So for a school project I have to make a site with a log-in system. It has a username and password field, and a submit button. It compares the username and password with those in a MySQL database. If the combination is in the database, the user may proceed, else they are redirected to the log-in page. I use prepared PDO statements for my database connection.
Now my teacher wants me to test the safety by performing sql attacks on the log-in system. Unfortunately I have no idea what to put in these boxes, and what would be the outcome. For example, I have tried putting values in both username and password fields that will return true, like this:
1==1, 1===1, 0 is null
But I do not know whether or not I have succeeded and if attackers may access or truncate my database by these sort of statements.
Html code:
<form method="post" action="includes/login.php">
<input type="text" name="gebruikersnaam" >
<input type="password" name="wachtwoord" >
<input type="submit" value="login">
</form>
Php authentication:
$myusername=$_POST['gebruikersnaam'];
$mypassword=$_POST['wachtwoord'];
$sql="SELECT * FROM leerling WHERE leerlingnummer='$myusername' and wachtwoord='$mypassword'";
$sql2="SELECT * FROM lop WHERE gebruikersnaam='$myusername' and wachtwoord='$mypassword'";
$statement2=$conn->prepare($sql2);
$statement2->execute();
$count2=$statement2->rowcount();
if($count2==1){proceed}
$statement = $conn->prepare($sql);
$statement->execute();
$count= $statement->rowcount();
if($count==1){proceed}
else {deny access}
Imagine this query:
SELECT id FROM users WHERE email=? AND password=? LIMIT 1
Now imagine the values would be foo#bar.hello and an empty string for password:
SELECT id FROM users WHERE email='foo#bar.hello' AND password='' LIMIT 1
This would not be harmful if these credentials are not in your database. Now lets give different input:
For email we fill in an empty string, and for password we insert ' OR 1=1 (Note the first apostrophe)
Your teacher wants you to find out whether this means your SQL server will execute the following query:
SELECT id FROM users WHERE email='' AND password='' OR 1=1 LIMIT 1
SQL is a declarative language with which you declare the expectations you have for your result. If your server would interpret our input as stated above, the first users id would be considered correct, simply because one is equal to one.
As it is, it is susceptible to SQL injection
The thing to look at when trying to inject is can I close the statement I'm in right now and add more to the end.
so if you enter username = 123456' -- the SQL statement becomes SELECT * FROM leerling WHERE leerlingnummer='123456' --' and wachtwoord='unimortant'
the -- starts a comment so all it does is select whatever student number is entered ignoring the password.
PDO has good alternatives to prevent this from happening called Prepared Statements. You declare your SQL queries and only enter where user infromation is going to be entered by using a ? or :lable and then bind user input to those points. The page does a way better job at explaining it. This way all user data is clearly seperated from the rest of the command and will be treated as a litteral string rather than a command. Stopping SQL injection.
$sql="SELECT * FROM users WHERE username = '{$_REQUEST['username']}' AND password = '{$_REQUEST['password']}";
Write query in such format will avoid sql injection.
$sql = 'SELECT * FROM users WHERE username = ? AND password = ?';
$query = $db->prepare($sql);
$query->bindParam(1, $_REQUEST['username']);
$query->bindParam(2, $_REQUEST['password']);
Or pass the parameter to mysql_real_escape_string function and then pass to queries.
$username=mysql_real_escape_string($_REQUEST['username']);
$password=mysql_real_escape_string($_REQUEST['password']);
At school, I believe I work with Oracle SQL Developer when writing SQL. And in this I can type:
SELECT Book_Title, Auth_ID
FROM book
WHERE Auth_ID = '&Enter ID';
This will then display a little message box where the user can enter an ID number to see all the books written by an author with that ID number.
I want to know if there is a way to do this in MySQL. I have looked and the nearest thing I can find is setting a variable before hand, which is not quite what I'm looking for:
SET #EnterID := 2;
select Book_Title, Auth_ID
from book
where Auth_ID = #EnterID;
The above statement in MySQL will return all the books with author ID of 2, but only because I set it to that previously. I want the user to be able to enter the variable.
Thanks.
Oracle has the concept of interactive queries, those that as you said you can run by adding the '&' before your variables names, that is a variable substitution, this concept doesn't exist in MySql, MySql is not interactive and requires the user to enter the values in the variables by using the keyword 'SET' and # (instead of & like in Oracle).
So, no, you cannot do what you are looking for since this is not a client-side implementation either.
BTW, I just noticed this was asked so many years ago, amazing that this is still not added as a feature in mysql.
For a prompt, you must put the char ':' followed by the name of the variable
Example :
select *
from YOUR_TABLE
where YOUR_COLUMN = :your_var
mysql is to run SQL queries .SQL is a query language, it is not for user interaction
See : How to ask MySQL to prompt for values in a query?
I'm not exactly sure on the correct technical wording, so excuse my title, but here's the problem. I have a MySQL database, and in the user table I have *user_name*, a *password_salt*, and an md5 password containing the password then salt. In a program, users connect and I get one query to send to validate a user.
When a user connects I need a way of selecting their user_name, and comparing the given password to the stored password, which requires retrieving the salt somewhere in the WHERE statement (I guess).
This is my hypothetical "example":
SELECT user_name
FROM users
WHERE user_name='$nick' AND
password = md5(CONCAT('$md5pass', md5((select password_salt FROM users where user_name='$nick'))))
LIMIT 1
Resolution Update: Got it working, thanks for the suggestions, a normal select sufficed, the problem was that the sql-auth api wasn't receiving the password unless the port was specified.
Actually you can freely use any column from table declared in "FROM" clause not only in "SELECT" clause, but also in "WHERE" clause, so I don't see a need to subquery here. Let it be simply:
SELECT user_name
FROM users
WHERE user_name='$nick' AND
password = md5(CONCAT('$md5pass', md5(password_salt)))
LIMIT 1
This way a row is selected only if it matches both:
- user name is correct
- the password in row matches given password
I am not sure though if I used md5() functions correctly. I copied your example.
SELECT user_name
FROM users
WHERE user_name='$nick' AND
password = md5(CONCAT('$md5pass', password_salt))
LIMIT 1
Try this instead:
SELECT user_name
FROM users
WHERE user_name='$nick' AND
password = md5(CONCAT('$md5pass', md5(password_salt)))
LIMIT 1