Issues (1507)

Security Analysis    not enabled

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.

PHPDaemon/Clients/DNS/Pool.php (14 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
2
namespace PHPDaemon\Clients\DNS;
3
4
use PHPDaemon\Cache\CappedStorageHits;
5
use PHPDaemon\Core\ComplexJob;
6
use PHPDaemon\FS\FileSystem;
7
use PHPDaemon\Network\Client;
8
9
/**
10
 * @package    NetworkClients
11
 * @subpackage DNSClient
12
 * @author     Vasily Zorin <[email protected]>
13
 */
14
class Pool extends Client
15
{
16
17
    /**
18
     * @var array Record Types [code => "name", ...]
19
     */
20
    public static $type = [
21
        1 => 'A',
22
        2 => 'NS',
23
        3 => 'MD',
24
        4 => 'MF',
25
        5 => 'CNAME',
26
        6 => 'SOA',
27
        7 => 'MB',
28
        8 => 'MG',
29
        9 => 'MR',
30
        10 => 'RR',
31
        11 => 'WKS',
32
        12 => 'PTR',
33
        13 => 'HINFO',
34
        14 => 'MINFO',
35
        15 => 'MX',
36
        16 => 'TXT',
37
        17 => 'RP',
38
        18 => 'AFSDB',
39
        19 => 'X25',
40
        20 => 'ISDN',
41
        21 => 'RT',
42
        22 => 'NSAP',
43
        23 => 'NSAP-PTR',
44
        24 => 'SIG',
45
        25 => 'KEY',
46
        26 => 'PX',
47
        27 => 'GPOS',
48
        28 => 'AAAA',
49
        29 => 'LOC',
50
        30 => 'NXT',
51
        31 => 'EID',
52
        32 => 'NIMLOC',
53
        33 => 'SRV',
54
        34 => 'ATMA',
55
        35 => 'NAPTR',
56
        36 => 'KX',
57
        37 => 'CERT',
58
        38 => 'A6',
59
        39 => 'DNAME',
60
        40 => 'SINK',
61
        41 => 'OPT',
62
        42 => 'APL',
63
        43 => 'DS',
64
        44 => 'SSHFP',
65
        45 => 'IPSECKEY',
66
        46 => 'RRSIG',
67
        47 => 'NSEC',
68
        48 => 'DNSKEY',
69
        49 => 'DHCID',
70
        50 => 'NSEC3',
71
        51 => 'NSEC3PARAM',
72
        55 => 'HIP',
73
        99 => 'SPF',
74
        100 => 'UINFO',
75
        101 => 'UID',
76
        102 => 'GID',
77
        103 => 'UNSPEC',
78
        249 => 'TKEY',
79
        250 => 'TSIG',
80
        251 => 'IXFR',
81
        252 => 'AXFR',
82
        253 => 'MAILB',
83
        254 => 'MAILA',
84
        255 => 'ALL',
85
        32768 => 'TA',
86
        32769 => 'DLV',
87
    ];
88
89
    /**
90
     * @var array Hosts file parsed [hostname => [addr, ...], ...]
91
     */
92
    public $hosts = [];
93
94
    /**
95
     * @var \PHPDaemon\Core\ComplexJob Preloading ComplexJob
96
     */
97
    public $preloading;
98
99
    /**
100
     * @var CappedStorageHits Resolve cache
101
     */
102
    public $resolveCache;
103
104
    /**
105
     * @var array Classes [code => "class"]
106
     */
107
    public static $class = [
108
        1 => 'IN',
109
        3 => 'CH',
110
        255 => 'ANY',
111
    ];
112
113
    /**
114
     * @var array resolve.conf file parsed
115
     */
116
    public $nameServers = [];
117
118
    /**
119
     * Constructor
120
     */
121
    protected function init()
122
    {
123
        $this->resolveCache = new CappedStorageHits($this->config->resolvecachesize->value);
0 ignored issues
show
The property resolvecachesize does not seem to exist in PHPDaemon\Config\Section.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
124
    }
125
126
    /**
127
     * Setting default config options
128
     * Overriden from NetworkClient::getConfigDefaults
129
     * @return array
130
     */
131
    protected function getConfigDefaults()
132
    {
133
        return [
134
            /* [integer] port */
135
            'port' => 53,
136
137
            /* [integer] resolvecachesize */
138
            'resolvecachesize' => 128,
139
140
            /* [string] Servers */
141
            'servers' => '',
142
143
            /* [string] hostsfile */
144
            'hostsfile' => '/etc/hosts',
145
146
            /* [string] resolvfile */
147
            'resolvfile' => '/etc/resolv.conf',
148
149
            /* [boolean] Expose? */
150
            'expose' => 1,
151
        ];
152
    }
153
154
    /**
155
     * Applies config
156
     * @return void
157
     */
158
    public function applyConfig()
159
    {
160
        parent::applyConfig();
161
        $pool = $this;
162
        if (!isset($this->preloading)) {
163
            $this->preloading = new ComplexJob();
164
        }
165
        $job = $this->preloading;
166
        $job->addJob('resolvfile', function ($jobname, $job) use ($pool) {
167
            FileSystem::readfile($pool->config->resolvfile->value, function ($file, $data) use ($pool, $job, $jobname) {
0 ignored issues
show
The property resolvfile does not seem to exist in PHPDaemon\Config\Section.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
168
                if ($file) {
169
                    foreach (explode("\n", $data) as $line) {
170
                        $line = trim($line);
171
                        if ($line !== '' && $line[0] !== '#' && preg_match('~nameserver ([^\r\n;]+)~i', $line, $m)) {
172
                            $pool->nameServers[] = $m[1];
173
                        }
174
                    }
175
                }
176
                $job->setResult($jobname);
177
            });
178
        });
179
        $job->addJob('hostsfile', function ($jobname, $job) use ($pool) {
180
            FileSystem::readfile($pool->config->hostsfile->value, function ($file, $data) use ($pool, $job, $jobname) {
0 ignored issues
show
The property hostsfile does not seem to exist in PHPDaemon\Config\Section.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
181
                if ($file) {
182
                    preg_match_all('~^([^#]\S+)\s+([^\r\n]+)\s*~m', $data, $m, PREG_SET_ORDER);
183
                    $pool->hosts = [];
184
                    foreach ($m as $h) {
0 ignored issues
show
The expression $m of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
185
                        $hosts = preg_split('~\s+~', $h[2]);
186
                        $ip = $h[1];
187
                        /* skip commentened ips */
188
                        if (preg_match('~^[\s]*?#~m', $ip)) {
189
                            continue;
190
                        }
191
                        foreach ($hosts as $host) {
192
                            $host = rtrim($host, '.') . '.';
193
                            $pool->hosts[$host][] = $ip;
194
                        }
195
                    }
196
                }
197
                $job->setResult($jobname);
198
            });
199
        });
200
        $job();
201
    }
202
203
    /**
204
     * Resolves the host
205
     * @param  string $hostname Hostname
206
     * @param  callable $cb Callback
207
     * @param  boolean $noncache Noncache?
208
     * @param  array $nameServers
209
     * @callback $cb ( array|string $addrs )
210
     * @return void
211
     */
212
    public function resolve($hostname, $cb, $noncache = false, $nameServers = [])
213
    {
214 View Code Duplication
        if (!$this->preloading->hasCompleted()) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
215
            $pool = $this;
216
            $this->preloading->addListener(function ($job) use ($hostname, $cb, $noncache, $pool, $nameServers) {
0 ignored issues
show
The parameter $job is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
217
                $pool->resolve($hostname, $cb, $noncache, $nameServers);
218
            });
219
            return;
220
        }
221
        $hostname = rtrim($hostname, '.') . '.';
222
        if (isset($this->hosts[$hostname])) {
223
            $cb($this->hosts[$hostname]);
224
            return;
225
        }
226
        if (!$noncache && ($item = $this->resolveCache->get($hostname))) { // cache hit
227
            $ip = $item->getValue();
228
            if ($ip === null) { // operation in progress
229
                $item->addListener($cb);
230
            } else { // hit
231
                $cb($ip);
232
            }
233
            return;
234
        } elseif (!$noncache) {
235
            $item = $this->resolveCache->put($hostname, null);
236
            $item->addListener($cb);
237
        }
238
        $pool = $this;
239
        $this->get($hostname, function ($response) use ($cb, $noncache, $hostname, $pool) {
240
            if (!isset($response['A'])) {
241
                if ($noncache) {
242
                    $cb(false);
243
                } else {
244
                    $pool->resolveCache->put($hostname, false, 5); // 5 - TTL of unsuccessful request
245
                }
246
                return;
247
            }
248
            if (!isset($response['A']) && !isset($response['AAAA'])) {
249
                $cb(false);
250
                return;
251
            }
252
            $addrs = [];
253
            $ttl = 0;
254 View Code Duplication
            if (isset($response['A'])) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
255
                foreach ($response['A'] as $r) {
256
                    $addrs[] = $r['ip'];
257
                    $ttl = $r['ttl'];
258
                }
259
            }
260 View Code Duplication
            if (isset($response['AAAA'])) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
                foreach ($response['AAAA'] as $r) {
262
                    $addrs[] = $r['ip'];
263
                    $ttl = $r['ttl'];
264
                }
265
            }
266
            if (sizeof($addrs) === 1) {
267
                $addrs = $addrs[0];
268
            }
269
            if ($noncache) {
270
                $cb($addrs);
271
            } else {
272
                $pool->resolveCache->put($hostname, $addrs, $ttl);
273
            }
274
        }, $noncache, $nameServers);
