@@ -40,83 +40,128 @@ class URLTest extends \GLPITestCase
40
40
public static function urlProvider (): iterable
41
41
{
42
42
yield [
43
- 'url ' => null ,
44
- 'expected ' => '' ,
43
+ 'url ' => null ,
44
+ 'sanitized ' => '' ,
45
+ 'relative ' => false ,
45
46
];
46
47
yield [
47
- 'url ' => '' ,
48
- 'expected ' => '' ,
48
+ 'url ' => '' ,
49
+ 'sanitized ' => '' ,
50
+ 'relative ' => false ,
49
51
];
50
52
51
53
// Javascript URL
52
54
yield [
53
- 'url ' => 'javascript:alert(1); ' ,
54
- 'expected ' => '' ,
55
+ 'url ' => 'javascript:alert(1); ' ,
56
+ 'sanitized ' => '' ,
57
+ 'relative ' => false ,
55
58
];
56
59
yield [
57
- 'url ' => "java \nscript:alert(1); " ,
58
- 'expected ' => '' ,
60
+ 'url ' => "java \nscript:alert(1); " ,
61
+ 'sanitized ' => '' ,
62
+ 'relative ' => false ,
59
63
];
60
64
yield [
61
- 'url ' => "j a v \t\ta \n s c \t ript :alert(1); " ,
62
- 'expected ' => '' ,
65
+ 'url ' => "j a v \t\ta \n s c \t ript :alert(1); " ,
66
+ 'sanitized ' => '' ,
67
+ 'relative ' => false ,
63
68
];
64
69
yield [
65
- 'url ' => 'jAvAscrIPt:alert(1); ' ,
66
- 'expected ' => '' ,
70
+ 'url ' => 'jAvAscrIPt:alert(1); ' ,
71
+ 'sanitized ' => '' ,
72
+ 'relative ' => false ,
67
73
];
68
74
yield [
69
- 'url ' => 'javascript:alert(1);" title="XSS!" ' ,
70
- 'expected ' => '' ,
75
+ 'url ' => 'javascript:alert(1);" title="XSS!" ' ,
76
+ 'sanitized ' => '' ,
77
+ 'relative ' => false ,
71
78
];
72
79
yield [
73
- 'url ' => 'javascript:alert(1) ' ,
74
- 'expected ' => '' ,
80
+ 'url ' => 'javascript:alert(1) ' ,
81
+ 'sanitized ' => '' ,
82
+ 'relative ' => false ,
75
83
];
76
84
yield [
77
- 'url ' => 'javascript://%0aalert(); ' ,
78
- 'expected ' => '' ,
85
+ 'url ' => 'javascript://%0aalert(); ' ,
86
+ 'sanitized ' => '' ,
87
+ 'relative ' => false ,
79
88
];
80
89
81
90
// Invalid URL
82
91
yield [
83
- 'url ' => 'ht tp://www.domain.tld/test ' ,
84
- 'expected ' => '' ,
92
+ 'url ' => 'ht tp://www.domain.tld/test ' ,
93
+ 'sanitized ' => '' ,
94
+ 'relative ' => false ,
85
95
];
86
96
yield [
87
- 'url ' => 'http:/www.domain.tld/test ' ,
88
- 'expected ' => '' ,
97
+ 'url ' => 'http:/www.domain.tld/test ' ,
98
+ 'sanitized ' => '' ,
99
+ 'relative ' => false ,
89
100
];
90
101
yield [
91
- 'url ' => '15//test ' ,
92
- 'expected ' => '' ,
102
+ 'url ' => '15//test ' ,
103
+ 'sanitized ' => '' ,
104
+ 'relative ' => false ,
93
105
];
94
106
95
107
// Sane URL
96
108
yield [
97
- 'url ' => 'http://www.domain.tld/test ' ,
98
- 'expected ' => 'http://www.domain.tld/test ' ,
109
+ 'url ' => 'http://www.domain.tld/test ' ,
110
+ 'sanitized ' => 'http://www.domain.tld/test ' ,
111
+ 'relative ' => false ,
99
112
];
100
113
yield [
101
- 'url ' => '//hostname/path/to/file ' ,
102
- 'expected ' => '//hostname/path/to/file ' ,
114
+ 'url ' => '//hostname/path/to/file ' ,
115
+ 'sanitized ' => '//hostname/path/to/file ' ,
116
+ 'relative ' => false ,
103
117
];
104
118
yield [
105
- 'url ' => '/test?abc=12 ' ,
106
- 'expected ' => '/test?abc=12 ' ,
119
+ 'url ' => '/test?abc=12 ' ,
120
+ 'sanitized ' => '/test?abc=12 ' ,
121
+ 'relative ' => true ,
107
122
];
108
123
yield [
109
- 'url ' => '/ ' ,
110
- 'expected ' => '/ ' ,
124
+ 'url ' => '/Path/To/Resource/15 ' ,
125
+ 'sanitized ' => '/Path/To/Resource/15 ' ,
126
+ 'relative ' => true ,
111
127
];
128
+ yield [
129
+ 'url ' => '/ ' ,
130
+ 'sanitized ' => '/ ' ,
131
+ 'relative ' => true ,
132
+ ];
133
+ yield [
134
+ 'url ' => '/.hiddenfile ' ,
135
+ 'sanitized ' => '/.hiddenfile ' ,
136
+ 'relative ' => false , // not considered as a valid relative URL, as it exposes an hidden resource
137
+ ];
138
+ yield [
139
+ 'url ' => '/front/.hidden.php ' ,
140
+ 'sanitized ' => '/front/.hidden.php ' ,
141
+ 'relative ' => false , // not considered as a valid relative URL, as it exposes an hidden resource
142
+ ];
143
+ yield [
144
+ 'url ' => '/front/../../oustideglpi.php ' ,
145
+ 'sanitized ' => '/front/../../oustideglpi.php ' ,
146
+ 'relative ' => false , // not considered as a valid relative URL, as it contains a `/..` token that may expose paths outside GLPI
147
+ ];
148
+ }
149
+
150
+ /**
151
+ * @dataProvider urlProvider
152
+ */
153
+ public function testSanitizeURL (?string $ url , string $ sanitized , bool $ relative ): void
154
+ {
155
+ $ instance = new \Glpi \Toolbox \URL ();
156
+ $ this ->assertEquals ($ sanitized , $ instance ->sanitizeURL ($ url ));
112
157
}
113
158
114
159
/**
115
160
* @dataProvider urlProvider
116
161
*/
117
- public function testSanitizeURL (?string $ url , string $ expected ): void
162
+ public function testIsGLPIRelativeUrl (?string $ url , string $ sanitized , bool $ relative ): void
118
163
{
119
164
$ instance = new \Glpi \Toolbox \URL ();
120
- $ this ->assertEquals ($ expected , $ instance ->sanitizeURL ( $ url ));
165
+ $ this ->assertEquals ($ relative , $ instance ->isGLPIRelativeUrl (( string ) $ url ));
121
166
}
122
167
}
0 commit comments