Skip to content

Commit

Permalink
Made api call limiter (brute force mitigation system)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ziga committed May 16, 2021
1 parent 76bd745 commit 3ebaac0
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 62 deletions.
35 changes: 35 additions & 0 deletions php/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,41 @@ public static function getUserIpAddress() : string {
return $_SERVER['REMOTE_ADDR'];
}

public static function userSentToManyRequests(string $action) : bool{
$timer = 0;

switch($action){
case 'createAccount':
$timer = Settings::$limiter_createAccount;
break;
case 'getPasswords':
$timer = Settings::$limiter_getPasswords;
break;
case 'savePassword':
$timer = Settings::$limiter_savePassword;
break;
case 'editPassword':
$timer = Settings::$limiter_editPassword;
break;
case 'deletePassword':
$timer = Settings::$limiter_deletePassword;
break;
case 'deleteAccount':
$timer = Settings::$limiter_deleteAccount;
break;
}

$ips_array = json_decode(file_get_contents('ips.json'), true);

if(!empty($ips_array[$action][self::getUserIpAddress()])){
if((time() - $ips_array[$action][self::getUserIpAddress()]) < $timer) return true;
}

$ips_array[$action][self::getUserIpAddress()] = time();
file_put_contents('ips.json', json_encode($ips_array));
return false;
}

public static function isPasswordCorrect(string $username, string $password) : int {
try{
$username = strtolower($username);
Expand Down
3 changes: 2 additions & 1 deletion php/Errors.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ class Errors{
"11" => "Something went wrong while deleting data from database!",
"12" => "Username must be between 6 and 30 characters long and can only contains letters, numbers and dots!",
"13" => "Something went wrong while updating data in database!",
"400" => "Action was not provided in POST!",
"400" => "Action was not provided in GET!",
"401" => "Action is invalid!",
"403" => "You didn't provide all required values in POST.",
"404" => "Can't connect into API.",
"429" => "Too Many Requests",
"505" => "Something went wrong while connecting to database!",
"999" => "You don't have permission to use this endpoint."
);
Expand Down
24 changes: 13 additions & 11 deletions php/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ class Settings{
Please do not touch those values if you are using docker-compose.
*/
static string $mysql_host = "passky-mysql";
static string $mysql_database = "passky";
static string $mysql_username = "passky";
static string $mysql_password = "uDWjSd8wB2HRBHei489o";

public static string $mysql_host = "passky-mysql";
public static string $mysql_database = "passky";
public static string $mysql_username = "passky";
public static string $mysql_password = "uDWjSd8wB2HRBHei489o";

/*
Expand All @@ -21,13 +22,14 @@ class Settings{
In this section you can set how many seconds users needs to wait until they can make new request to API for spacific action.
*/
static int $limiter_login = 3;
static int $limiter_getPasswords = 3;
static int $limiter_savePassword = 2;
static int $limiter_editPassword = 2;
static int $limiter_deletePassword = 2;
static int $limiter_createAccount = 1800; // Time will be reset if user delete his account.
static int $limiter_deleteAccount = 1800; // Time will be reset if account has been deleted successfully.

public static int $limiter_getPasswords = 3;
public static int $limiter_savePassword = 2;
public static int $limiter_editPassword = 2;
public static int $limiter_deletePassword = 2;
public static int $limiter_createAccount = 30;
public static int $limiter_deleteAccount = 30;

}

?>
138 changes: 88 additions & 50 deletions php/index.php
Original file line number Diff line number Diff line change
@@ -1,56 +1,94 @@
<?php
require_once "Display.php";
require_once "Database.php";
require_once "Settings.php";

if(!empty($_GET['action'])){
switch($_GET['action']){
case "createAccount":
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_POST['email']) && isset($_SERVER['PHP_AUTH_PW'])){
echo Database::createAccount($_SERVER['PHP_AUTH_USER'], $_POST['email'], $_SERVER['PHP_AUTH_PW']);
}else{
echo Display::json(403);
}
break;
case "getPasswords":
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])){
echo Database::getPasswords($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
}else{
echo Display::json(403);
}
break;
case "savePassword":
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && isset($_POST['website']) && isset($_POST['username']) && isset($_POST['password'])){
echo Database::savePassword($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $_POST['website'], $_POST['username'], $_POST['password']);
}else{
echo Display::json(403);
}
break;
case "editPassword":
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && isset($_POST['password_id']) && isset($_POST['website']) && isset($_POST['username']) && isset($_POST['password'])){
echo Database::editPassword($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $_POST['password_id'], $_POST['website'], $_POST['username'], $_POST['password']);
}else{
echo Display::json(403);
}
break;
case "deletePassword":
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && isset($_POST['password_id'])){
echo Database::deletePassword($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $_POST['password_id']);
}else{
echo Display::json(403);
}
break;
case "deleteAccount":
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])){
echo Database::deleteAccount($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
}else{
echo Display::json(403);
}
break;
default:
echo Display::json(401);
break;
}
}else{
echo Display::json(400);
if(empty($_GET['action'])){
echo Display::json(400);
return;
}

switch($_GET['action']){
case "createAccount":
if(Database::userSentToManyRequests('createAccount')){
echo Display::json(429);
return;
}

if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_POST['email']) || !isset($_SERVER['PHP_AUTH_PW'])){
echo Display::json(403);
return;
}

echo Database::createAccount($_SERVER['PHP_AUTH_USER'], $_POST['email'], $_SERVER['PHP_AUTH_PW']);
break;
case "getPasswords":
if(Database::userSentToManyRequests('getPasswords')){
echo Display::json(429);
return;
}

if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])){
echo Display::json(403);
return;
}

echo Database::getPasswords($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
break;
case "savePassword":
if(Database::userSentToManyRequests('savePassword')){
echo Display::json(429);
return;
}

if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || !isset($_POST['website']) || !isset($_POST['username']) || !isset($_POST['password'])){
echo Display::json(403);
return;
}

echo Database::savePassword($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $_POST['website'], $_POST['username'], $_POST['password']);
break;
case "editPassword":
if(Database::userSentToManyRequests('editPassword')){
echo Display::json(429);
return;
}

if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || !isset($_POST['password_id']) || !isset($_POST['website']) || !isset($_POST['username']) || !isset($_POST['password'])){
echo Display::json(403);
return;
}

echo Database::editPassword($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $_POST['password_id'], $_POST['website'], $_POST['username'], $_POST['password']);
break;
case "deletePassword":
if(Database::userSentToManyRequests('deletePassword')){
echo Display::json(429);
return;
}

if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) || !isset($_POST['password_id'])){
echo Display::json(403);
return;
}

echo Database::deletePassword($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'], $_POST['password_id']);
break;
case "deleteAccount":
if(Database::userSentToManyRequests('deleteAccount')){
echo Display::json(429);
return;
}

if(!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])){
echo Display::json(403);
return;
}

echo Database::deleteAccount($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
break;
default:
echo Display::json(401);
break;
}
?>
8 changes: 8 additions & 0 deletions php/ips.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"getPasswords": {},
"savePassword": {},
"editPassword": {},
"deletePassword": {},
"createAccount": {},
"deleteAccount": {}
}

0 comments on commit 3ebaac0

Please sign in to comment.