You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: developer_manual/basics/controllers.rst
+42-8Lines changed: 42 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -881,36 +881,70 @@ Nextcloud supports brute-force protection on an action basis. By default control
881
881
882
882
The native brute-force protection will slow down requests if too many violations have been found. This slow down will be applied to all requests against a brute-force protected controller with the same action from the affected IP.
883
883
884
-
To enable brute force protection the following *Annotation* can be added to the controller:
884
+
To enable brute force protection the following *Attribute* can be added to the controller:
885
885
886
-
* **@BruteForceProtection(action=string)**: "string" is the name of the action. Such as "login" or "reset". Brute-force attempts are on a per-action basis; this means if a violation for the "login" action is triggered, other actions such as "reset" or "foobar" are not affected.
886
+
* ``#[BruteForceProtection(action: 'string')]``: "string" is the name of the action. Such as "login" or "reset". Brute-force attempts are on a per-action basis; this means if a violation for the "login" action is triggered, other actions such as "reset" or "foobar" are not affected.
887
887
888
-
Then the **throttle()** method has to be called on the response in case of a violation. Doing so will increase the throttle counter and make following requests slower.
888
+
.. note::
889
+
890
+
The attribute is only available in Nextcloud 27 or later. In older versions the ``@BruteForceProtection(action=string)`` annotation can be used, but that does not allow multiple assignments to a single controller method.
891
+
892
+
Then the **throttle()** method has to be called on the response in case of a violation. Doing so will increase the throttle counter and make following requests slower, until a slowness of roughly 30 seconds is reached and the controller returns a ``429 Too Many Requests`` status is returned instead of avoid further requests.
889
893
890
894
A controller method that would employ brute-force protection with an action of "foobar" would look as following:
891
895
892
896
.. code-block:: php
897
+
:emphasize-lines: 11,18
893
898
894
899
<?php
895
900
namespace OCA\MyApp\Controller;
896
901
897
902
use OCP\IRequest;
898
903
use OCP\AppFramework\Controller;
904
+
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
899
905
use OCP\AppFramework\Http\TemplateResponse;
900
906
901
907
class PageController extends Controller {
902
908
903
-
/**
904
-
* @BruteForceProtection(action=foobar)
905
-
*/
906
-
public function rateLimitedForAll(): TemplateResponse {
909
+
#[BruteForceProtection(action: 'foobar')]
910
+
public function bruteforceProtected(): TemplateResponse {
907
911
$templateResponse = new TemplateResponse(…);
908
912
// In case of a violation increase the throttle counter
909
913
// note that $this->auth->isSuccessful here is just an
910
914
// example.
911
-
if(!$this->auth->isSuccessful()) {
915
+
if(!$this->auth->isSuccessful()) {
912
916
$templateResponse->throttle();
913
917
}
914
918
return $templateResponse;
915
919
}
916
920
}
921
+
922
+
A controller can also have multiple factors to brute force against. In this case you can specify multiple attributes and then in the throttle you specify the action which was violated. This is especially useful when a secret, in the sample below token, could be guessed on multiple endpoints e.g. a share token on the API level, preview endpoint, frontend controller, etc. while another secret (password), is specific to this one controller method.
923
+
924
+
.. code-block:: php
925
+
:emphasize-lines: 11-12,16,20
926
+
927
+
<?php
928
+
namespace OCA\MyApp\Controller;
929
+
930
+
use OCP\IRequest;
931
+
use OCP\AppFramework\Controller;
932
+
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
933
+
use OCP\AppFramework\Http\TemplateResponse;
934
+
935
+
class PageController extends Controller {
936
+
937
+
#[BruteForceProtection(action: 'token')]
938
+
#[BruteForceProtection(action: 'password')]
939
+
public function getPasswordProtectedShare(string $token, string $password): TemplateResponse {
0 commit comments