I have a search feature that onkeydown gives out suggestions. Currently, the query only fetches from one row of the table customer_name, and I'm trying to have the id row as well to be searched for the suggestions.
so my query syntax looks likes this:
$query = "SELECT * FROM customers WHERE customer_name OR id like'%".$search."%' LIMIT 5";
But the above query will only fetches from the second table name i.e., id but not both.
What am I doing wrong here?
I could be wrong, but WHERE customer_name will always evaluate to true and thus include all records. You need to specify what customer_name should be compared to.
Correct query:
SELECT * FROM customers
WHERE customer_name LIKE '%".$search."%'
OR id LIKE '%".$search."%'
LIMIT 5;
As an important security tip, you should look into prepared statements instead of mixing data with your queries. Doing so leaves you vulnerable to SQL injection attacks.
Related
I have two tables in a database. The first table is "tb_ctsreport" with fields "qr_id, idNum, date, time" and the other one is "tb_usersreg" with many fields which includes idNum, firstName, lastName, age and address. I have displayed my table using this query:
$query = "SELECT * FROM tb_ctsreport LEFT JOIN tb_usersreg ON tb_ctsreport.idNum=tb_usersreg.idNum";
This gives me a resulting table of qr_id, idNum, Name(concatenated firstName and lastName), date, time.
Then I wanted to create a search query from this table that I have created, however, I am lost and I don't know how will I include the values firstName and lastName when searching because it is placed in another table. This is my working query except for an undefined index for displaying the name since I don't know how.
$query = "SELECT * FROM tb_ctsreport WHERE CONCAT(qr_id, idNum, time, date) LIKE '%".$searchBox."%'";
I have also tried this sql query but only gives me an error.
$query = "SELECT * FROM tb_ctsreport WHERE CONCAT(qr_id, idNum, time, date) LIKE '%".$searchBox."%'
UNION
SELECT * FROM tb_usersreg WHERE CONCAT(lastName, firstName) LIKE '%".$searchBox."%'";
Please help me. I am just new to php. Thank you!
You can use a WHERE clause after the JOINs clauses. So you can write your SQL query as:
SELECT *
FROM tb_ctsreport
LEFT JOIN tb_usersreg ON tb_ctsreport.idNum = tb_usersreg.idNum
WHERE
CONCAT(
tb_ctsreport.qr_id,
tb_ctsreport.idNum,
tb_ctsreport.time,
tb_ctsreport.date,
tb_usersreg.lastName,
tb_usersreg.firstName
) LIKE :searchBox
In the above query :searchBox is your query parameter.
Care when you concatenate user input with your SQL query, this introduces a huge security vulnerability called SQL Injection. You shuld prefer to use parameterized query to avoid this issue.
When you are referencing multiple tables in an SQL query I advise you to always use the fully qualified name for the columns in order to avoid any ambiguity.
So I have this query in php
SELECT a.sifra,a.slika,a.slika2,a.imeProizvoda,a.opis,b.cijena,b.cijena2
FROM proizvodi a
inner join stanje b
on a.sifra = b.sifra
WHERE a.imeProizvoda LIKE '%$search%'
I tried making sql injection with DROP TABLE proizvodi in every way i found on internet but couldn't make it work
How would someone make that query in search so my database proizvodi is deleted
To avoid SQL injection in PHP, you should absolutely use prepared statements, which make it pretty much impossible to do any SQL injection. For an answer to your question, we can try the following:
$search = "'; DROP TABLE proizvodi; SELECT * FROM dual WHERE '1' LIKE '";
This would result in the following being executed:
SELECT a.sifra, a.slika, a.slika2, a.imeProizvoda, a.opis, b.cijena, b.cijena2
FROM proizvodi a
INNER JOIN stanje b
ON a.sifra = b.sifra
WHERE a.imeProizvoda LIKE '%';
DROP TABLE proizvodi;
SELECT * FROM dual WHERE '1' LIKE '%'
The basic idea is to trip up PHP/MySQL by ending the original valid statement, and then injecting some other (malicious) statement afterwards. Note that DROP and DELETE are not the only damaging things which could happen. For example, doing a SELECT * on a customer table containing credit card numbers could be the most damaging thing to happen.
Disclaimer: I don't live in my parents' basement and spend all my time injecting websites. But, I knew enough to guess at an answer to your question.
I have a bunch of tables that are like Client# and the # changes. Is there a way to create a query to query that table based on the client number you get from logging in as their use?
Example to give idea:
$q2 = "SELECT * FROM users WHERE username = '".$_SESSION['username']."'";
$result2 = mysql_query($q2,$conn);
$row = mysql_fetch_assoc($result2);
$_CLIENT_ID = $row['CLIENTID'];
$q2 = "SELECT * FROM client+".$_CLIENT_ID."";
Is there a better way to do this?
I'm trying to keep clients in their own tables so they do not get to massive.
I'm trying to keep clients in their own tables so they do not get to massive.
This is almost always the wrong strategy. The table size isn't as important as how you have indexed it for access, and it can be partitioned later, should that become necessary. The proper way to handle this is simply a column in one table which identifies the client id.
With a proper client-identifying column you can query as:
SELECT othertable.*
FROM
users
JOIN othertable ON users.CLIENTID = othertable.CLIENTID
WHERE users.username = '$_SESSION['username']'
Dealing with dynamic table names becomes troublesome not only because it is more difficult to query against. You cannot, for example, use a placeholder in place of a table name with many parameterized query APIs like PDO & MySQLi:
// Won't work with a PDO prepared statement. :clienttable place holder isn't allowed
SELECT * FROM :clienttable WHERE value=:someval
I have this code for a news feed and it's combined with a code for a "load more" function. The updates table is where the updates in the newsfeed exist. The username_poster is the username of the person posting an update into which displays in the newsfeed. $last_msg_id represents the id of the last post in the newsfeed to represent what to load next.
The problem I'm having is whenever my code calls to this script, it never loads it. The script works fine when I have the
username_poster IN
(SELECT user_id FROM scuela_following WHERE follower_id = '".$_SESSION['username']."')`
out of the code, but as soon as I add it in, it stops working. Any help would be greatly appreciated.
<?php
$last_msg_id=$_GET['last_msg_id'];
$sql=mysql_query("SELECT * FROM updates_table WHERE id < '$last_msg_id' AND username_poster IN
(SELECT user_id FROM scuela_following WHERE follower_id = '".$_SESSION['username']."')
ORDER BY id DESC LIMIT 5");
$last_msg_id="";
while($row=mysql_fetch_array($sql))
{
}
?>
In this SQL it looks like you're looking for a "username_poster" in your subquery, when you're only selecting "user_id."
AND username_poster IN
(SELECT user_id
FROM scuela_following
Alter the SQL to look for "user_id" instead of "username_poster", or return "username_poster" instead of "user_id" in the subquery.
And as mentioned above, you should really use queries with parameters to prevent SQL injection.
I see that you miss the session_start(); at the very top of your script.
I suspect that there is a problem here:
"... WHERE follower_id = '".$_SESSION['username']."' ..."
Firstly you are not properly escaping and may have an SQL injection vulnerability. You should use mysql_real_escape_string or parameterized queries.
Secondly, it looks like you are comparing a username (e.g. "foobar") to an ID (e.g. 10042). You probably need to join with another table that relates usernames to user IDs.
This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 2 years ago.
The sql injection will work only when my query looks like below sample
SELECT * FROM login WHERE id = $my_id_va;
Assume if my query is
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
Than I will get following error
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'order by id desc' at line 1
So, this 1 or 1=1; SHOW TABLES will not work, correct?
My site was hacked successively many times.
I want one quick answer: When my query looks like the following one, what ways or which types of query can they use to hack my site?
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
What are the ways to execute the show table in the following query
SELECT * FROM login WHERE id = $my_id_va ORDER BY id DESC
I am also using escaping function to handle the query string values, like mysql_real_escape_string($my_id_va). Yes, obviously this for single related hack, but not sure.
Added some more
SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate between '2011-07-21 or 1=1; SHOW TABLES --' and '2011-07-31' ORDER BY EventDate DESC
but show table not worked
If you are using PHP5, use parametarized query, use PDO.
Int cast
If id is a number, you can int-cast your variable as well. Integers are safe to use:
$x = (int)$yourInputVar;
$s = "select * from Table where id = $x";
mysql_real_escape_string
If you want to pass a string, you can, and should, use mysql_real_escape_string, but this function escapes only those characters that are inside the string. You will still need to add quotes around the string, so:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = $x";
.. will result in the query: select * from Table where id = hello. This is obiously not a valid query, since hello should be in quotes.
Change the query to:
$x = mysql_real_escape_string('hello');
$s = "select * from Table where id = '$x'";
.. and everything works fine. You add the quotes around, and mysql_real_escape_string takes care of special characters inside the string, if any.
Parameters
Another solution is to use parameterized queries. This can by done using MySQLi or PDO. The advantage is that you only tell your database where a variable should be inserted, and the database takes care of the escaping yourself.
It also may add a performance benefit, because these queries could be cached without their parameters, make a more efficient use of the query cache. This doesn't really work yet in current versions of MySQL, though.
You are right that 1 or 1=1; SHOW TABLES will give a syntax error but this will work:
1 or 1=1 --
The -- comments out the rest of the query.
In your case the value is an integer so instead of using mysql_real_escape_string you can use intval.
If you set $my_id_va to:
1 or 1=1; SHOW TABLES --
The -- will comment out the rest of the command, effectively terminating it.
I'm not sure what effect mysql_real_escape_string will have on the query. What you should be doing is parameterized queries.
1. First query somehow secured
$sql = sprintf('SELECT * FROM login WHERE id = %d ORDER BY id DESC', mysql_real_escape_string($my_id_va));
2. Second query somehow secured
$sql = sprintf("SELECT EventActuallyCharged, EventDate FROM tblevent WHERE EventDate BETWEEN '%s' AND '%s' ORDER BY EventDate DESC",
mysql_real_escape_string($start_date),
mysql_real_escape_string($end_date));
Read the docs about sprintf if you don't understand it.
However, as others have said, it would be very very secure if you would use parameterized queries with a class such as PDO or MySQLi.