Skip to content

Commit

Permalink
[3.x] Fix bug where special characters can be used when generating th…
Browse files Browse the repository at this point in the history
…rottle key (#216)

* Fix bug where special characters can be used when generating throttle keys

* Update ThrottlesLogins.php

* Update ThrottlesLogins.php

Co-authored-by: Liam Hackett <liamh@DESKTOP-RS5AQ35.localdomain>
Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
3 people authored Jan 20, 2022
1 parent f124752 commit 7a4397c
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 1 deletion.
84 changes: 83 additions & 1 deletion auth-backend/ThrottlesLogins.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ protected function fireLockoutEvent(Request $request)
*/
protected function throttleKey(Request $request)
{
return Str::lower($request->input($this->username())).'|'.$request->ip();
return $this->removeSpecialCharacters(Str::lower($request->input($this->username())).'|'.$request->ip());
}

/**
Expand Down Expand Up @@ -121,4 +121,86 @@ public function decayMinutes()
{
return property_exists($this, 'decayMinutes') ? $this->decayMinutes : 1;
}

/**
* Remove special characters that may allow users to bypass rate limiting.
*
* @param string $key
* @return string
*/
protected function removeSpecialCharacters($key)
{
$values = [
'' => 'a',
'' => 'b',
'' => 'c',
'' => 'd',
'' => 'e',
'' => 'f',
'' => 'g',
'' => 'h',
'' => 'i',
'' => 'j',
'' => 'k',
'' => 'l',
'' => 'm',
'' => 'n',
'' => 'o',
'' => 'p',
'' => 'q',
'' => 'r',
'' => 's',
'' => 't',
'' => 'u',
'' => 'v',
'' => 'w',
'' => 'x',
'' => 'y',
'' => 'z',
'' => '1',
'' => '2',
'' => '3',
'' => '4',
'' => '5',
'' => '6',
'' => '7',
'' => '8',
'' => '9',
'' => '10',
'' => '11',
'' => '12',
'' => '13',
'' => '14',
'' => '15',
'' => '16',
'' => '17',
'' => '18',
'' => '19',
'' => '20',
'' => '0',
'' => '1',
'' => '2',
'' => '3',
'' => '4',
'' => '5',
'' => '6',
'' => '7',
'' => '8',
'' => '9',
'' => '10',
'' => '11',
'' => '12',
'' => '13',
'' => '14',
'' => '15',
'' => '16',
'' => '17',
'' => '18',
'' => '19',
'' => '20',
'' => '0',
];

return strtr($key, $values);
}
}
66 changes: 66 additions & 0 deletions tests/AuthBackend/ThrottleLoginsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Laravel\Ui\Tests\AuthBackend;

use Illuminate\Foundation\Auth\ThrottlesLogins;
use Orchestra\Testbench\TestCase;
use Illuminate\Http\Request;
use PHPUnit\Framework\MockObject\MockObject;

class ThrottleLoginsTest extends TestCase
{
/**
* @test
* @dataProvider specialCharacterProvider
*/
public function it_can_replace_special_characters(string $value, string $expected): void
{
$throttle = $this->getMockForTrait(ThrottlesLogins::class);
$reflection = new \ReflectionClass($throttle);
$method = $reflection->getMethod('removeSpecialCharacters');
$method->setAccessible(true);

$this->assertSame($expected, $method->invoke($throttle, $value));
}

public function specialCharacterProvider(): array
{
return [
['ⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ', 'abcdefghijklmnopqrstuvwxyz'],
['⓪①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳', '01234567891011121314151617181920'],
['⓵⓶⓷⓸⓹⓺⓻⓼⓽⓾', '12345678910'],
['⓿⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴', '011121314151617181920'],
['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
['0123456789', '0123456789'],
];
}

/**
* @test
* @dataProvider emailProvider
*/
public function it_can_generate_throttle_key(string $email, string $expectedEmail): void
{
$throttle = $this->getMockForTrait(ThrottlesLogins::class, [], '', true, true, true, ['username']);
$throttle->method('username')->willReturn('email');
$reflection = new \ReflectionClass($throttle);
$method = $reflection->getMethod('throttleKey');
$method->setAccessible(true);

$request = $this->mock(Request::class);
$request->expects('input')->with('email')->andReturn($email);
$request->expects('ip')->andReturn('192.168.0.1');

$this->assertSame($expectedEmail . '|192.168.0.1', $method->invoke($throttle, $request));
}

public function emailProvider(): array
{
return [
'lowercase special characters' => ['ⓣⓔⓢⓣ@ⓛⓐⓡⓐⓥⓔⓛ.ⓒⓞⓜ', 'test@laravel.com'],
'uppercase special characters' => ['ⓉⒺⓈⓉ@ⓁⒶⓇⒶⓋⒺⓁ.ⒸⓄⓂ', 'test@laravel.com'],
'special character numbers' =>['test⑩⓸③@laravel.com', 'test1043@laravel.com'],
'default email' => ['test@laravel.com', 'test@laravel.com'],
];
}
}

0 comments on commit 7a4397c

Please sign in to comment.