Issues (108)

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.

src/Foundation/Application.php (1 issue)

Severity

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
namespace EntWeChat\Foundation;
4
5
use Doctrine\Common\Cache\Cache as CacheInterface;
6
use Doctrine\Common\Cache\FilesystemCache;
7
use EntWeChat\Core\AccessToken;
8
use EntWeChat\Core\Exceptions\InvalidConfigException;
9
use EntWeChat\Core\Http;
10
use EntWeChat\Support\Log;
11
use Monolog\Handler\HandlerInterface;
12
use Monolog\Handler\NullHandler;
13
use Monolog\Handler\StreamHandler;
14
use Monolog\Logger;
15
use Pimple\Container;
16
use Symfony\Component\HttpFoundation\Request;
17
18
/**
19
 * Class Application.
20
 *
21
 * @property \EntWeChat\Core\AccessToken                $access_token
22
 * @property \EntWeChat\Server\Guard                    $server
23
 * @property \EntWeChat\User\User                       $user
24
 * @property \EntWeChat\User\Tag                        $user_tag
25
 * @property \EntWeChat\User\Department                 $user_department
26
 * @property \EntWeChat\User\Batch                      $user_batch
27
 * @property \EntWeChat\Js\Js                           $js
28
 * @property \EntWeChat\Js\Contact                      $js_contact
29
 * @property \EntWeChat\Menu\Menu                       $menu
30
 * @property \EntWeChat\Broadcast\Broadcast             $broadcast
31
 * @property \EntWeChat\Material\Material               $material
32
 * @property \EntWeChat\Material\Temporary              $material_temporary
33
 * @property \EntWeChat\Card\Card                       $card
34
 * @property \EntWeChat\Agent\Agent                     $agent
35
 * @property \EntWeChat\Chat\Chat                       $chat
36
 * @property \EntWeChat\ShakeAround\ShakeAround         $shakearound
37
 * @property \EntWeChat\Soter\Soter                     $soter
38
 * @property \EntWeChat\Payment\Merchant                $merchant
39
 * @property \EntWeChat\Payment\Payment                 $payment
40
 * @property \EntWeChat\Payment\LuckyMoney\LuckyMoney   $lucky_money
41
 * @property \EntWeChat\Payment\MerchantPay\MerchantPay $merchant_pay
42
 * @property \EntWeChat\Payment\CashCoupon\CashCoupon   $cash_coupon
43
 * @property \EntWeChat\Auth\App                        $oauth
44
 * @property \EntWeChat\Auth\Web                        $auth
45
 * @property \EntWeChat\Staff\Staff                     $staff
46
 * @property \EntWeChat\Suite\Suite                     $suite
47
 * @property \EntWeChat\OA\API                          $oa
48
 *
49
 * @method \EntWeChat\Support\Collection getCallbackIp()
50
 */
