I have created this code for testing of SQL injection.
<?php
mysql_connect('localhost', 'root', '');
mysql_select_db("test");
$id = $_POST['data'];
$query = "SELECT * FROM members WHERE memberId ='" . $id . "'";
$q = mysql_query($query);
if (mysql_num_rows($q) == 0)
{
printf("<h4>Wrong user ID!</h4>");
}
else
{
while ($row = mysql_fetch_array($q))
{
printf("<h4>Your ID is %s</h4>", $row["memberId"]);
}
}
?>
When variable $id is 1' OR '1'='1, I can see all IDs in the table members.
I would like also realize DROP TABLE, but I can't figure out what to insert in variable id $id. I have tried to insert 123'; DROP TABLE sql injection-- in $id.
Do you have any idea what to insert in $id or how to modify this code?
In the console it would be: '; drop table members; select '
However you are using mysql_query and it supports only a single statement.
Here is what the manual says:
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.
Also check this question.
As suggested there you can try using multi_query in your example.
Related
I'm developing an app for android that uses a DB on a server.
I wrote some script php to create new rows in some tables and get all elements from a table (using JSON to exchange data between android and mysql).
Now I have a problem:
i need to select an id from a table and then use this to insert a row in anothere table that has this foreign key.
Well, when I try to select my id, i don't know why, but look like it doesn't work.
Here a simple example how I select this id:
//connect to DB...
$result = mysql_query (*SELECT id FROM 'table' WHERE name = $name );
$row = mysql_fetch_assoc($result);
$id = $row['id'];
When i use this to select an id, and put it in another query (always on the same connectio) nothing is stored.
if I force the value manually, and so in the same second query I put a number of a preesisting id, the insert works, so the problem is in this piece of code.
Hope someone could help me.
Thank you!
The code that you have put on the question, contains syntax errors.
- Remove * from the start of query
- put the query inside " "
- remove single quote ('table') from table name
Here is the modified code:
//connect to DB...
$result = mysql_query ("SELECT id FROM table WHERE name = $name" );
$row = mysql_fetch_assoc($result);
$id = $row['id'];
Also you should escape the parameter $name in query. And you should use mysqli or PDO instead of mysql extension.
try this:
$result = mysql_query (*SELECT id FROM 'table' WHERE name = $name );
$row = mysql_fetch_assoc($result);
while($row > 0){
$id = $row['id'];
}
another day another question...
I need to write PHP script to update mySQL database.
For example: updating profile page when user want to change their first name, last name or etc.
Here is my php script so far, it doesn't work. Please help!
<?php
# $db = new MySQLi('localhost','root','','myDB');
if(mysqli_connect_errno()) {
echo 'Connection to database failed:'.mysqli_connect_error();
exit();
}
if (isset($_GET['id'])) {
$id = $db->real_escape_string($_GET['id']);
$First_Name2 = $_POST['First_Name2'];
$query = "UPDATE people SET $First_Name2 = First_Name WHERE `Id` = '$id'";
$result = $db->query($query);
if(! $result)
{
die('Could not update data: ' . mysql_error());
}
echo "Updated data successfully\n";
$db->close();
}
?>
THank you.
Your sql is wrong. Apart from the gaping wide open SQL injection attack vulnerability, you're generating bad sql.
e.g. consider submitting "Fred" as the first name:
$First_Name2 = "Fred";
$query = "UPDATE people SET Fred = First_name WHERE ....";
now you're telling the db to update a field name "Fred" to the value in the "First_Name" field. Your values must be quoted, and reversed:
$query = "UPDATE people SET First_name = '$First_Name2' ...";
You are also mixing the mysqli and mysql DB libraries like a drunk staggering down the street. PHP's db libraries and function/method calls are NOT interchangeable like that.
In short, this code is pure cargo-cult programming.
I'm building a simple bug tracking tool.
You can create new projects, when you create a project you have to fill in a form, that form posts to project.class.php (which is this code)
$name = $_POST['name'];
$descr = $_POST['description'];
$leader = $_POST['leader'];
$email = $_POST['email'];
$sql="INSERT INTO projects (name, description, leader, email, registration_date)
VALUES ('$name', '$descr', '$leader', '$email', NOW())";
$result = mysql_real_escape_string($sql);
$result = mysql_query($sql);
if($result){
header('Location: ../projectpage.php?id='.mysql_insert_id());
}
else {
echo "There is something wrong. Try again later.";
}
mysql_close();
(It's not yet sql injection prove, far from complete...)
Eventually you get redirected to the unique project page, which is linked to the id that is stored in the MySQL db. I want to show the name of that project on the page, but it always shows the name of the first project in the database.
(here I select the data from the MySQL db.)
$query = 'SELECT CONCAT(name)
AS name FROM projects';
$result = mysql_real_escape_string($query);
$result = mysql_query ($query);
(here I show the name of the project on my page, but it's always the name of the first project in the MySQL db)
<?php
if ($row = mysql_fetch_array ($result))
echo '<h5>' . $row['name'] . '</h5>';
?>
How can I show the name of the right project? The one that is linked with the id?
Do I have the use WHERE .... ?
Yes, You have to use the WHERE to specify which project You want to get. I'm also not sure why are You using CONCAT function when You want to get only one project.
Other important thing is that You have to use mysql_real_escape_string() function on parameters before You put them in the query string. And use apropriate functions for specific type of data You receive.
So Your statement for getting the project should look like this:
SELECT name FROM projects WHERE id = ' . intval($_GET['id'])
Also when before You use the mysql_fetch_assoc() function, check if there are any records in the result with
if(mysql_num_rows($result) > 0)
{
$project = mysql_fetch_assoc($result);
/* $project['name'] */
}
try this
// first get the id, if from the url use $_GET['id']
$id = "2";
$query = "SELECT `name` FROM `projects` WHERE `id`='".intval($id). "'";
$result = mysql_query(mysql_real_escape_string($query));
use mysql_fetch_row, here you'll not have to loop through each record, just returns single row
// if you want to fetch single record from db
// then use mysql_fetch_row()
$row = mysql_fetch_row($result);
if($row) {
echo '<h5>'.$row[0].'</h5>';
}
$row[0] indicates the first field mentioned in your select query, here its name
The might be of assistance:
Your are currently assing a query string parameter projectpage.php?id=
When you access the page the sql must pick up and filter on the query string parameter like this:
$query = 'SELECT CONCAT(name) AS name FROM projects WHERE projectid ='. $_GET["id"];
$result = mysql_real_escape_string($query);
$result = mysql_query ($query);
Also maybe move mysql_insert_id() to right after assigning the result just to be safe.
$result = mysql_query($sql);
$insertId = mysql_insert_id();
Then when you assign it to the querystring just use the parameter and also the
header('Location: ../projectpage.php?id='.$insertId);
So I've been trying to replicate a second order SQL Injection. Here's an example template of two php based sites that I've prepared. Let's just call it a voter registration form. A user can register and then you can check if you're a registered voter or not.
insert.php
<?php
$db_selected = mysql_select_db('canada',$conn);
if (!db_selected)
die("can't use mysql: ". mysql_error());
$sql_statement = "INSERT into canada (UserID,FirstName,LastName,Age,State,Town)
values ('".mysql_real_escape_string($_REQUEST["UserID"])."',
'".mysql_real_escape_string($_REQUEST["FirstName"])."',
'".mysql_real_escape_string($_REQUEST["LastName"])."',
".intval($_REQUEST["Age"]).",
'".mysql_real_escape_string($_REQUEST["State"])."',
'".mysql_real_escape_string($_REQUEST["Town"])."')";
echo "You ran the sql query=".$sql_statement."<br/>";
$qry = mysql_query($sql_statement,$conn) || die (mysql_error());
mysql_close($conn);
Echo "Data inserted successfully";
}
?>
select.php
<?php
$db_selected = mysql_select_db('canada', $conn);
if(!db_selected)
die('Can\'t use mysql:' . mysql_error());
$sql = "SELECT * FROM canada WHERE UserID='".addslashes($_POST["UserID"])."'";
echo "You ran the sql query=".$sql."<br/>";
$result = mysql_query($sql,$conn);
$row=mysql_fetch_row($result);
$sql1 = "SELECT * FROM canada WHERE FirstName = '".$row[1]."'";
echo "The web application ran the sql query internally=" .$sql1. "<br/>";
$result1 = mysql_query($sql1, $conn);
$row1 = mysql_fetch_row($result1);
mysql_close($conn);
echo "<br><b><center>Database Output</center></b><br><br>";
echo "<br>$row1[1] $row1[2] , you are a voter! <br>";
echo "<b>VoterID: $row[0]</b><br>First Name: $row[1]<br>Last Name: $row[2]
<br>Age: $row[3]<br>Town: $row[4]<br>State: $row[5]<br><hr><br>";
}
?>
So I purposely made this vulnerable to show how second order SQL Injection works, a user can type in a code into the first name section (where I am currently stuck, I've tried many different ways but it seems that I can't get it to do anything).
Then when a person wants to activate the code that he has inserted in the first name section, all he needs to do is just type in the userID and the code will be inserted.
For example:
I will type into the insert.php page as:
userid = 17
firstname = (I need to inject something here)
lastname = ..
age = ..
town = ..
state = ..
Then when I check for my details, and type in 17, the SQL script injected will be activated.
Can I get few examples on what sort of vulnerabilities I can show through this?
What is there to demonstrate?
Second order SQL injection is nothing more than SQL injection, but the unsafe code isn't the first line.
So, to demonstrate:
1) Create a SQL injection string that would do something unwanted when executed without escaping.
2) Store that string safely in your DB (with escaping).
3) Let some other piece of your code FETCH that string, and use it elsewhere without escaping.
EDIT: Added some examplecode:
A table:
CREATE TABLE tblUsers (
userId serial PRIMARY KEY,
firstName TEXT
)
Suppose you have some SAFE code like this, receiving firstname from a form:
$firstname = someEscapeFunction($_POST["firstname"]);
$SQL = "INSERT INTO tblUsers (firstname) VALUES ('{$firstname }');";
someConnection->execute($SQL);
So far, so good, assuming that someEscapeFunction() does a fine job. It isn't possible to inject SQL.
If I would send as a value for firstname the following line, you wouldn't mind:
bla'); DELETE FROM tblUsers; //
Now, suppose somebody on the same system wants to transport firstName from tblUsers to tblWhatever, and does that like this:
$userid = 42;
$SQL = "SELECT firstname FROM tblUsers WHERE (userId={$userid})";
$RS = con->fetchAll($SQL);
$firstName = $RS[0]["firstName"];
And then inserts it into tblWhatever without escaping:
$SQL = "INSERT INTO tblWhatever (firstName) VALUES ('{$firstName}');";
Now, if firstname contains some deletecommand it will still be executed.
Using a first name of:
' OR 1 OR '
This will produce a where clause in the second SQL of
WHERE FirstName = '' OR 1 OR ''
Therefore the result will be the first record in the table.
By adding a LIMIT clause, you can extract all rows from the table with:
' OR 1 ORDER BY UserID ASC LIMIT 0, 1 --
Obviously it will only extract 1 row at a time, so you would need to repeat that and increment the 0 in the LIMIT. This example uses a comment -- to terminate the remaining SQL which would otherwise cause the query to fail because it would add a single quote after your LIMIT.
The above is a simple example, a more complex attack would be to use a UNION SELECT which would give you access to the entire DB through the use of information_schema.
Also you are using addslashes() in one of your queries. That is not as secure as mysql_real_escape_string() and in turn: escaping quotes with either is not as secure as using prepared statements or parameterised queries for example in PDO or MySQLi.
Suppose I have a table called "device" as below:
device_id(field)
123asf15fas
456g4fd45ww
7861fassd45
I would like to use the code below to insert new record:
...
$q = "INSERT INTO $database.$table `device_id` VALUES $device_id";
$result = mysql_query($q);
...
I don't want to insert a record that is already exist in the DB table, so how can I check whether it have duplicated record before inserting new record?
Should I revise the MYSQL statement or PHP code?
Thanks
UPDATE
<?php
// YOUR MYSQL DATABASE CONNECTION
$hostname = 'localhost';
$username = 'root';
$password = '';
$database = 'device';
$table = 'device_id';
$db_link = mysql_connect($hostname, $username, $password);
mysql_select_db( $database ) or die('ConnectToMySQL: Could not select database: ' . $database );
//$result = ini_set ( 'mysql.connect_timeout' , '60' );
$device_id = $_GET["device_id"];
$q = "REPLACE INTO $database.$table (`device_id`) VALUES ($device_id)";
$result = mysql_query($q);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
?>
Since I understood well your question you have two ways to go, it depends how you would like to do the task.
First way -> A simple query can returns a boolean result in the device_id (Exists or not) from your database table. If yes then do not INSERT or REPLACE (if you wish).
Second Way -> You can edit the structure of your table and certify that the field device_id is a UNIQUE field.
[EDITED]
Explaining the First Way
Query your table as follow:
SELECT * FROM `your_table` WHERE `device_id`='123asf15fas'
then if you got results, then you have already that data stored in your table, then the results is 1 otherwise it is 0
In raw php it looks like:
$result = mysql_query("SELECT * FROM `your_table` WHERE `device_id`='123asf15fas'");
if (!$result)
{
// your code INSERT
$result = mysql_query("INSERT INTO $database.$table `device_id` VALUES $device_id");
}
Explaining the Second Way
If your table is not yet populated you can create an index for your table, for example go to your SQL command line or DBMS and do the follow command to your table:
ALTER TABLE `your_table` ADD UNIQUE (`device_id`)
Warning: If it is already populated and there are some equal data on that field, then the index will not be created.
With the index, when someone try to insert the same ID, will get with an error message, something like this:
#1062 - Duplicate entry '1' for key 'PRIMARY'
The best practice is to use as few SQL queries as possible. You can try:
REPLACE INTO $database.$table SET device_id = $device_id;
Source