Issues (6)

Security Analysis    no request data  

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

  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.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  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.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  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.
  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.
  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.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  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.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  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.
  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.
  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.
  Header Injection
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.

Service/ProxyBonanza.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * This file is part of the wow-apps/symfony-proxybonanza project
4
 * https://github.com/wow-apps/symfony-proxybonanza
5
 *
6
 * (c) 2016 WoW-Apps
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WowApps\ProxybonanzaBundle\Service;
13
14
use GuzzleHttp\Client as GuzzleClient;
15
use GuzzleHttp\Exception\ClientException;
16
use WowApps\ProxybonanzaBundle\Entity\AuthIps;
17
use WowApps\ProxybonanzaBundle\Entity\Plan;
18
use WowApps\ProxybonanzaBundle\Entity\Proxy;
19
use WowApps\ProxybonanzaBundle\Repository\AuthIpsRepository;
20
use WowApps\ProxybonanzaBundle\Repository\PlanRepository;
21
use WowApps\ProxybonanzaBundle\Repository\ProxiesRepository;
22
use WowApps\ProxybonanzaBundle\Traits\HelperTrait;
23
24
/**
25
 * Class ProxyBonanza
26
 * @author Alexey Samara <[email protected]>
27
 * @package wow-apps/symfony-proxybonanza
28
 */
