diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 9ccc914564..07e021a4b7 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -9,7 +9,7 @@ use Utopia\Abuse\Adapters\TimeLimit; use Utopia\Storage\Device\Local; use Utopia\Storage\Storage; -App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes) { +App::init(function ($utopia, $request, $response, $project, $user, $register, $events, $audits, $usage, $deletes, $db) { /** @var Utopia\App $utopia */ /** @var Utopia\Swoole\Request $request */ /** @var Appwrite\Utopia\Response $response */ @@ -21,6 +21,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e /** @var Appwrite\Event\Event $usage */ /** @var Appwrite\Event\Event $deletes */ /** @var Appwrite\Event\Event $functions */ + /** @var PDO $db */ Storage::setDevice('files', new Local(APP_STORAGE_UPLOADS.'/app-'.$project->getId())); Storage::setDevice('functions', new Local(APP_STORAGE_FUNCTIONS.'/app-'.$project->getId())); @@ -31,47 +32,47 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e throw new Exception('Missing or unknown project ID', 400); } - // /* - // * Abuse Check - // */ - // $timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use ($register) { - // return $register->get('db'); - // }); - // $timeLimit->setNamespace('app_'.$project->getId()); - // $timeLimit - // ->setParam('{userId}', $user->getId()) - // ->setParam('{userAgent}', $request->getUserAgent('')) - // ->setParam('{ip}', $request->getIP()) - // ->setParam('{url}', $request->getHostname().$route->getURL()) - // ; + /* + * Abuse Check + */ + $timeLimit = new TimeLimit($route->getLabel('abuse-key', 'url:{url},ip:{ip}'), $route->getLabel('abuse-limit', 0), $route->getLabel('abuse-time', 3600), function () use (&$db) { + return $db; + }); + $timeLimit->setNamespace('app_'.$project->getId()); + $timeLimit + ->setParam('{userId}', $user->getId()) + ->setParam('{userAgent}', $request->getUserAgent('')) + ->setParam('{ip}', $request->getIP()) + ->setParam('{url}', $request->getHostname().$route->getURL()) + ; - // //TODO make sure we get array here + //TODO make sure we get array here - // foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys - // if(!empty($value)) { - // $timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value); - // } - // } + foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys + if(!empty($value)) { + $timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value); + } + } - // $abuse = new Abuse($timeLimit); + $abuse = new Abuse($timeLimit); - // if ($timeLimit->limit()) { - // $response - // ->addHeader('X-RateLimit-Limit', $timeLimit->limit()) - // ->addHeader('X-RateLimit-Remaining', $timeLimit->remaining()) - // ->addHeader('X-RateLimit-Reset', $timeLimit->time() + $route->getLabel('abuse-time', 3600)) - // ; - // } + if ($timeLimit->limit()) { + $response + ->addHeader('X-RateLimit-Limit', $timeLimit->limit()) + ->addHeader('X-RateLimit-Remaining', $timeLimit->remaining()) + ->addHeader('X-RateLimit-Reset', $timeLimit->time() + $route->getLabel('abuse-time', 3600)) + ; + } - // $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles); - // $isAppUser = Auth::isAppUser(Authorization::$roles); + $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles); + $isAppUser = Auth::isAppUser(Authorization::$roles); - // if (($abuse->check() // Route is rate-limited - // && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') // Abuse is not diabled - // && (!$isAppUser && !$isPrivilegedUser)) // User is not an admin or API key - // { - // throw new Exception('Too many requests', 429); - // } + if (($abuse->check() // Route is rate-limited + && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled') // Abuse is not diabled + && (!$isAppUser && !$isPrivilegedUser)) // User is not an admin or API key + { + throw new Exception('Too many requests', 429); + } /* * Background Jobs @@ -111,7 +112,7 @@ App::init(function ($utopia, $request, $response, $project, $user, $register, $e ->setParam('projectId', $project->getId()) ; -}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes'], 'api'); +}, ['utopia', 'request', 'response', 'project', 'user', 'register', 'events', 'audits', 'usage', 'deletes', 'db'], 'api'); App::init(function ($utopia, $request, $response, $project, $user) { /** @var Utopia\App $utopia */ diff --git a/composer.lock b/composer.lock index b0f8743264..22f89efb6e 100644 --- a/composer.lock +++ b/composer.lock @@ -1324,16 +1324,16 @@ }, { "name": "utopia-php/abuse", - "version": "0.4.1", + "version": "0.4.2", "source": { "type": "git", "url": "https://github.com/utopia-php/abuse.git", - "reference": "8b7973aae4b02489bd22ffea45b985608f13b6d9" + "reference": "286b52209818e5033573e6441d65adbc48a6f715" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/abuse/zipball/8b7973aae4b02489bd22ffea45b985608f13b6d9", - "reference": "8b7973aae4b02489bd22ffea45b985608f13b6d9", + "url": "https://api.github.com/repos/utopia-php/abuse/zipball/286b52209818e5033573e6441d65adbc48a6f715", + "reference": "286b52209818e5033573e6441d65adbc48a6f715", "shasum": "" }, "require": { @@ -1370,9 +1370,9 @@ ], "support": { "issues": "https://github.com/utopia-php/abuse/issues", - "source": "https://github.com/utopia-php/abuse/tree/0.4.1" + "source": "https://github.com/utopia-php/abuse/tree/0.4.2" }, - "time": "2021-06-05T14:31:33+00:00" + "time": "2021-06-23T15:04:44+00:00" }, { "name": "utopia-php/analytics", @@ -2003,16 +2003,16 @@ }, { "name": "utopia-php/swoole", - "version": "0.2.3", + "version": "0.2.4", "source": { "type": "git", "url": "https://github.com/utopia-php/swoole.git", - "reference": "45c42aae7e7d3f9f82bf194c2cfa5499b674aefe" + "reference": "37d8c64b536d6bc7da4f0f5a934a0ec44885abf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/swoole/zipball/45c42aae7e7d3f9f82bf194c2cfa5499b674aefe", - "reference": "45c42aae7e7d3f9f82bf194c2cfa5499b674aefe", + "url": "https://api.github.com/repos/utopia-php/swoole/zipball/37d8c64b536d6bc7da4f0f5a934a0ec44885abf4", + "reference": "37d8c64b536d6bc7da4f0f5a934a0ec44885abf4", "shasum": "" }, "require": { @@ -2053,9 +2053,9 @@ ], "support": { "issues": "https://github.com/utopia-php/swoole/issues", - "source": "https://github.com/utopia-php/swoole/tree/0.2.3" + "source": "https://github.com/utopia-php/swoole/tree/0.2.4" }, - "time": "2021-03-22T22:39:24+00:00" + "time": "2021-06-22T10:49:24+00:00" }, { "name": "utopia-php/system", @@ -4819,7 +4819,6 @@ "type": "github" } ], - "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { diff --git a/src/Appwrite/Realtime/Server.php b/src/Appwrite/Realtime/Server.php index bdf5ac2973..15c977cb40 100644 --- a/src/Appwrite/Realtime/Server.php +++ b/src/Appwrite/Realtime/Server.php @@ -211,24 +211,24 @@ class Server throw new Exception('Missing or unknown project ID', 1008); } - // /* - // * Abuse Check - // * - // * Abuse limits are connecting 128 times per minute and ip address. - // */ - // $timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, function () use ($db) { - // return $db; - // }); - // $timeLimit - // ->setNamespace('app_' . $project->getId()) - // ->setParam('{ip}', $request->getIP()) - // ->setParam('{url}', $request->getURI()); + /* + * Abuse Check + * + * Abuse limits are connecting 128 times per minute and ip address. + */ + $timeLimit = new TimeLimit('url:{url},ip:{ip}', 128, 60, function () use (&$db) { + return $db; + }); + $timeLimit + ->setNamespace('app_' . $project->getId()) + ->setParam('{ip}', $request->getIP()) + ->setParam('{url}', $request->getURI()); - // $abuse = new Abuse($timeLimit); + $abuse = new Abuse($timeLimit); - // if ($abuse->check() && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') { - // throw new Exception('Too many requests', 1013); - // } + if ($abuse->check() && App::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') { + throw new Exception('Too many requests', 1013); + } /* * Validate Client Domain - Check to avoid CSRF attack.