Is this code safe from injection, xss and whole other attacks or no ?

The below code is for search box :

$output = '';
$string = $_POST['query'];
$search = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
$stmt = $con->prepare(" SELECT * FROM topics_categories WHERE cat_name LIKE 
? LIMIT 3");
$result = $stmt->get_result();
while($row = mysqli_fetch_array($result))
$output .= '
<a href="topics.php?cat_id='.$row['cat_id'] .'">'.$row['cat_name'].'</a>';
echo $output;
  • 1
    \$\begingroup\$ I am guessing this code doesn't really work the way you expect it to. Your LIKE clause is not really doing a LIKE search. And I have no idea as to why you would be using htmlspecialchars() the way you are. \$\endgroup\$ – Mike Brant Jun 6 '17 at 22:44
  • \$\begingroup\$ it's work i just want to know it's safe or no , how should i using htmlspecialchars() ? \$\endgroup\$ – Beginner Jun 6 '17 at 22:46

Searches are customarily done using HTTP GET requests rather than POST requests, since they do not modify information on the server.

You are not applying escaping correctly.

  • Why are you performing HTML escaping here?

    $search = htmlspecialchars($string, ENT_QUOTES, 'UTF-8');

    The data in the cat_name column should not be HTML-escaped, so it would be inappropriate to HTML-escape the search term.

  • You are neglecting to perform HTML escaping on $row['cat_name']. When you are embedding text in HTML, you need to escape it using htmlspecialchars(). Otherwise, if the cat_name happens to contain a string that looks like an HTML tag, the page could break.

Furthermore, I wouldn't bother constructing $output. It would be simpler to echo each line of output as it comes. That gets rid of two lines of clutter: $output = '' and echo $output. (There might be a slight difference in performance, but I wouldn't worry about it.)

  • \$\begingroup\$ The lines before the link are safe ? because i didn't escape url yet . at the first i want to make sure the $_POST['query'] and sql query are safe then if they safe i want know how to make the url safe too \$\endgroup\$ – Beginner Jun 7 '17 at 0:15
  • \$\begingroup\$ Strings that should be escaped need to be escaped for a reason. Conversely, strings that don't need to be escaped should not be escaped. Don't randomly sprinkle escaping functions here and there "just in case" — you must understand why you are applying the escape. In the case of your SQL query, $stmt->bind_param(…) will apply the SQL string escaping for you. Any escaping that you manually apply to $string will just corrupt the query string. \$\endgroup\$ – 200_success Jun 7 '17 at 0:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.