-1

I'm building a website which uses information passed through a URL to pick out information from a database table, but it was brought to my attention that doing this may cause a SQL Injection. As I thought this was only an issue where you were inserting information into a database, I'm a bit confused as to when, how and where you should protect your code.

Currently I have a url which looks like:

www.website.com/article.php?title=title&id=1

Which is shortened in htaccess to www.website.com/article/title/1

In my article.php page I then have:

<?php
if(isset($_GET["id"])){$url_id = $_GET["id"];}else{
header("Location: $site_url");
exit();
};
?>
<?php
if(isset($_GET["title"])){$url_title = $_GET["title"];}else{
header("Location: $site_url");
exit();
};
?>
<?php
$article_sql = "SELECT ...

I currently use mysqli_real_escape_string to prevent SQL Injection threats, but I'm unsure where to use it here. I'm guessing that adding...

...
<?php
if(isset($_GET["title"])){$url_title = $_GET["title"];}else{
header("Location: $site_url");
exit();
};
?>
<?php
$url_id = mysqli_real_escape_string($url_id); // ADDED
$url_title = mysqli_real_escape_string($url_title); // ADDED
?>
<?php
$article_sql = "SELECT 
...

Should do the trick, but is this correct?

Steve Gee
  • 49
  • 1
  • 8
  • 1
    Everything what you need is in this thread. – S.I. Dec 16 '16 at 11:37
  • 1
    Just for your info, mysqli_real_escape_string has absolutely nothing to do with SQL injections. – Your Common Sense Dec 16 '16 at 11:40
  • @YourCommonSense So why have I been told on so many occasions that it is a solution to Injection threats? – Steve Gee Dec 16 '16 at 11:43
  • http://www.sqlinjection.net/advanced/php/mysql-real-escape-string/ ??? – Steve Gee Dec 16 '16 at 11:45
  • And probably this: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet – S.I. Dec 16 '16 at 11:47
  • Okay @S.I., but is there a solution to the code I provided? I'd like to get this sorted without having to change my coding style too much – Steve Gee Dec 16 '16 at 11:49
  • 1
    In my opinion you'll not be safe until you start to use prepared statements. Just don't inject directly the variable in the query. – S.I. Dec 16 '16 at 11:51
  • @S.I. Any suggestions on how I can do it indirectly? I mean passing variables through a URL is pretty standard practice. How do sites that don't use Prepared statements cope with this issue? – Steve Gee Dec 16 '16 at 11:55
  • *"why have I been told on so many occasions?"* - because there are too many idiots around? Just for clarity, the only trusting source is a manual page and there is not a single mention of whatever injection in the documentation text. – Your Common Sense Dec 16 '16 at 11:57
  • @YourCommonSense Well it seems there are a lot of idiots here on the Stack then. And in that case, is any of the information posted here of any use to anyone? – Steve Gee Dec 16 '16 at 11:58
  • All the suggestions has been posted in the very first comment half a hour ago. Do you *really* think you are the very first person with such a question here? – Your Common Sense Dec 16 '16 at 11:59
  • Seems you're the least helpful person here anyway @YourCommonSense – Steve Gee Dec 16 '16 at 12:02
  • *"it seems there are a lot of idiots here on the Stack then"* - unfortunately, yes. *"is any of the information posted here of any use to anyone"* - in such a vague form - yes, of course. Some information is surely of some use for someone. But you cannot blindly trust to everything posted here as it is posted by fellow users like you. – Your Common Sense Dec 16 '16 at 12:02
  • I am just the least *servile* person here, which is not the same. – Your Common Sense Dec 16 '16 at 12:04

1 Answers1

0

You already use mysqli_ so take advantage of it. Here is simple example based on code you provide:

<?php
 // $mysqli is the connection
$article_sql = $mysqli->prepare("SELECT * FROM table WHERE url_id = ? AND url_title = ?");

$article_sql->bind_param("is", $url_id, $url_title);
$article_sql->execute();

$result = $article_sql->get_result();
while ($row = $result->fetch_array(MYSQLI_NUM)) {
  foreach ($row as $r) {
    print "$r ";
  }
  print "\n";
}
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
S.I.
  • 3,250
  • 12
  • 48
  • 77
  • Thanks. I'm definitely going to look into using this code. Just as a side question - Is it true that for an injection attack to `Drop` one of your tables, it must know the name of the table? If so, wouldn't it be a good solution to just give the table an obscure name? – Steve Gee Dec 16 '16 at 12:12
  • Well, yes... attacker must know what he attack :) But he must find it with injection which you will prevent using this techniques. Check this [cheet sheet](http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet) – S.I. Dec 16 '16 at 12:17
  • Seems the attackers can find a way around everything, lol. As I'm sure they are unfortunately bound to do again, even making prepared statements unsafe in the future :-( - Is there a way to prevent them from Listing Tables and Databases using a universal PHP code that can be placed in a single `include` file? – Steve Gee Dec 16 '16 at 12:23
  • Well you can restrict user what permission to have over mysql database: http://dev.mysql.com/doc/refman/5.7/en/grant.html . And restrict the user to use only certain tables. – S.I. Dec 16 '16 at 12:32
  • Well I've added myself as a user to the database in CPanel, and set permissions, but would this prevent a URL based attack. I was wondering if... As I know my url's will never use a special character, if I could set it so that if a special char existed in any url, I could use a PHP script to automatically redirect to another page to prevent the attacking url from even loading up the targeted page? – Steve Gee Dec 16 '16 at 12:43
  • Everything coming from user side should be triple check, sanitized, escaped, prepared.. etc.. Never trust users :) – S.I. Dec 16 '16 at 12:57
  • What I mean is, nothing legitimate would ever contain a special character, because it's all text titles and id numbers, so if something with a `@` or `"` came through a URL it would almost definitely be something suspicious. So therefore can a script be made to capture the url of every page, and redirect back out if a special character exists? – Steve Gee Dec 16 '16 at 13:03
  • Should be possible to include such a script on each page yes. – S.I. Dec 16 '16 at 13:05
  • And would that be a viable solution in preventing a possible SQL injection? – Steve Gee Dec 16 '16 at 13:08
  • I'm not hundred percent sure but If you use modern techniques you won't be worried about it. – S.I. Dec 16 '16 at 13:14
  • I'll look into using the code you provided, but as the site is live and has content on there already, I'm obviously reluctant to mess around too much with the coding. Thanks again S.I. – Steve Gee Dec 16 '16 at 13:23
  • You can make some test environment on localhost or something. And start slowly to change first critical pages i.e. where user make inputs. – S.I. Dec 16 '16 at 13:27