Issues (27)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/ConnectionManager.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php declare(strict_types=1);
2
/**
3
 * Query
4
 *
5
 * SQL Query Builder / Database Abstraction Layer
6
 *
7
 * PHP version 7.1
8
 *
9
 * @package     Query
10
 * @author      Timothy J. Warren <[email protected]>
11
 * @copyright   2012 - 2018 Timothy J. Warren
12
 * @license     http://www.opensource.org/licenses/mit-license.html  MIT License
13
 * @link        https://git.timshomepage.net/aviat4ion/Query
14
 */
15
namespace Query;
16
17
use DomainException;
18
19
/**
20
 * Connection manager class to manage connections for the
21
 * Query method
22
 */
23
final class ConnectionManager {
24
25
	/**
26
	 * Map of named database connections
27
	 * @var array
28
	 */
29
	private $connections = [];
30
31
	/**
32
	 * Class instance variable
33
	 * @var ConnectionManager|null
34
	 */
35
	private static $instance;
36
37
	/**
38
	 * Private constructor to prevent multiple instances
39
	 * @codeCoverageIgnore
40
	 */
41
	private function __construct()
42
	{
43
	}
44
45
	/**
46
	 * Private clone method to prevent cloning
47
	 *
48
	 * @throws DomainException
49
	 * @return void
50
	 */
51
	public function __clone()
52
	{
53
		throw new DomainException("Can't clone singleton");
54
	}
55
56
	/**
57
	 * Prevent serialization of this object
58
	 *
59
	 * @throws DomainException
60
	 * @return void
61
	 */
62
	public function __sleep()
63
	{
64
		throw new DomainException('No serializing of singleton');
65
	}
66
67
	/**
68
	 * Make sure serialize/deserialize doesn't work
69
	 *
70
	 * @throws DomainException
71
	 * @return void
72
	 */
73
	public function __wakeup()
74
	{
75
		throw new DomainException("Can't unserialize singleton");
76
	}
77
78
	/**
79
	 * Return  a connection manager instance
80
	 *
81
	 * @staticvar null $instance
82
	 * @return ConnectionManager
83
	 */
84
	public static function getInstance(): ConnectionManager
85
	{
86
		if (self::$instance === NULL)
87
		{
88
			self::$instance = new self();
89
		}
90
91
		return self::$instance;
92
	}
93
94
	/**
95
	 * Returns the connection specified by the name given
96
	 *
97
	 * @param string|array|object $name
98
	 * @return QueryBuilderInterface
99
	 * @throws Exception\NonExistentConnectionException
100
	 */
101
	public function getConnection($name = ''): QueryBuilderInterface
102
	{
103
		// If the parameter is a string, use it as an array index
104
		if (is_scalar($name) && isset($this->connections[$name]))
105
		{
106
			return $this->connections[$name];
107
		}
108
		else if (empty($name) && ! empty($this->connections)) // Otherwise, return the last one
109
		{
110
			return end($this->connections);
111
		}
112
113
		// You should actually connect before trying to get a connection...
114
		throw new Exception\NonExistentConnectionException('The specified connection does not exist');
115
	}
116
117
	/**
118
	 * Parse the passed parameters and return a connection
119
	 *
120
	 * @param object|array $params
121
	 * @throws Exception\BadDBDriverException
122
	 * @return QueryBuilderInterface
123
	 */
124
	public function connect($params): QueryBuilderInterface
125
	{
126
		[$dsn, $dbtype, $params, $options] = $this->parseParams($params);
0 ignored issues
show
The variable $dsn does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $dbtype seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
The variable $options does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
$params is of type object|array, but the function expects a object<stdClass>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
127
128
		$dbtype = ucfirst($dbtype);
0 ignored issues
show
The variable $dbtype seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
129
		$driver = "\\Query\\Drivers\\{$dbtype}\\Driver";
130
131
		// Create the database connection
132
		$db =  ! empty($params->user)
133
			? new $driver($dsn, $params->user, $params->pass, $options)
134
			: new $driver($dsn, '', '', $options);
135
136
		// Set the table prefix, if it exists
137
		if (isset($params->prefix))
138
		{
139
			$db->setTablePrefix($params->prefix);
140
		}
141
142
		// Create Query Builder object
143
		$conn = new QueryBuilder($db, new QueryParser($db));
144
145
146
		// Save it for later
147
		if (isset($params->alias))
148
		{
149
			$this->connections[$params->alias] = $conn;
150
		}
151
		else
152
		{
153
			$this->connections[] = $conn;
154
		}
155
156
		return $conn;
157
	}
158
159
	/**
160
	 * Parses params into a dsn and option array
161
	 *
162
	 * @param \stdClass $params
163
	 * @return object|array
164
	 * @throws Exception\BadDBDriverException
165
	 */
166
	public function parseParams($params): array
167
	{
168
		$params = (object) $params;
169
		$params->type = strtolower($params->type);
170
		$dbtype = ($params->type !== 'postgresql') ? $params->type : 'pgsql';
171
		$dbtype = ucfirst($dbtype);
172
173
		// Make sure the class exists
174
		if ( ! class_exists("\\Query\\Drivers\\{$dbtype}\\Driver"))
175
		{
176
			throw new Exception\BadDBDriverException('Database driver does not exist, or is not supported');
177
		}
178
179
		// Set additional PDO options
180
		$options = [];
181
182
		if (isset($params->options))
183
		{
184
			$options = (array) $params->options;
185
		}
186
187
		// Create the dsn for the database to connect to
188
		if(strtolower($dbtype) === 'sqlite')
189
		{
190
			$dsn = $params->file;
191
		}
192
		else
193
		{
194
			$dsn = $this->createDsn($dbtype, $params);
195
		}
196
197
198
		return [$dsn, $dbtype, $params, $options];
199
	}
200
201
	/**
202
	 * Create the dsn from the db type and params
203
	 *
204
	 * @codeCoverageIgnore
205
	 * @param string $dbtype
206
	 * @param array|object $params
207
	 * @return string
208
	 */
209
	private function createDsn(string $dbtype, $params): string
210
	{
211
		$pairs = [];
212
213
		if ( ! empty($params->database))
214
		{
215
			$pairs[] = implode('=', ['dbname', $params->database]);
216
		}
217
218
		$skip = [
219
			'name' => 'name',
220
			'pass' => 'pass',
221
			'user' => 'user',
222
			'type' => 'type',
223
			'prefix' => 'prefix',
224
			'options' => 'options',
225
			'database' => 'database',
226
			'alias' => 'alias'
227
		];
228
229
		foreach($params as $key => $val)
230
		{
231
			if (( ! array_key_exists($key, $skip)) &&  ! empty($val))
232
			{
233
				$pairs[] = implode('=', [$key, $val]);
234
			}
235
		}
236
237
		return strtolower($dbtype) . ':' . implode(';', $pairs);
238
	}
239
}