1

I'm trying to test if for existing URLs in a user form field and need a little guidance. I am a placement student and told the place I'm working for I'm not great with PHP and here I am working with PHP.

This is looking like the best I've tried thus far:

    $file = [url];
    $file_headers = @get_headers($file);
    if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
         $exists = false;
    }
    else {
         $exists = true;
    }


    if ($_POST[code] == '') {
        header("Location: index.php"); 
        exit;
    }
    else if ($exists == false){
        print("URL is not valid");

    } 
    else {

        $query = "INSERT INTO redirects
        SET code = '$_POST[code]',
        url  = '$_POST[url]',
        requester = '$_POST[requester]',
        date = '$_POST[iw_start]',
        webperson = '$_POST[webperson]',
        active = '$_POST[active]'";

        mysql_query ($query, $link);

    }

?>

Am I on the right path?

*BEFORE YOU ANSWER: THE SQL QUERY IS NOT MINE. PLEASE KEEP THAT IN MIND.

Bee
  • 61
  • 6
  • If you're trying to get hacked, you're absolutely on the right path. Your query is completely vulnerable to SQL injection. – Fosco Jun 01 '11 at 13:56
  • First, I'd check whether the hostname actually has an IP address - e.g. http://ohjoawgioaerihuiouiwe.example.com/ is an URL, yet the domain doesn't exist. Second, you could get various other response codes - e.g. 410 Gone, or 500 Server Error. – Piskvor left the building Jun 01 '11 at 13:57
  • You also haven't told us what the problem is. – Fosco Jun 01 '11 at 13:59
  • They don't have error reporting here and it is driving me nuts. I've tried adding this to the top of the scripts: ini_set('error_reporting', E_ALL); but it isn't working. – Bee Jun 01 '11 at 14:03
  • I always just get 500 Server Error. – Bee Jun 01 '11 at 14:03

4 Answers4

0

You should use CURL to test the existing url.

From How can one check to see if a remote file exists using PHP?:

$ch = curl_init($_POST[url]);

curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// $retcode > 400 -> not found, $retcode = 200, found.
curl_close($ch);

Then, for your database, you should add an unique constraint in order to avoid adding duplicate urls.

Now, as mentionned in the comments, what you did is vulnerable to SQL Injection. A user can post malicious data through the form and, for example, delete all the entry in your database. You must secure the input data (POST/GET) that you receive from your users, always.

Community
  • 1
  • 1
Cyril N.
  • 38,875
  • 36
  • 142
  • 243
  • but what if I don't know the URL being input? – Bee Jun 01 '11 at 13:58
  • I'll have to take that up with the code guy here... It's all his, he has just given me a few side projects for placement. It's unlikely that someone would try and put malicious data as this is a admin area. Although it's likely that the SQL is like that across most of the site. – Bee Jun 01 '11 at 14:08
  • It depends on who is accessing the admin area. If it's just the boss, why not, but if it's some employees, just one unhappy one could arm your database :) – Cyril N. Jun 01 '11 at 14:09
0

If you read the manual, get_headers returns false on failure so I would also check that before checking the HTTP status code.

Also you haven't escaped any of your variables in your SQL query.

fire
  • 21,383
  • 17
  • 79
  • 114
  • the SQL code belongs the guy here who does all the coding. It works, I have modified it only to try and check the url. – Bee Jun 01 '11 at 13:59
0

Try replacing your query with this:

$query = "INSERT INTO redirects
        SET code = '" . mysql_real_escape_string($_POST['code']) . "',
        url  = '" . mysql_real_escape_string($_POST['url']) . "',
        requester = '" . mysql_real_escape_string($_POST['requester']) . "',
        date = '" . mysql_real_escape_string($_POST['iw_start']) . "',
        webperson = '" . mysql_real_escape_string($_POST['webperson']) . "',
        active = '" . mysql_real_escape_string($_POST['active']) . "'";
Fosco
  • 38,138
  • 7
  • 87
  • 101
0

Maybe try using a regex pattern to determine if it is a valid URL first?

$valid = "/^(http://|https://)(([a-z0-9]([-a-z0-9]*[a-z0-9]+)?){1,63}\.)+[a-z]{2,6}/";

if (preg_match($valid, $file)) { echo "OK" };
Paul
  • 1,527
  • 2
  • 16
  • 24