51
class Application extends Container
52
{
53
    /**
54
     * Service Providers.
55
     *
56
     * @var array
57
     */
58
    protected $providers = [
59
        ServiceProviders\ServerServiceProvider::class,
60
        ServiceProviders\UserServiceProvider::class,
61
        ServiceProviders\JsServiceProvider::class,
62
        ServiceProviders\MenuServiceProvider::class,
63
        ServiceProviders\BroadcastServiceProvider::class,
64
        ServiceProviders\CardServiceProvider::class,
65
        ServiceProviders\MaterialServiceProvider::class,
66
        ServiceProviders\AgentServiceProvider::class,
67
        ServiceProviders\ChatServiceProvider::class,
68
        ServiceProviders\SoterServiceProvider::class,
69
        ServiceProviders\OAuthServiceProvider::class,
70
        ServiceProviders\PaymentServiceProvider::class,
71
        ServiceProviders\ShakeAroundServiceProvider::class,
72
        ServiceProviders\StaffServiceProvider::class,
73
        ServiceProviders\SuiteServiceProvider::class,
74
        ServiceProviders\FundamentalServiceProvider::class,
75
        ServiceProviders\OAServiceProvider::class,
76
    ];
77
78
    /**
79
     * Account Instances.
80
     *
81
     * @var array
82
     */
83
    protected $accounts = [];
84
85
    /**
86
     * Application constructor.
87
     *
88
     * @param array $config
89
     */
90
    public function __construct($config)
91
    {
92
        parent::__construct();
93
94
        $this['config'] = function () use ($config) {
95
            return new Config($config);
96
        };
97
98
        if ($this['config']['debug']) {
99
            error_reporting(E_ALL);
100
        }
101
102
        $this->registerProviders();
103
        $this->registerBase();
0 ignored issues
show
The call to the method EntWeChat\Foundation\Application::registerBase() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
104
        $this->initializeLogger();
105
106
        Http::setDefaultOptions($this['config']->get('guzzle', ['timeout' => 5.0]));
107
108
        $this->logConfiguration($config);
109
    }
110
111
    /**
112
     * Load account.
113
     *
114
     * @param string $account
115
     *
116
     * @throws InvalidConfigException
117
     *
118
     * @return Application
119
     */
120
    public function account($account)
121
    {
122
        if (isset($this->accounts[$account])) {
123
            return $this->accounts[$account];
124
        }
125
126
        if (!isset($this['config']['account'][$account])) {
127
            throw new InvalidConfigException('This account not exist.');
128
        }
129
130
        return $this->accounts[$account] = new self(
131
            array_merge($this['config']->all(), $this['config']['account'][$account])
132
        );
133
    }
134
135
    /**
136
     * Log configuration.
137
     *
138
     * @param array $config
139
     */
140
    public function logConfiguration($config)
141
    {
142
        $config = new Config($config);
143
144
        if ($config->has('account')) {
145
            $config->forget('account');
146
        }
147
148
        $keys = ['corp_id', 'secret', 'suite.suite_id', 'suite.secret'];
149
        foreach ($keys as $key) {
150
            !$config->has($key) || $config[$key] = '***'.substr($config[$key], -5);
151
        }
152
153
        Log::debug('Current config:', $config->toArray());
154
    }
155
156
    /**
157
     * Add a provider.
158
     *
159
     * @param string $provider
160
     *
161
     * @return Application
162
     */
163
    public function addProvider($provider)
164
    {
165
        array_push($this->providers, $provider);
166
167
        return $this;
168
    }
169
170
    /**
171
     * Set providers.
172
     *
173
     * @param array $providers
174
     */
175
    public function setProviders(array $providers)
176
    {
177
        $this->providers = [];
178
179
        foreach ($providers as $provider) {
180
            $this->addProvider($provider);
181
        }
182
    }
183
184
    /**
185
     * Return all providers.
186
     *
187
     * @return array
188
     */
189
    public function getProviders()
190
    {
191
        return $this->providers;
192
    }
193
194
    /**
195
     * Magic get access.
196
     *
197
     * @param string $id
198
     *
199
     * @return mixed
200
     */
201
    public function __get($id)
202
    {
203
        return $this->offsetGet($id);
204
    }
205
206
    /**
207
     * Magic set access.
208
     *
209
     * @param string $id
210
     * @param mixed  $value
211
     */
212
    public function __set($id, $value)
213
    {
214
        $this->offsetSet($id, $value);
215
    }
216
217
    /**
218
     * Register providers.
219
     */
220
    private function registerProviders()
221
    {
222
        foreach ($this->providers as $provider) {
223
            $this->register(new $provider());
224
        }
225
    }
226
227
    /**
228
     * Register basic providers.
229
     */
230
    private function registerBase()
231
    {
232
        $this['request'] = function () {
233
            return Request::createFromGlobals();
234
        };
235
236
        if (!empty($this['config']['cache']) && $this['config']['cache'] instanceof CacheInterface) {
237
            $this['cache'] = $this['config']['cache'];
238
        } else {
239
            $this['cache'] = function () {
240
                return new FilesystemCache(sys_get_temp_dir());
241
            };
242
        }
243
244
        $this['access_token'] = function () {
245
            return new AccessToken(
246
                $this['config']['corp_id'],
247
                $this['config']['secret'],
248
                $this['cache']
249
            );
250
        };
251
    }
252
253
    /**
254
     * Initialize logger.
255
     */
256
    private function initializeLogger()
257
    {
258
        if (Log::hasLogger()) {
259
            return;
260
        }
261
262
        $logger = new Logger('entwechat');
263
264
        if (!$this['config']['debug'] || defined('PHPUNIT_RUNNING')) {
265
            $logger->pushHandler(new NullHandler());
266
        } elseif ($this['config']['log.handler'] instanceof HandlerInterface) {
267
            $logger->pushHandler($this['config']['log.handler']);
268
        } elseif ($logFile = $this['config']['log.file']) {
269
            $logger->pushHandler(new StreamHandler(
270
                    $logFile,
271
                    $this['config']->get('log.level', Logger::WARNING),
272
                    true,
273
                    $this['config']->get('log.permission', null))
274
            );
275
        }
276
277
        Log::setLogger($logger);
278
    }
279
}
280