TestSplitPosUnicodeSecurityRegression specifically tests the vulnerability described in GHSA-g966-83w7-6w38 where Unicode case-folding caused incorrect SCRIPT_NAME/PATH_INFO splitting
(t *testing.T)
| 249 | // described in GHSA-g966-83w7-6w38 where Unicode case-folding caused |
| 250 | // incorrect SCRIPT_NAME/PATH_INFO splitting |
| 251 | func TestSplitPosUnicodeSecurityRegression(t *testing.T) { |
| 252 | // U+023A: Ⱥ (UTF-8: C8 BA). Lowercase is ⱥ (UTF-8: E2 B1 A5), longer in bytes. |
| 253 | path := "/ȺȺȺȺshell.php.txt.php" |
| 254 | split := []string{".php"} |
| 255 | |
| 256 | pos := splitPos(path, split) |
| 257 | |
| 258 | // The vulnerable code would return 22 (computed on lowercased string) |
| 259 | // The correct code should return 18 (position in original string) |
| 260 | expectedPos := strings.Index(path, ".php") + len(".php") |
| 261 | assert.Equal(t, expectedPos, pos, "split position should match first .php in original string") |
| 262 | assert.Equal(t, 18, pos, "split position should be 18, not 22") |
| 263 | |
| 264 | if pos > 0 && pos <= len(path) { |
| 265 | scriptName := path[:pos] |
| 266 | pathInfo := path[pos:] |
| 267 | |
| 268 | assert.Equal(t, "/ȺȺȺȺshell.php", scriptName, "script name should be the path up to first .php") |
| 269 | assert.Equal(t, ".txt.php", pathInfo, "path info should be the remainder after first .php") |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | // TestSplitPosSecurityRegressionUnicodeBypass guards against |
| 274 | // GHSA-3g8v-8r37-cgjm (uninitialized match flag on inner non-ASCII byte) and |
nothing calls this directly
no test coverage detected