Hallo!

Ik wou graag enige bruteforce protection op mijn website maken waarbij als je 3 keer foute login hebt gedaan, je 50 minuten niet kan inloggen etc., en ik had het volgende:


<?php
function checkWrongAttempts($ip, $plaats)
{
  $settings = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/../datafile.ini');
  include($_SERVER['DOCUMENT_ROOT'].$settings['path'].'paneel/includes/init.php');
  $datum = strtotime('UTC');

  $searchWrongAttemptsSql = $link->query("SELECT * FROM `".$settings['path']."foutepogingen` WHERE `ip`='".sha1($ip)."' AND `plaats`='".$link->real_escape_string($plaats)."' ORDER BY `datum` DESC");

  if ($searchWrongAttemptsSql && $searchWrongAttemptsSql->num_rows >= 3)
  {
    $wrongAttempt = $searchWrongAttemptsSql->fetch_assoc();

    if ($datum <= strtotime('+5 minutes', $wrongAttempt['datum']))
    {
      return false;
    }
  }
}

function insertWrongAttempt($ip, $plaats)
{
  $settings = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/../datafile.ini');
  include($_SERVER['DOCUMENT_ROOT'].$settings['path'].'paneel/includes/init.php');
  $datum = strtotime('UTC');

  $insertWrongAttempt = $link->query("INSERT INTO `".$settings['prefix']."foutepogingen` (`ip`, `plaats`, `datum`) VALUES ('".sha1($ip)."', '".$link->real_escape_string($plaats)."', '".$link->real_escape_string($datum)."')");

  if ($insertWrongAttempt)
  {
    return true;
  }
}

function login($gebruikersnaam, $wachtwoord)
{
  $settings = parse_ini_file($_SERVER['DOCUMENT_ROOT'].'/../datafile.ini');
  include($_SERVER['DOCUMENT_ROOT'].$settings['path'].'paneel/includes/init.php');
  $datum = strtotime('UTC');

  if (checkWrongAttempts(getIp(), 'index') != true)
  {
    $searchUserSql = $link->query("SELECT `id`, `wachtwoord` FROM `leden` WHERE `gebruikersnaam`='".$link->real_escape_string($gebruikersnaam)."'");

    if ($searchUserSql && $searchUserSql->num_rows === 1)
    {
      $userDetails = $searchUserSql->fetch_assoc();

      if (!password_verify($wachtwoord, $userDetails['wachtwoord']))
      {
        if (insertWrongAttempt(getIp(), 'index') === true)
        {
          return false;
        }
      }
    }
    else
    {
      if (insertWrongAttempt(getIp(), 'index') === true)
      {
        return false;
      }
    }
  }
  else
  {
    return false;
  }
}
?>

Maar hij blijft hierbij het gehele script uitvoeren, terwijl ik al 25 keer foute login heb gedaan.. Zelf denk ik dat het probleem bij het checken ligt, maar ik dit lukt mij niet om te debuggen Alvast bedankt voor de hulp!
Voor global settings gebruik ik liever constanten omdat die efficiënter met geheugen omgaan en overal beschikbaar zijn. Dan ben je van global af en heb je er verder geen omkijken meer naar: de configuratieconstanten zijn er gewoon overal en altijd. Dat kun je uiteraard ook implementeren met een parse_ini_file().
Zou dit vooral verder bouwen omdat je er veel van kan leren!

Maar praktisch is het niet en je zal eerder de normale gebruiker er mee tot last zijn dan dat je 'hackers' er mee buiten sluit.
Paar redenen:
1) De check is op IP. Dus als meerdere mensen in een bedrijf een foute inlogpogingen doen zijn ze samen de sjaak, daarnaast zal een 'hacker' verkeer vanuit verschillende ip's sturen. Denk aan een botnet of iets van Amazon waar je snel veel kleine scripts kan draaien, en als we naar ipv6 gaan kijken dan zijn de mogelijkheden nog groter. Daarbij komt bij ipv6 dat verschillende notaties heeft voor 1 ipadres.

