diff --git a/CHANGELOG.md b/CHANGELOG.md index 64d2c65df..0d829fe12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Fixed typo in `modular.yaml` causing media to be ignored [#1725](https://github.com/getgrav/grav/issues/1725) * Reverted `case_insensitive_urls` option as it was causing issues with taxonomy [#1733](https://github.com/getgrav/grav/pull/1733) * Removed an extra `/` in `CompileFile.php` [#1693](https://github.com/getgrav/grav/pull/1693) + * Uri: Encode user and password to prevent issues in browsers # v1.3.8 ## 10/26/2017 diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index ad37d0f91..e87584885 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -107,7 +107,9 @@ class Uri // Build fragment. $this->fragment = null; - // Filter path and query string. + // Filter userinfo, path and query string. + $this->user = $this->user !== null ? static::filterUserInfo($this->user) : null; + $this->password = $this->password !== null ? static::filterUserInfo($this->password) : null; $this->path = empty($this->path) ? '/' : static::filterPath($this->path); $this->query = static::filterQuery($this->query); @@ -148,7 +150,9 @@ class Uri $this->host = $this->validateHostname($this->host) ? $this->host : 'unknown'; } - // Filter path, query string and fragment. + // Filter userinfo, path, query string and fragment. + $this->user = $this->user !== null ? static::filterUserInfo($this->user) : null; + $this->password = $this->password !== null ? static::filterUserInfo($this->password) : null; $this->path = empty($this->path) ? '/' : static::filterPath($this->path); $this->query = static::filterQuery($this->query); $this->fragment = $this->fragment !== null ? static::filterQuery($this->fragment) : null; @@ -1172,6 +1176,23 @@ class Uri return $path; } + /** + * Filters the user info string. + * + * @param string $info The raw user or password. + * @return string The percent-encoded user or password string. + */ + public static function filterUserInfo($info) + { + return preg_replace_callback( + '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u', + function ($match) { + return rawurlencode($match[0]); + }, + $info + ); + } + /** * Filter Uri path. * @@ -1187,7 +1208,7 @@ class Uri public static function filterPath($path) { return preg_replace_callback( - '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/u', function ($match) { return rawurlencode($match[0]); }, @@ -1204,7 +1225,7 @@ class Uri public static function filterQuery($query) { return preg_replace_callback( - '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/', + '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/u', function ($match) { return rawurlencode($match[0]); },