1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
<?php
declare(strict_types=1);
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class UserDAOTest extends TestCase {
#[DataProvider('pathTraversalPayloadsProvider')]
public function testExistsRejectsPathTraversal(string $payload): void {
self::assertFalse(FreshRSS_UserDAO::exists($payload));
}
#[DataProvider('pathTraversalPayloadsProvider')]
public function testMtimeRejectsPathTraversal(string $payload): void {
self::assertSame(0, FreshRSS_UserDAO::mtime($payload));
}
#[DataProvider('pathTraversalPayloadsProvider')]
public function testCtimeRejectsPathTraversal(string $payload): void {
self::assertSame(0, FreshRSS_UserDAO::ctime($payload));
}
/**
* @return array<string,array<int,string>>
*/
public static function pathTraversalPayloadsProvider(): array {
return [
'parent directory' => ['../'],
'double parent directory' => ['../../'],
'traversal to app' => ['../../app'],
'traversal to etc' => ['../../../etc'],
'traversal with null byte' => ["../\0"],
'absolute path' => ['/etc/passwd'],
'dot only' => ['.'],
'double dot' => ['..'],
'slash in name' => ['user/config'],
'backslash traversal' => ['..\\..\\app'],
'encoded traversal' => ['%2e%2e%2f'],
'mixed traversal' => ['valid/../invalid'],
'empty string' => [''],
];
}
#[DataProvider('validUsernamesProvider')]
public function testExistsAcceptsValidUsernames(string $username): void {
$result = FreshRSS_UserDAO::exists($username);
self::assertIsBool($result);
}
#[DataProvider('validUsernamesProvider')]
public function testMtimeAcceptsValidUsernames(string $username): void {
$result = FreshRSS_UserDAO::mtime($username);
self::assertIsInt($result);
}
#[DataProvider('validUsernamesProvider')]
public function testCtimeAcceptsValidUsernames(string $username): void {
$result = FreshRSS_UserDAO::ctime($username);
self::assertIsInt($result);
}
/**
* @return array<string,array<int,string>>
*/
public static function validUsernamesProvider(): array {
return [
'simple' => ['alice'],
'with numbers' => ['user123'],
'with underscore' => ['test_user'],
'with dot' => ['user.name'],
'with hyphen' => ['user-name'],
'with at' => ['user@domain'],
'single char' => ['a'],
'max length' => [str_repeat('a', 39)],
];
}
}
|