Validate server input
- Allow only scheme, host and port in the server field. - Use proper default host and port in Elasticsearch and ClickHouse driver.
This commit is contained in:
parent
55d40f8563
commit
27132d1175
|
@ -58,9 +58,15 @@ if (isset($_GET["elastic"])) {
|
||||||
return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method);
|
return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function connect($server, $username, $password) {
|
function connect($server, $username, $password) {
|
||||||
preg_match('~^(https?://)?(.*)~', $server, $match);
|
$this->_url = build_http_url($server, $username, $password, "localhost", 9200);
|
||||||
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
|
|
||||||
$return = $this->query('');
|
$return = $this->query('');
|
||||||
if ($return) {
|
if ($return) {
|
||||||
$this->server_info = $return['version']['number'];
|
$this->server_info = $return['version']['number'];
|
||||||
|
@ -227,9 +233,6 @@ if (isset($_GET["elastic"])) {
|
||||||
global $adminer;
|
global $adminer;
|
||||||
$connection = new Min_DB;
|
$connection = new Min_DB;
|
||||||
list($server, $username, $password) = $adminer->credentials();
|
list($server, $username, $password) = $adminer->credentials();
|
||||||
if (strpos($server, '/') !== false || strpos($server, ':') !== false) {
|
|
||||||
return lang('Only hostname or IP address');
|
|
||||||
}
|
|
||||||
if ($password != "" && $connection->connect($server, $username, "")) {
|
if ($password != "" && $connection->connect($server, $username, "")) {
|
||||||
return lang('Database does not support password.');
|
return lang('Database does not support password.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,58 @@ if ($_COOKIE["adminer_permanent"]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validate_server_input() {
|
||||||
|
if (SERVER == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = parse_url(SERVER);
|
||||||
|
if (!$parts) {
|
||||||
|
auth_error(lang('Invalid credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check proper URL parts.
|
||||||
|
if (isset($parts['user']) || isset($parts['pass']) || isset($parts['query']) || isset($parts['fragment'])) {
|
||||||
|
auth_error(lang('Invalid credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow only HTTP/S scheme.
|
||||||
|
if (isset($parts['scheme']) && !preg_match('~^(https?)$~i', $parts['scheme'])) {
|
||||||
|
auth_error(lang('Invalid credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow only host without a path. Note that "localhost" is parsed as path.
|
||||||
|
$host = (isset($parts['host']) ? $parts['host'] : '') . (isset($parts['path']) ? $parts['path'] : '');
|
||||||
|
if (strpos(rtrim($host, '/'), '/') !== false) {
|
||||||
|
auth_error(lang('Invalid credentials.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check privileged ports.
|
||||||
|
if (isset($parts['port']) && ($parts['port'] < 1024 || $parts['port'] > 65535)) {
|
||||||
|
auth_error(lang('Connecting to privileged ports is not allowed.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @param string $defaultServer
|
||||||
|
* @param int|null $defaultPort
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) {
|
||||||
|
if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) {
|
||||||
|
$this->error = lang('Invalid credentials.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($matches[1] ?: "http://") .
|
||||||
|
($username !== "" || $password !== "" ? "$username:$password@" : "") .
|
||||||
|
($matches[2] !== "" ? $matches[2] : $defaultServer) .
|
||||||
|
(isset($matches[3]) ? $matches[3] : ($defaultPort ? ":$defaultPort" : ""));
|
||||||
|
}
|
||||||
|
|
||||||
function add_invalid_login() {
|
function add_invalid_login() {
|
||||||
global $adminer;
|
global $adminer;
|
||||||
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
|
$fp = file_open_lock(get_temp_dir() . "/adminer.invalid");
|
||||||
|
@ -55,7 +107,7 @@ $auth = $_POST["auth"];
|
||||||
if ($auth) {
|
if ($auth) {
|
||||||
session_regenerate_id(); // defense against session fixation
|
session_regenerate_id(); // defense against session fixation
|
||||||
$vendor = $auth["driver"];
|
$vendor = $auth["driver"];
|
||||||
$server = $auth["server"];
|
$server = trim($auth["server"]);
|
||||||
$username = $auth["username"];
|
$username = $auth["username"];
|
||||||
$password = (string) $auth["password"];
|
$password = (string) $auth["password"];
|
||||||
$db = $auth["db"];
|
$db = $auth["db"];
|
||||||
|
@ -81,7 +133,7 @@ if ($auth) {
|
||||||
set_session($key, null);
|
set_session($key, null);
|
||||||
}
|
}
|
||||||
unset_permanent();
|
unset_permanent();
|
||||||
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . '.');
|
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.'));
|
||||||
|
|
||||||
} elseif ($permanent && !$_SESSION["pwds"]) {
|
} elseif ($permanent && !$_SESSION["pwds"]) {
|
||||||
session_regenerate_id();
|
session_regenerate_id();
|
||||||
|
@ -158,11 +210,9 @@ if (isset($_GET["username"]) && !class_exists("Min_DB")) {
|
||||||
stop_session(true);
|
stop_session(true);
|
||||||
|
|
||||||
if (isset($_GET["username"]) && is_string(get_password())) {
|
if (isset($_GET["username"]) && is_string(get_password())) {
|
||||||
list($host, $port) = explode(":", SERVER, 2);
|
validate_server_input();
|
||||||
if (preg_match('~^\s*([-+]?\d+)~', $port, $match) && ($match[1] < 1024 || $match[1] > 65535)) { // is_numeric('80#') would still connect to port 80
|
|
||||||
auth_error(lang('Connecting to privileged ports is not allowed.'));
|
|
||||||
}
|
|
||||||
check_invalid_login();
|
check_invalid_login();
|
||||||
|
|
||||||
$connection = connect();
|
$connection = connect();
|
||||||
$driver = new Min_Driver($connection);
|
$driver = new Min_Driver($connection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,9 +55,15 @@ if (isset($_GET["clickhouse"])) {
|
||||||
return $this->rootQuery($this->_db, $query);
|
return $this->rootQuery($this->_db, $query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $server
|
||||||
|
* @param string $username
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function connect($server, $username, $password) {
|
function connect($server, $username, $password) {
|
||||||
preg_match('~^(https?://)?(.*)~', $server, $match);
|
$this->_url = build_http_url($server, $username, $password, "localhost", 8123);
|
||||||
$this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]";
|
|
||||||
$return = $this->query('SELECT 1');
|
$return = $this->query('SELECT 1');
|
||||||
return (bool) $return;
|
return (bool) $return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue