0

Here's my current code:

<?php 
$key = $_REQUEST['key'];
$url = $_REQUEST['url'];

include_once '../../dbconnect.php';

$query = $conn->query("SELECT * FROM members WHERE apikey='$key' && status='Active'");
$userRow=$query->fetch_array();
$conn->close();

/// Verify the URL starts with http:// or https://
if (0 === strpos($url, 'http://') || 0 === strpos($url, 'https://')) {
$url = $url;
} else {
$url = "http://$url";
}

/// Verify the key is 32 characters
if (!preg_match('/[^A-Za-z0-9]/', $key) && (strlen($key) == 32)) {

/// Verify the URL isn't malicious
if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
    die('Error:  Invalid URL');
} else {

if ($userRow['status'] === 'Active') {

function generateRandomString($length = 8) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

$redirect = generateRandomString();

$addshort = $conn->query("INSERT INTO short_".$redirect[0]." (redirect, apikey, url) VALUES ('".$redirect."','".$key."','".$url."')");

if ($conn->query($addshort) === TRUE) {
echo "added correctly";
} else {
echo "there was an error";
}

$conn->close();

} else {
echo "Error:  Account Not Active";
}

}

} else {
die('Error:  Invalid API Key');
}
?>

Here's the error_log:

[18-Oct-2016 12:21:31 America/New_York] PHP Warning:  mysqli::query(): Couldn't fetch mysqli in /home/username/public_html/subdomains/url/index.php on line 40
[18-Oct-2016 12:21:31 America/New_York] PHP Warning:  mysqli::query(): Empty query in /home/username/public_html/subdomains/url/index.php on line 42
[18-Oct-2016 12:21:31 America/New_York] PHP Warning:  mysqli::close(): Couldn't fetch mysqli in /home/username/public_html/subdomains/url/index.php on line 48

You can see on the 7th line where I connect to the database for the first time:

$query = $conn->query("SELECT * FROM members WHERE apikey='$key' && status='Active'");

And that line is working. However, the second time I'm connecting to do an INSERT, I'm getting the above errors:

$addshort = $conn->query("INSERT INTO short_".$redirect[0]." (redirect, apikey, url) VALUES ('".$redirect."','".$key."','".$url."')");

Is there something I'm missing from just staring at this code for too long?

James Sandzalone
  • 31
  • 1
  • 1
  • 4

2 Answers2

6

Your connection has been closed, after execution of first SELECT Statement, it means connection closed to early:

$conn->close();

You need to use close() after your all queries or re build connection. ist one is the better option.

You are getting user input $_REQUEST['key'], it means your query is open for SQL injection, this will help you to understand how can you prevent your code with SQL injection: How can I prevent SQL injection in PHP?

Community
  • 1
  • 1
devpro
  • 16,184
  • 3
  • 27
  • 38
  • That fixed it perfectly! I'll accept in 4 minutes, once SO lets me. Any idea why `echo "there was an error";` is running instead of `echo "added correctly";`? The rows are being added to the database correctly, so I'm not sure why the error is occurring... – James Sandzalone Oct 18 '16 at 16:37
  • @JamesSandzalone:this is very interesting, for this error you need to check MArkB answer.. :) – devpro Oct 18 '16 at 16:39
  • James, @marc-b already mentioned, about this problem, :) – devpro Oct 18 '16 at 16:40
  • @JamesSandzalone: dont fogot SQL injection veryi very important... – devpro Oct 18 '16 at 16:40
-1

This:

$addshort = $conn->query("INSERT ...')");
^^^^^^^
if ($conn->query($addshort) === TRUE) {
                   ^^^^^

$addshort is your query result/handle/object, which you then try to EXECUTE AGAIN, which doesn't work. query() expects an SQL string, and you're passing in an object.

And on top of that, you're vulnerable to sql injection attacks.

Marc B
  • 356,200
  • 43
  • 426
  • 500