2) Je script is Timing attack gevoelig. Want als een gebruiker niet wordt gevonden dan krijg je meteen een return, terwijl hij anders wel een password_verify doet. In het verschil van de response tijden weet de 'hacker' in elk geval of een gebruikersnaam wel of niet bestaat.
De password_verify functis is wel timing attack proof.

En vraag aan je hoster of ze een NTP sync willen aanzetten op je server ;)
Bedankt voor de reacties! Ik ben nu van plan alle dingen toe te passen, en te beginnen met OOP. Dan gelijk daar een vraag over, ik had met OOP een mysqli connect gemaakt maar nu ik wil ik buiten de Class om, de variable $mysqli aanroepen. Ik heb het opgezocht op google maar ik (wat ik zocht) heb het niet kunnen vinden.

mijn code:

<?php
class database extends mysqli {
    public $mysqli;

    public function __construct() {
        $this->mysqli = new mysqli('localhost', '***', '***', '***');

        if (!$this->mysqli) {
            die('Fout met verbinding');
        }
        else
        {
          return $this->mysqli;
        }
    }
}

// ANDER BESTAND
include($_SERVER['DOCUMENT_ROOT'].'/paneel/includes/classes/database.class.php');

$mysqli = new database();

echo $mysqli->real_escape_string('`test`');
?>


Ik hoop dat iemand even mij hieruit kan helpen! (real_escape_string() gebruikte ik even om te testen)
Extenden is wel hartstikke leuk, maar je vindt nu wel het wiel opnieuw uit.
Normaal kan je met
<?php $mysqli = new mysqli("localhost", "user", "password", "mijnwebsite"); ?>
connecten met je database via MySQLi.
Harstikke bedankt! ik heb nu dit om het te echoen:
echo $database->mysqli->real_escape_string('`d`');
en heb extends mysqli weg gehaald en return etc. ook.
$database bestaat niet eens, tenzij je die variabele waar je de class initieert hebt hernoemd.
Nu stuit ik alleen op het volgende probleem, hij showt nu geen error als de gegevens fout zijn.. Waar zit nu het probleem?


<?php
class database
{
    public $mysqli;

    public function __construct()
    {
        $this->mysqli = new mysqli("localhost", "****", "*****", "******");

        if (!$this->mysqli)
        {
             die('Fout met verbinding');
        }
    }
}
?>






include($_SERVER['DOCUMENT_ROOT'].'/paneel/includes/classes/database.class.php');

$database = new database();


[size=xsmall]Toevoeging op 17/03/2017 19:47:08:[/size]

Update^^
Waarom maak je het jezelf zo moeilijk...
Recht uit de manual:

<?php

class database  extends mysqli {
    public function __construct($host, $user, $pass, $db) {
        parent::__construct($host, $user, $pass, $db);

        if (mysqli_connect_error()) {
            die('Connect Error (' . mysqli_connect_errno() . ') '
                    . mysqli_connect_error());
        }
    }
}

$db = new database('localhost', 'my_user', 'my_password', 'my_db');

echo 'Success... ' . $db->host_info . "\n";

$db->close();
?>

Ik zou hier alleen wel de OO varianten gebruiken en binnen de class ook niet terugvallen op de procedurele varianten. Dit kan tot onvoorspelbaar gedrag en/of incompatibiliteit tussen PHP versies leiden:

<?php

class database extends mysqli {
public function __construct($host, $user, $pass, $db) {
parent::__construct($host, $user, $pass, $db);

if ($this->connect_error()) {
die('Connect Error (' . $this->connect_errno() . ') '
. $this->connect_error());
}
}
}

$db = new database('localhost', 'my_user', 'my_password', 'my_db');

echo 'Success... ' . $db->host_info . "\n";

$db->close();
?>
Maar met deze class kan ik toch niet met een andere class $db gebruiken?

[size=xsmall]Toevoeging op 18/03/2017 07:18:47:[/size]

Of moet ik dan $db meegeven met die class?

$class = new class($db);

Reageren