Issues (1919)

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.

lib/Ajde/Mailer/class.pop3.php (10 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
/**
3
 * PHPMailer POP-Before-SMTP Authentication Class.
4
 * PHP Version 5.0.0
5
 * Version 5.2.7.
6
 *
7
 * @link      https://github.com/PHPMailer/PHPMailer/
8
 *
9
 * @author    Marcus Bointon (coolbru) <[email protected]>
10
 * @author    Jim Jagielski (jimjag) <[email protected]>
11
 * @author    Andy Prevost (codeworxtech) <[email protected]>
12
 * @author    Brent R. Matzelle (original founder)
13
 * @copyright 2013 Marcus Bointon
14
 * @copyright 2010 - 2012 Jim Jagielski
15
 * @copyright 2004 - 2009 Andy Prevost
16
 * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
17
 * @note      This program is distributed in the hope that it will be useful - WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
 * FITNESS FOR A PARTICULAR PURPOSE.
20
 */
21
22
/**
23
 * PHPMailer POP-Before-SMTP Authentication Class.
24
 * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
25
 * Does not support APOP.
26
 *
27
 * @author  Richard Davey (original author) <[email protected]>
28
 * @author  Marcus Bointon (coolbru) <[email protected]>
29
 * @author  Jim Jagielski (jimjag) <[email protected]>
30
 * @author  Andy Prevost (codeworxtech) <[email protected]>
31
 */
32
class POP3
33
{
34
    /**
35
     * The POP3 PHPMailer Version number.
36
     *
37
     * @var string
38
     */
39
    public $Version = '5.2.7';
40
41
    /**
42
     * Default POP3 port number.
43
     *
44
     * @var int
45
     */
46
    public $POP3_PORT = 110;
47
48
    /**
49
     * Default timeout in seconds.
50
     *
51
     * @var int
52
     */
53
    public $POP3_TIMEOUT = 30;
54
55
    /**
56
     * POP3 Carriage Return + Line Feed.
57
     *
58
     * @var string
59
     *
60
     * @deprecated Use the constant instead
61
     */
62
    public $CRLF = "\r\n";
63
64
    /**
65
     * Debug display level.
66
     * Options: 0 = no, 1+ = yes.
67
     *
68
     * @var int
69
     */
70
    public $do_debug = 0;
71
72
    /**
73
     * POP3 mail server hostname.
74
     *
75
     * @var string
76
     */
77
    public $host;
78
79
    /**
80
     * POP3 port number.
81
     *
82
     * @var int
83
     */
84
    public $port;
85
86
    /**
87
     * POP3 Timeout Value in seconds.
88
     *
89
     * @var int
90
     */
91
    public $tval;
92
93
    /**
94
     * POP3 username.
95
     *
96
     * @var string
97
     */
98
    public $username;
99
100
    /**
101
     * POP3 password.
102
     *
103
     * @var string
104
     */
105
    public $password;
106
107
    /**
108
     * Resource handle for the POP3 connection socket.
109
     *
110
     * @var resource
111
     */
112
    private $pop_conn;
113
114
    /**
115
     * Are we connected?
116
     *
117
     * @var bool
118
     */
119
    private $connected;
120
121
    /**
122
     * Error container.
123
     *
124
     * @var array
125
     */
126
    private $error;
127
128
    /**
129
     * Line break constant.
130
     */
131
    const CRLF = "\r\n";
132
133
    /**
134
     * Constructor.
135
     */
136
    public function __construct()
137
    {
138
        $this->pop_conn = 0;
0 ignored issues
show
Documentation Bug introduced by
It seems like 0 of type integer is incompatible with the declared type resource of property $pop_conn.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
139
        $this->connected = false;
140
        $this->error = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $error.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
141
    }
142
143
    /**
144
     * Simple static wrapper for all-in-one POP before SMTP.
145
     *
146
     * @param        $host
147
     * @param bool   $port
148
     * @param bool   $tval
149
     * @param string $username
150
     * @param string $password
151
     * @param int    $debug_level
152
     *
153
     * @return bool
154
     */
155
    public static function popBeforeSmtp(
156
        $host,
157
        $port = false,
158
        $tval = false,
159
        $username = '',
160
        $password = '',
161
        $debug_level = 0
162
    ) {
163
        $pop = new self();
164
165
        return $pop->authorise($host, $port, $tval, $username, $password, $debug_level);
166
    }
167
168
    /**
169
     * Authenticate with a POP3 server.
170
     * A connect, login, disconnect sequence
171
     * appropriate for POP-before SMTP authorisation.
172
     *
173
     * @param string   $host
174
     * @param bool|int $port
175
     * @param bool|int $tval
176
     * @param string   $username
177
     * @param string   $password
178
     * @param int      $debug_level
179
     *
180
     * @return bool
181
     */
182
    public function authorise($host, $port = false, $tval = false, $username = '', $password = '', $debug_level = 0)
183
    {
184
        $this->host = $host;
185
        // If no port value provided, use default
186
        if ($port === false) {
187
            $this->port = $this->POP3_PORT;
188
        } else {
189
            $this->port = $port;
0 ignored issues
show
Documentation Bug introduced by
It seems like $port can also be of type boolean. However, the property $port is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
190
        }
191
        // If no timeout value provided, use default
192
        if ($tval === false) {
193
            $this->tval = $this->POP3_TIMEOUT;
194
        } else {
195
            $this->tval = $tval;
0 ignored issues
show
Documentation Bug introduced by
It seems like $tval can also be of type boolean. However, the property $tval is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
196
        }
197
        $this->do_debug = $debug_level;
198
        $this->username = $username;
199
        $this->password = $password;
200
        //  Refresh the error log
201
        $this->error = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $error.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
202
        //  connect
203
        $result = $this->connect($this->host, $this->port, $this->tval);
0 ignored issues
show
It seems like $this->tval can also be of type boolean; however, POP3::connect() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
204
        if ($result) {
205
            $login_result = $this->login($this->username, $this->password);
206
            if ($login_result) {
207
                $this->disconnect();
208
209
                return true;
210
            }
211
        }
212
        // We need to disconnect regardless of whether the login succeeded
213
        $this->disconnect();
214
215
        return false;
216
    }
217
218
    /**
219
     * Connect to a POP3 server.
220
     *
221
     * @param string   $host
222
     * @param bool|int $port
223
     * @param int      $tval
224
     *
225
     * @return bool
226
     */
227
    public function connect($host, $port = false, $tval = 30)
228
    {
229
        //  Are we already connected?
230
        if ($this->connected) {
231
            return true;
232
        }
233
234
        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
235
        //Rather than suppress it with @fsockopen, capture it cleanly instead
236
        set_error_handler([$this, 'catchWarning']);
237
238
        //  connect to the POP3 server
239
        $this->pop_conn = fsockopen(
240
            $host, //  POP3 Host
241
            $port, //  Port #
242
            $errno, //  Error Number
243
            $errstr, //  Error Message
244
            $tval
245
        ); //  Timeout (seconds)
246
        //  Restore the error handler
247
        restore_error_handler();
248
        //  Does the Error Log now contain anything?
249
        if ($this->error && $this->do_debug >= 1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->error 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...
250
            $this->displayErrors();
251
        }
252
        //  Did we connect?
253
        if ($this->pop_conn == false) {
254
            //  It would appear not...
255
            $this->error = [
256
                'error'  => "Failed to connect to server $host on port $port",
257
                'errno'  => $errno,
258
                'errstr' => $errstr,
259
            ];
260
            if ($this->do_debug >= 1) {
261
                $this->displayErrors();
262
            }
263
264
            return false;
265
        }
266
267
        //  Increase the stream time-out
268
        //  Check for PHP 4.3.0 or later
269
        if (version_compare(phpversion(), '5.0.0', 'ge')) {
270
            stream_set_timeout($this->pop_conn, $tval, 0);
271
        } else {
272
            //  Does not work on Windows
273
            if (substr(PHP_OS, 0, 3) !== 'WIN') {
274
                socket_set_timeout($this->pop_conn, $tval, 0);
275
            }
276
        }
277
278
        //  Get the POP3 server response
279
        $pop3_response = $this->getResponse();
280
        //  Check for the +OK
281
        if ($this->checkResponse($pop3_response)) {
282
            //  The connection is established and the POP3 server is talking
283
            $this->connected = true;
284
285
            return true;
286
        }
287
288
        return false;
289
    }
290
291
    /**
292
     * Log in to the POP3 server.
293
     * Does not support APOP (RFC 2828, 4949).
294
     *
295
     * @param string $username
296
     * @param string $password
297
     *
298
     * @return bool
299
     */
300
    public function login($username = '', $password = '')
301
    {
302
        if ($this->connected == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
303
            $this->error = 'Not connected to POP3 server';
0 ignored issues
show
Documentation Bug introduced by
It seems like 'Not connected to POP3 server' of type string is incompatible with the declared type array of property $error.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
304
305
            if ($this->do_debug >= 1) {
306
                $this->displayErrors();
307
            }
308
        }
309
        if (empty($username)) {
310
            $username = $this->username;
311
        }
312
        if (empty($password)) {
313
            $password = $this->password;
314
        }
315
316
        // Send the Username
317
        $this->sendString("USER $username".self::CRLF);
318
        $pop3_response = $this->getResponse();
319
        if ($this->checkResponse($pop3_response)) {
320
            // Send the Password
321
            $this->sendString("PASS $password".self::CRLF);
322
            $pop3_response = $this->getResponse();
323
            if ($this->checkResponse($pop3_response)) {
324
                return true;
325
            }
326
        }
327
328
        return false;
329
    }
330
331
    /**
332
     * Disconnect from the POP3 server.
333
     */
334
    public function disconnect()
335
    {
336
        $this->sendString('QUIT');
337
        //The QUIT command may cause the daemon to exit, which will kill our connection
338
        //So ignore errors here
339
        @fclose($this->pop_conn);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
340
    }
341
342
    /**
343
     * Get a response from the POP3 server.
344
     * $size is the maximum number of bytes to retrieve.
345
     *
346
     * @param int $size
347
     *
348
     * @return string
349
     */
350
    private function getResponse($size = 128)
351
    {
352
        $r = fgets($this->pop_conn, $size);
353
        if ($this->do_debug >= 1) {
354
            echo "Server -> Client: $r";
355
        }
356
357
        return $r;
358
    }
359
360
    /**
361
     * Send raw data to the POP3 server.
362
     *
363
     * @param string $string
364
     *
365
     * @return int
366
     */
367
    private function sendString($string)
368
    {
369
        if ($this->pop_conn) {
370
            if ($this->do_debug >= 2) { //Show client messages when debug >= 2
371
                echo "Client -> Server: $string";
372
            }
373
374
            return fwrite($this->pop_conn, $string, strlen($string));
375
        }
376
377
        return 0;
378
    }
379
380
    /**
381
     * Checks the POP3 server response.
382
     * Looks for for +OK or -ERR.
383
     *
384
     * @param string $string
385
     *
386
     * @return bool
387
     */
388
    private function checkResponse($string)
389
    {
390
        if (substr($string, 0, 3) !== '+OK') {
391
            $this->error = [
392
                'error'  => "Server reported an error: $string",
393
                'errno'  => 0,
394
                'errstr' => '',
395
            ];
396
            if ($this->do_debug >= 1) {
397
                $this->displayErrors();
398
            }
399
400
            return false;
401
        } else {
402
            return true;
403
        }
404
    }
405
406
    /**
407
     * Display errors if debug is enabled.
408
     */
409
    private function displayErrors()
410
    {
411
        echo '<pre>';
412
        foreach ($this->error as $single_error) {
413
            print_r($single_error);
414
        }
415
        echo '</pre>';
416
    }
417
418
    /**
419
     * POP3 connection error handler.
420
     *
421
     * @param int    $errno
422
     * @param string $errstr
423
     * @param string $errfile
424
     * @param int    $errline
425
     */
426
    private function catchWarning($errno, $errstr, $errfile, $errline)
427
    {
428
        $this->error[] = [
429
            'error'   => 'Connecting to the POP3 server raised a PHP warning: ',
430
            'errno'   => $errno,
431
            'errstr'  => $errstr,
432
            'errfile' => $errfile,
433
            'errline' => $errline,
434
        ];
435
    }
436
}
437