275
    }
276
277
    /**
278
     * Gets the host information
279
     * @param  string $hostname Hostname
280
     * @param  callable $cb Callback
281
     * @param  boolean $noncache Noncache?
282
     * @param  array $nameServers
283
     * @param  string $proto
284
     * @callback $cb ( )
285
     * @return void
286
     */
287
    public function get($hostname, $cb, $noncache = false, $nameServers = [], $proto = 'udp')
288
    {
289
        $pool = $this;
290
        if (!$nameServers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nameServers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
291
            $nameServers = $this->nameServers;
292
        }
293 View Code Duplication
        if (!$this->preloading->hasCompleted()) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
294
            $this->preloading->addListener(function ($job) use (
0 ignored issues
show
The parameter $job is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
295
                $hostname,
296
                $cb,
297
                $noncache,
298
                $pool,
299
                $nameServers,
300
                $proto
301
            ) {
302
                $pool->get($hostname, $cb, $noncache, $nameServers, $proto);
303
            });
304
            return;
305
        }
306
        $nameServer = reset($nameServers);
307
        $isIpv6 = filter_var($nameServer, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
308
        if ($isIpv6) {
309
            $nameServer = '[' . $nameServer . ']';
310
        }
311
        $onGetConnection = function ($conn) use ($cb, $hostname, $nameServers, $noncache, $pool, $proto) {
312
            if (!$conn || !$conn->isConnected()) {
313
                if ($proto === 'udp') {
314
                    //Fail to  connect via udp, trying by tcp
315
                    $pool->get($hostname, $cb, $noncache, $nameServers, 'tcp');
316
                    return;
317
                }
318
                array_shift($nameServers);
319
                if (!$nameServers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nameServers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
320
                    //Totally fail to resolve name
321
                    $cb(false);
322
                } else {
323
                    //Fail connect to curr Ns, but we can try another ns
324
                    $pool->get($hostname, $cb, $noncache, $nameServers, 'udp');
325
                }
326
            } else {
327
                $conn->get(
328
                    $hostname,
329
                    function ($response) use ($hostname, $cb, $proto, $noncache, $nameServers, $pool) {
330
                        if ($response === false && $proto === 'udp') {
331
                            //Fail to  connect via udp, trying by tcp
332
                            $pool->get($hostname, $cb, $noncache, $nameServers, 'tcp');
333
                        } else {
334
                            call_user_func($cb, $response);
335
                        }
336
                    }
337
                );
338
            }
339
        };
340
        list($host, $type, $class) = explode(':', $hostname . '::', 3);
0 ignored issues
show
The assignment to $host is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
The assignment to $class is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
341
        if ($type === 'AXFR') {
342
            $proto = 'tcp';
343
        }
344
        $this->getConnection($proto . '://' . $nameServer, $onGetConnection);
345
        return;
346
    }
347
}
348