29
class ProxyBonanza
30
{
31
    use HelperTrait;
32
33
    /** @var array */
34
    private $config;
35
36
    /** @var GuzzleClient */
37
    private $guzzleClient;
38
39
    /** @var PlanRepository */
40
    private $planRepository;
41
42
    /** @var ProxiesRepository */
43
    private $proxiesRepository;
44
45
    /** @var AuthIpsRepository */
46
    private $authIpsRepository;
47
48
    /**
49
     * ProxyBonanza constructor.
50
     * @param array $config
51
     * @param PlanRepository $planRepository
52
     * @param ProxiesRepository $proxiesRepository
53
     * @param AuthIpsRepository $authIpsRepository
54
     */
55
    public function __construct(
56
        array $config,
57
        PlanRepository $planRepository,
58
        ProxiesRepository $proxiesRepository,
59
        AuthIpsRepository $authIpsRepository
60
    ) {
61
        $this->setConfig($config);
62
        $this->planRepository = $planRepository;
63
        $this->proxiesRepository = $proxiesRepository;
64
        $this->authIpsRepository = $authIpsRepository;
65
        $this->guzzleClient = new GuzzleClient(
66
            ['headers' => ['Authorization' => $this->config['api_key']]]
67
        );
68
    }
69
70
    /**
71
     * @return array
72
     */
73
    public function getConfig(): array
74
    {
75
        return $this->config;
76
    }
77
78
    /**
79
     * @param array $config
80
     * @return ProxyBonanza
81
     */
82
    public function setConfig(array $config)
83
    {
84
        $this->config = $config;
85
        return $this;
86
    }
87
88
    /**
89
     * @param string $url
90
     * @return array
91
     * @throws \RuntimeException
92
     */
93
    private function getAPIResponse(string $url): array
94
    {
95
        try {
96
            $request = $this->guzzleClient->get($url);
97
        } catch (ClientException $e) {
98
            throw new \RuntimeException($e->getMessage());
99
        }
100
101
        $response = $request->getBody();
102
103
        $json = json_decode($response, true);
104
        if (!$json) {
105
            throw new \RuntimeException('Can\'t parse json');
106
        }
107
108
        if (!$json['success']) {
109
            throw new \RuntimeException('Error in response');
110
        }
111
112
        return $json;
113
    }
114
115
    /**
116
     * @return \ArrayObject|Plan[]
117
     */
118
    public function getRemotePlans(): \ArrayObject
119
    {
120
        $result = new \ArrayObject();
121
122
        $proxyBonanzaPlans = $this->getAPIResponse($this->config['api_url'] . 'userpackages.json');
123
        if (empty($proxyBonanzaPlans['data'])) {
124
            return $result;
125
        }
126
127
        foreach ($proxyBonanzaPlans['data'] as $plan) {
128
            $proxyBonanzaPlan = new Plan();
129
            $proxyBonanzaPlan
130
                ->setId((int)$plan['id'])
131
                ->setLogin($plan['login'])
132
                ->setPassword($plan['password'])
133
                ->setExpires($this->convertDateTime($plan['expires']))
134
                ->setBandwidth($plan['bandwidth'])
135
                ->setLastIpChange($this->convertDateTime($plan['last_ip_change']))
136
                ->setPackageName($plan['package']['name'])
137
                ->setPackageBandwidth($plan['package']['bandwidth'])
138
                ->setPackagePrice((float) $plan['package']['price'])
139
                ->setPackageHowmanyIps((int) $plan['package']['howmany_ips'])
140
                ->setPackagePricePerGig((float) $plan['package']['price_per_gig'])
0 ignored issues
show
(double)$plan['package']['price_per_gig'] of type double is incompatible with the type integer expected by parameter $packagePricePerGig of WowApps\ProxybonanzaBund...setPackagePricePerGig(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

140
                ->setPackagePricePerGig(/** @scrutinizer ignore-type */ (float) $plan['package']['price_per_gig'])
Loading history...
141
                ->setPackageType($plan['package']['package_type'])
142
            ;
143
144
            $result->offsetSet($proxyBonanzaPlan->getId(), $proxyBonanzaPlan);
145
        }
146
147
        return $result;
148
    }
149
150
    /**
151
     * @param \ArrayObject|Plan[] $pbPlans
152
     * @return \ArrayObject|Plan[]
153
     */
154
    public function getRemotePacks(\ArrayObject $pbPlans): \ArrayObject
155
    {
156
        if (!$pbPlans->count()) {
157
            throw new \InvalidArgumentException('Can\'t get ip packs for empty plans');
158
        }
159
160
        /** @var Plan $pbPlan */
161
        foreach ($pbPlans as $pbPlan) {
162
            $pbPackUrl = $this->config['api_url'] . sprintf('userpackages/%s.json', $pbPlan->getId());
163
164
            $pbPack = $this->getAPIResponse($pbPackUrl);
165
            if (empty($pbPack['data']['ippacks'])) {
166
                continue;
167
            }
168
169
            foreach ($pbPack['data']['ippacks'] as $item) {
170
                $proxy = new Proxy();
171
                $proxy
172
                    ->setProxyId((int)$item['id'])
173
                    ->setProxyIp($item['ip'])
174
                    ->setProxyPlan($pbPlan->getId())
175
                    ->setPlan($pbPlan)
176
                    ->setProxyPortHttp((int)$item['port_http'])
177
                    ->setProxyPortSocks((int)$item['port_socks'])
178
                    ->setProxyRegionId((int)$item['proxyserver']['georegion_id'])
179
                    ->setProxyRegionCountryName($item['proxyserver']['georegion']['name'])
180
                ;
181
182
                $pbPlan->appendProxy($proxy);
183
            }
184
185
            if (empty($pbPack['data']['authips'])) {
186
                continue;
187
            }
188
189
            foreach ($pbPack['data']['authips'] as $item) {
190
                $authIp = new AuthIps();
191
                $authIp
192
                    ->setId((int)$item['id'])
193
                    ->setIp($item['id'])
194
                ;
195
                $pbPlan->appendAuthIp($authIp);
196
            }
197
        }
198
199
        return $pbPlans;
200
    }
201
202
    /**
203
     * @param \ArrayObject|Plan[] $pbPlans
204
     */
205
    public function updateLocalDataFromRemote(\ArrayObject $pbPlans = null)
206
    {
207
        if (is_null($pbPlans) || !$pbPlans->count()) {
208
            $pbPlans = $this->getRemotePlans();
209
            $pbPlans = $this->getRemotePacks($pbPlans);
210
        }
211
212
        $this->planRepository->empty();
213
        $this->planRepository->insertPlans($pbPlans);
214
215
        $this->proxiesRepository->empty();
216
        $this->proxiesRepository->insertProxies($pbPlans);
217
218
        $this->authIpsRepository->empty();
219
        $this->authIpsRepository->insertAuthIps($pbPlans);
220
    }
221
222
    /**
223
     * @param int $planId
224
     * @return Plan
225
     * @throws \InvalidArgumentException
226
     */
227
    public function getLocalPlan(int $planId): Plan
228
    {
229
        return $this->planRepository->getLocalPlan($planId);
230
    }
231
232
    /**
233
     * @return \ArrayObject|Plan[]
234
     * @throws \InvalidArgumentException
235
     */
236
    public function getLocalPlans(): \ArrayObject
237
    {
238
        $proxyBonanzaPlans = $this->planRepository->getLocalPlans();
239
240
        if (empty($proxyBonanzaPlans)) {
241
            throw new \InvalidArgumentException('No local plans founded. Run proxybonanza:update to set local plans.');
242
        }
243
244
        return $proxyBonanzaPlans;
245
    }
246
247
    /**
248
     * @param Plan|null $pbPlan
249
     * @return \ArrayObject|Proxy[]
250
     */
251
    public function getLocalProxies(Plan $pbPlan = null): \ArrayObject
252
    {
253
        return $this->proxiesRepository->getLocalProxies($pbPlan);
254
    }
255
256
    /**
257
     * @param \ArrayObject|Plan[] $pbPlans
258
     * @return \ArrayObject|Plan[]
259
     */
260
    public function getLocalPlansProxies(\ArrayObject $pbPlans): \ArrayObject
261
    {
262
        if (empty($pbPlans)) {
263
            return $pbPlans;
264
        }
265
266
        foreach ($pbPlans as $pbPlan) {
267
            $pbPlan->setProxy($this->getLocalProxies($pbPlan));
268
        }
269
270
        return $pbPlans;
271
    }
272
273
    /**
274
     * @param \ArrayObject|Proxy[] $proxies
275
     * @return Proxy
276
     */
277
    public function getRandomProxy(\ArrayObject $proxies): Proxy
278
    {
279
        $keys = $this->getArrayObjectKeys($proxies);
280
        return $proxies->offsetGet(
281
            $keys[array_rand($keys, 1)]
282
        );
283
    }
284
285
    /**
286
     * @param Proxy $proxy
287
     * @return bool
288
     */
289
    public function testProxyConnection(Proxy $proxy): bool
290
    {
291
        $client = new GuzzleClient();
292
293
        $proxyTCP = [
294
            'http' => 'tcp://' . $proxy->getPlan()->getLogin() . ':'
295
                . $proxy->getPlan()->getPassword() . '@'
296
                . $proxy->getProxyIp() . ':'
297
                . $proxy->getProxyPortHttp(),
298
            'https' => 'tcp://' . $proxy->getPlan()->getLogin() . ':'
299
                . $proxy->getPlan()->getPassword() . '@'
300
                . $proxy->getProxyIp() . ':'
301
                . $proxy->getProxyPortHttp(),
302
        ];
303
304
        $response = $client->request('GET', 'http://google.com', ['proxy' => $proxyTCP]);
305
306
        if (!in_array($response->getStatusCode(), [200, 301, 302])) {
307
            return false;
308
        }
309
310
        return true;
311
    }
312
}
313