I have a list of customer in a database with a column name is postcode
At the moment my search runs the SQL
SELECT *
FROM customer
WHERE postcode LIKE '%".$_POST["search term"]."%'
Which works fine but if a row in the databse has the postcode of (SS1 1AB) and someone types in (SS11AB) how can I make it find the correct row?
Basically I want to be Able to search every single combination etc
Only way you could probably do is to with either a regex or white space replacement.
PHP: $term = str_replace(' ', '', $_POST["search term"]);
Query: Select * from customer where REPLACE(postcode, ' ', '') LIKE '%".$term."%'
Having said that however, you'd be far better off formatting the data on insert, because as your table grows, that lookup will become more and more expensive to run. One of my pet hates is websites that use a post code as authentication or verification data, then force you to use a particular notation. I've seen people hypenate the space in their post code before too, so you should always normalise the format before inserting it, or enforce a format (i prefer the former option, but the latter is easier).
Also your query is vulnerable to injection exploits. But thats another topic
Besides the SQL injection, Which you should sort out.
The column should be SS11AB, then query on str_replace(" ", "", $_POST['search term'])
you can make your column look like that by
update customer set postcode = replace(postcode, " " , "")
That will remove all spaces in the column, Then you just need to query without the space with the function above
Mysql allows regular expression matches which would be one way. What I would do though is standardize on a single correct representation in the database - and validate input against that. This would avoid SQL injection issues and make matching easier. It would also allow you to filter out typos when data is entered into the database.
Related
My question of to day is. Do i need to escape PDO in my script?
$columns = implode(", ",$column);
$query = ''.$query.' '.$columns.' FROM '.$table.'';
$dbh_query = $dbh->prepare($query);
$dbh_query->execute();
$dbh_querys = $dbh_query->fetchAll();
return $dbh_querys;
The whole script can be found at.
https://github.com/joshuahiwat/crud/blob/master/control/query_connector.class.php
Can someone explain why do i need a escape at this time or why not.
I like to hear from you, thanks a lot!
The parts of your query that are dynamic are the table name and column names. You can't use bind functions for these parts of the query. Bind functions can be used only for the parts of the query that would otherwise be a simple value in an SQL query. Like a numeric constant, or a quoted string or quoted date literal.
To avoid SQL injection from dynamic table names or column names, you have the following choices:
Use values that are predefined in your class, or otherwise certain to be safe. Don't use external content from users or any other source.
Use escaping. Note that the function PDO::quote() doesn't do the kind of escaping you need for table names or column names.
Create a "allowlist" of known table names and the column names for the respective table, and compare the dynamic input to the allowlist. If it doesn't match the allowlist, raise an error.
First of all you need to understand that the word you are using - "escape" - is meaningless.
What you probably mean is "to make your query safe from SQL injection". But, unfortunately, there is no such magic "escaping" that will make some abstract query safe.
The traditional query building assumes that all the query parts beside data values are hard-coded, while data values are bound via placeholders, like this:
$query = 'SELECT col1, col2 FROM some_table WHERE id = ?';
$stmt = $dbh->prepare($query);
$stmt->execute([$id]);
$row = $stmt->fetch();
This kind of a query considered safe.
In your case of a dynamically constructed query, every part is potentially vulnerable.
And here it is very important to understand that a burden of sanitizing all the query parts is entirely on this function. You cannot dismiss the danger simply claiming that your data is coming from the trusted source. That's a slippery ground because people often have no idea whether their source is trusted or not.
So, if take your question as "Do I have to protect this code from SQL injection", than the answer is - YES, YOU HAVE.
In the meantime you are protecting only a small part of your query - the data values. So you still have to protect (this term is much better than "escape") all other parts.
On a side note, your code is connecting to database every time it runs a query, which is highly inefficient and makes it impossible to use some database features.
I have a movie database website and I'm having a small issue with the search.
Lets say that the movie name saved in the database is
Going Clear: Scientology and the Prison of Belief
As you can see there a : in the title.
When my users search for Going Clear Scientology and the Prison of Belief they get no results, same if the movie title has ', here is my search query:
SELECT * FROM movie WHERE title LIKE '%$search%'
How can I fix that?
Keep two things in mind when trying to insert into the database using php.
First, when you are inserting into the database your data, say for example the movie name here "Going Clear: Scientology and the Prison of Belief", trim off the extra strings like : . This well help you later on.
Second, similar to the first one, when you are taking an input from the user sanitize it. There might be strings like ',$,\,? etc which are not relevant. After you have done that you can go for a query search in the DB.
I guess your code here is okay.
select * from movie where title like 'Going%';
The above query works for me when I check it in my DB. See if your search variable is initializing properly.
You need to escapes special characters in a string for use in an SQL statement. Always store these type of value into database after escaping special character and also pass your search term into query after escaping special character.
For this you have to use
mysql_real_escape_string()
Eg:
$search = "Going Clear: Scientology and the Prison of Belief";
$search = mysql_real_escape_string($search);
$query= "SELECT * FROM movie WHERE title LIKE '%$search%'";
You can read here
http://php.net/manual/en/function.mysql-real-escape-string.php
I am building a web app which relies heavily on a database. Here is an example of the type of query I use a lot:
CREATE TABLE item$userenteredname$username
Basically each time a create a new item, there is a table which stores info for every time something is added. So I need the table names to remain the same.
I recently spent quite a while updating my code to use PDO. I understand how to prepare statements and bind values, but you can't do this with table names. Haven't been able to find a proper answer to my question, which to clarify is...
How can I sanitise user input against sql injection when I can't use prepare's or mysql_real_escape_string because the variable is in a table name?
My strategy for this use case would be to strip out non-alphanumeric characters.
$usereneteredname = preg_replace('/[^0-9a-zA-Z_]/', '', $usereneteredname);
$username = preg_replace('/[^0-9a-zA-Z_]/', '', $username);
// then "CREATE TABLE item$userenteredname$username"
This strategy is called whitelisting. That preg_replace call will replace anything that isn't 0-9a-zA-Z_.
Further considerations:
You may also wish to validate the string lengths after the output, and make sure you are operating on a string not an array.
My website has been attacked by SQL injection. Hacker used following in URL query string:
abc-buy.php?sid=144760&op=-3+union+all+select+1,2,3,4,5,6,7,load_file%28%22/etc/passwd%22%29
How can I avoid these kind of attacks?
Always validate untrusted input.
All input is untrusted.
How to validate the input depends on what the input is, but in this case, it's probably pretty obvious that -3+union+all+select+1,2,3,4,5,6,7,load_file%28%22/etc/passwd%22%29 is not valid input for op (whatever op is).
So in this case, it would probably be as simple as adding some code to check that the value for "op" matches one of the expected values.
if ( op != "or" and op != "and" and op != "monkeys" ) {
raise_exception("Invalid op specified! Go away you trickster!");
}
You should do this for every value you receive from users. Although it's trickier for free-form fields, like email addresses or comments, etc. But still, make sure they are valid data for the field they're matching--and escape any free-form fields before you insert them into the database. That can make the difference between:
INSERT INTO users (username,fullname) VALUES ("bob","Robert"); DROP TABLE users; SELECT 1 WHERE "x"="");
and:
INSERT INTO users(username,fullname) VALUES ("bob",Robert\"\)\; DROP TABLE users\; SELECT 1 WHERE \"x\"=\"");
The functional difference being that with the first (un-escaped) version, the DROP TABLE users; command executes, and with the second, you simply insert a new user with a really long, silly name of Robert"); DROP TABLE users; SELECT 1 WHERE "x"=".
Switch to PDO and use prepared statements with placeholders for everything.
As most of the answers says, you should escape everything you save into your database (field placeholders).
But I have recently discovered that you should escape all place holders in your query, because without it:
Placeholders for the "FROM clause" could allow hackers to access any table's data.
Placeholders for the "WHERE clause", could allow hackers to any row in the current table. That means a hacker could access your app as any user in your database when trying to log in.
use zend framework. that will by default prevent it
http://framework.zend.com/
or everything you put in the database you escape.
http://php.net/manual/en/function.mysql-real-escape-string.php
My database has name records that occasionally contain apostrophes, such as Joe's Bar and I've just coded a query script in PHP that grabs that field and sticks it into a select statement with the usual $query = "SELECT address FROM restaurants WHERE name='$name'"; and the apostrophe in some of the restaurant names derails the Love Train.
How do I keep this from happening?
Snide answer - Use the same technique you used when you inserted them INTO the database via PHP.
Rebuttal - I was having the same problem then and cheated and entered the troublesome ones directly using PHPMyAdmin but this can't be ignored any longer.
Thank you for taking the time to answer this during the holidays.
You have to $name = mysql_real_escape_string($name); before that line.
You might also want to read up on SQL Injections, since your inputs are clearly unsanitized.
Have a look here
How can I use an apostrophe (') in a
query string?
mysql_real_escape_string
PHP mysql_real_escape_string