Issues (1)

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.

Main.php (1 issue)

Labels
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
/**
4
 * @package 2 Checkout
5
 * @author Iurii Makukh <[email protected]>
6
 * @copyright Copyright (c) 2017, Iurii Makukh <[email protected]>
7
 * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License 3.0
8
 */
9
10
namespace gplcart\modules\twocheckout;
11
12
use Exception;
13
use gplcart\core\Module;
14
use Omnipay\TwoCheckoutPlus\Gateway;
15
use UnexpectedValueException;
16
17
/**
18
 * Main class for 2 Checkout module
19
 */
20
class Main
21
{
22
23
    /**
24
     * The current order
25
     * @var array
26
     */
27
    protected $data_order;
28
29
    /**
30
     * Omnipay response instance
31
     * @var object
32
     */
33
    protected $response;
34
35
    /**
36
     * Frontend controller instance
37
     * @var \gplcart\core\controllers\frontend\Controller $controller
38
     */
39
    protected $controller;
40
41
    /**
42
     * Order model instance
43
     * @var \gplcart\core\models\Order $order
44
     */
45
    protected $order;
46
47
    /**
48
     * Module class instance
49
     * @var \gplcart\core\Module $module
50
     */
51
    protected $module;
52
53
    /**
54
     * @param Module $module
55
     */
56
    public function __construct(Module $module)
57
    {
58
        $this->module = $module;
59
    }
60
61
    /**
62
     * Implements hook "route.list"
63
     * @param array $routes
64
     */
65
    public function hookRouteList(array &$routes)
66
    {
67
        $routes['admin/module/settings/twocheckout'] = array(
68
            'access' => 'module_edit',
69
            'handlers' => array(
70
                'controller' => array('gplcart\\modules\\twocheckout\\controllers\\Settings', 'editSettings')
71
            )
72
        );
73
    }
74
75
    /**
76
     * Implements hook "module.enable.before"
77
     * @param mixed $result
78
     */
79
    public function hookModuleEnableBefore(&$result)
80
    {
81
        $this->checkGateway($result);
82
    }
83
84
    /**
85
     * Implements hook "module.install.before"
86
     * @param mixed $result
87
     */
88
    public function hookModuleInstallBefore(&$result)
89
    {
90
        $this->checkGateway($result);
91
    }
92
93
    /**
94
     * Implements hook "payment.methods"
95
     * @param array $methods
96
     */
97
    public function hookPaymentMethods(array &$methods)
98
    {
99
        $methods['twocheckout'] = array(
100
            'module' => 'twocheckout',
101
            'image' => 'image/icon.png',
102
            'title' => '2 Checkout',
103
            'status' => $this->getStatus(),
104
            'template' => array('complete' => 'pay')
105
        );
106
    }
107
108
    /**
109
     * Implements hook "order.add.before"
110
     * @param array $order
111
     * @param \gplcart\core\models\Order $object
112
     */
113
    public function hookOrderAddBefore(array &$order, $object)
114
    {
115
        // Adjust order status before creation
116
        // We want to get payment in advance, so assign "awaiting payment" status
117
        if ($order['payment'] === 'twocheckout') {
118
            $order['status'] = $object->getStatusAwaitingPayment();
119
        }
120
    }
121
122
    /**
123
     * Implements hook "order.checkout.complete"
124
     * @param string $message
125
     * @param array $order
126
     */
127
    public function hookOrderCompleteMessage(&$message, $order)
128
    {
129
        if ($order['payment'] === 'twocheckout') {
130
            $message = ''; // Hide default message
131
        }
132
    }
133
134
    /**
135
     * Implements hook "order.complete.page"
136
     * @param array $order
137
     * @param \gplcart\core\models\Order $model
138
     * @param \gplcart\core\controllers\frontend\Controller $controller
139
     */
140
    public function hookOrderCompletePage(array $order, $model, $controller)
141
    {
142
        $this->setOrderCompletePage($order, $model, $controller);
143
    }
144
145
    /**
146
     * Check 2checkout gateway class is loaded
147
     * @param mixed $result
148
     */
149
    protected function checkGateway(&$result)
150
    {
151
        try {
152
            $this->getGateway();
153
        } catch (Exception $ex) {
154
            $result = $ex->getMessage();
155
        }
156
    }
157
158
    /**
159
     * Set order complete page
160
     * @param array $order
161
     * @param \gplcart\core\models\Order $model
162
     * @param \gplcart\core\controllers\frontend\Controller $controller
163
     */
164
    protected function setOrderCompletePage(array $order, $model, $controller)
165
    {
166
        $this->order = $model;
167
        $this->data_order = $order;
168
        $this->controller = $controller;
169
170
        if ($order['payment'] === 'twocheckout') {
171
            $this->submitPayment();
172
            $this->completePayment();
173
        }
174
    }
175
176
    /**
177
     * Get gateway instance
178
     * @return \Omnipay\TwoCheckoutPlus\Gateway
179
     * @throws UnexpectedValueException
180
     */
181
    public function getGateway()
182
    {
183
        /* @var $module \gplcart\modules\omnipay_library\Main */
184
        $module = $this->module->getInstance('omnipay_library');
185
        $gateway = $module->getGatewayInstance('TwoCheckoutPlus');
186
187
        if (!$gateway instanceof Gateway) {
0 ignored issues
show
The class Omnipay\TwoCheckoutPlus\Gateway does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
188
            throw new UnexpectedValueException('Gateway must be instance of Omnipay\TwoCheckoutPlus\Gateway');
189
        }
190
191
        return $gateway;
192
    }
193
194
    /**
195
     * Returns a module setting
196
     * @param string $name
197
     * @param mixed $default
198
     * @return mixed
199
     */
200
    protected function getModuleSetting($name, $default = null)
201
    {
202
        return $this->module->getSettings('twocheckout', $name, $default);
203
    }
204
205
    /**
206
     * Returns the current status of the payment method
207
     */
208
    protected function getStatus()
209
    {
210
        return $this->getModuleSetting('status')
211
            && $this->getModuleSetting('accountNumber')
212
            && $this->getModuleSetting('secretWord');
213
    }
214
215
    /**
216
     * Performs actions when purchase is completed
217
     */
218
    protected function completePayment()
219
    {
220
        if ($this->controller->isQuery('paid')) {
221
            $gateway = $this->getGateway();
222
            $this->response = $gateway->completePurchase($this->getPurchaseParams())->send();
223
            $this->processResponse();
224
        }
225
    }
226
227
    /**
228
     * Handles submitted payment
229
     */
230
    protected function submitPayment()
231
    {
232
        if ($this->controller->isPosted('pay')) {
233
234
            $gateway = $this->getGateway();
235
            $gateway->setDemoMode((bool) $this->getModuleSetting('test'));
236
            $gateway->setCurrency($this->data_order['currency']);
237
            $gateway->setSecretWord($this->getModuleSetting('secretWord'));
238
            $gateway->setAccountNumber($this->getModuleSetting('accountNumber'));
239
240
            $cart = array(array(
241
                'quantity' => 1,
242
                'type' => 'product',
243
                'price' => $this->data_order['total_formatted_number'],
244
                'name' => $this->controller->text('Order #@num', array('@num' => $this->data_order['order_id']))
245
            ));
246
247
            $gateway->setCart($cart);
248
249
            $this->response = $gateway->purchase($this->getPurchaseParams())->send();
250
251
            if ($this->response->isRedirect()) {
252
                $this->response->redirect();
253
            } else if (!$this->response->isSuccessful()) {
254
                $this->redirectError();
255
            }
256
        }
257
    }
258
259
    /**
260
     * Returns an array of purchase parameters
261
     * @return array
262
     */
263
    protected function getPurchaseParams()
264
    {
265
        return array(
266
            'currency' => $this->data_order['currency'],
267
            'total' => $this->data_order['total_formatted_number'],
268
            'cancelUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('cancel' => true), true),
269
            'returnUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('paid' => true), true)
270
        );
271
    }
272
273
    /**
274
     * Processes gateway response
275
     */
276
    protected function processResponse()
277
    {
278
        if ($this->response->isSuccessful()) {
279
            $this->updateOrderStatus();
280
            $this->addTransaction();
281
            $this->redirectSuccess();
282
        } else if ($this->response->isRedirect()) {
283
            $this->response->redirect();
284
        } else {
285
            $this->redirectError();
286
        }
287
    }
288
289
    /**
290
     * Redirect on error transaction
291
     */
292
    protected function redirectError()
293
    {
294
        $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
295
    }
296
297
    /**
298
     * Redirect on successful transaction
299
     */
300
    protected function redirectSuccess()
301
    {
302
        $vars = array(
303
            '@num' => $this->data_order['order_id'],
304
            '@status' => $this->order->getStatusName($this->data_order['status'])
305
        );
306
307
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
308
        $this->controller->redirect('/', $message, 'success', true);
309
    }
310
311
    /**
312
     * Update order status after successful transaction
313
     */
314
    protected function updateOrderStatus()
315
    {
316
        $data = array('status' => $this->getModuleSetting('order_status_success'));
317
318
        $this->order->update($this->data_order['order_id'], $data);
319
        $this->data_order = $this->order->get($this->data_order['order_id']);
320
    }
321
322
    /**
323
     * Adds a transaction
324
     * @return integer
325
     */
326
    protected function addTransaction()
327
    {
328
        /* @var $model \gplcart\core\models\Transaction */
329
        $model = gplcart_instance_model('Transaction');
330
331
        $transaction = array(
332
            'total' => $this->data_order['total'],
333
            'order_id' => $this->data_order['order_id'],
334
            'currency' => $this->data_order['currency'],
335
            'payment_method' => $this->data_order['payment'],
336
            'gateway_transaction_id' => $this->response->getTransactionReference()
337
        );
338
339
        return $model->add($transaction);
340
    }
341
342
}
343