Issues (37)

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/Tracker.php (1 issue)

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 namespace Arcanedev\LaravelTracker;
2
3
use Arcanedev\LaravelTracker\Contracts\Tracker as TrackerContract;
4
use Exception;
5
use Illuminate\Contracts\Foundation\Application;
6
use Illuminate\Http\Request;
7
use Illuminate\Routing\Route;
8
9
/**
10
 * Class     Tracker
11
 *
12
 * @package  Arcanedev\LaravelTracker
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
class Tracker implements TrackerContract
16
{
17
    /* -----------------------------------------------------------------
18
     |  Traits
19
     | -----------------------------------------------------------------
20
     */
21
22
    use Traits\TrackersMaker;
23
24
    /* -----------------------------------------------------------------
25
     |  Properties
26
     | -----------------------------------------------------------------
27
     */
28
29
    /**
30
     * The application container.
31
     *
32
     * @var \Illuminate\Contracts\Foundation\Application
33
     */
34
    protected $app;
35
36
    /**
37
     * The request instance.
38
     *
39
     * @var \Illuminate\Http\Request
40
     */
41
    private $request;
42
43
    /**
44
     * Tracking enabled status.
45
     *
46
     * @var  bool
47
     */
48
    protected $enabled = false;
49
50
    /**
51
     * The current visitor data.
52
     *
53
     * @var array
54
     */
55
    protected $visitorData = [
56
        'user_id'     => null,
57
        'device_id'   => null,
58
        'agent_id'    => null,
59
        'geoip_id'    => null,
60
        'referer_id'  => null,
61
        'cookie_id'   => null,
62
        'language_id' => null,
63
        'client_ip'   => '',
64
        'is_robot'    => false,
65
        'user_agent'  => '',
66
    ];
67
68
    /**
69
     * The current visitor activity data.
70
     *
71
     * @var array
72
     */
73
    protected $visitorActivityData = [
74
        'visitor_id'    => null,
75
        'path_id'       => null,
76
        'query_id'      => null,
77
        'referer_id'    => null,
78
        'route_path_id' => null,
79
        'error_id'      => null,
80
        'method'        => '',
81
        'is_ajax'       => false,
82
        'is_secure'     => false,
83
        'is_json'       => false,
84
        'wants_json'    => false,
85
    ];
86
87
    /**
88
     * Indicates if migrations will be run.
89
     *
90
     * @var bool
91
     */
92
    public static $runsMigrations = true;
93
94
    /* -----------------------------------------------------------------
95
     |  Constructor
96
     | -----------------------------------------------------------------
97
     */
98
99
    /**
100
     * Tracker constructor.
101
     *
102
     * @param  \Illuminate\Contracts\Foundation\Application  $app
103
     */
104 117
    public function __construct(Application $app)
105
    {
106 117
        $this->app     = $app;
107 117
        $this->enabled = $this->getConfig('enabled', $this->enabled);
108 117
    }
109
110
    /* -----------------------------------------------------------------
111
     |  Getters & Setters
112
     | -----------------------------------------------------------------
113
     */
114
115
    /**
116
     * Get the application instance.
117
     *
118
     * @return \Illuminate\Contracts\Foundation\Application
119
     */
120 117
    protected function app()
121
    {
122 117
        return $this->app;
123
    }
124
125
    /**
126
     * Get the config repository.
127
     *
128
     * @return \Illuminate\Contracts\Config\Repository
129
     */
130 117
    private function config()
131
    {
132 117
        return $this->make('config');
133
    }
134
135
    /**
136
     * Get the tracker config.
137
     *
138
     * @param  string      $key
139
     * @param  mixed|null  $default
140
     *
141
     * @return mixed
142
     */
143 117
    private function getConfig($key, $default = null)
144
    {
145 117
        return $this->config()->get("laravel-tracker.$key", $default);
146
    }
147
148
    /**
149
     * Set the request.
150
     *
151
     * @param  \Illuminate\Http\Request  $request
152
     *
153
     * @return self
154
     */
155 6
    private function setRequest(Request $request)
156
    {
157 6
        $this->mergeVisitorActivityData([
158 6
            'method'      => $request->method(),
159 6
            'is_ajax'     => $request->ajax(),
160 6
            'is_secure'   => $request->isSecure(),
161 6
            'is_json'     => $request->isJson(),
162 6
            'wants_json'  => $request->wantsJson(),
163
        ]);
164
165 6
        $this->request = $request;
166
167 6
        return $this;
168
    }
169
170
    /* -----------------------------------------------------------------
171
     |  Main Methods
172
     | -----------------------------------------------------------------
173
     */
174
175
    /**
176
     * Start the tracking.
177
     *
178
     * @param  \Illuminate\Http\Request  $request
179
     */
180 6
    public function trackRequest(Request $request)
181
    {
182 6
        if ($this->isEnabled()) {
183 6
            $this->setRequest($request);
184
185 6
            $this->mergeVisitorActivityData([
186 6
                'visitor_id' => $this->getVisitorId(),
187 6
                'path_id'    => $this->getPathId(),
188 6
                'query_id'   => $this->getQueryId(),
189 6
                'referer_id' => $this->getRefererId(),
190
            ]);
191
192 6
            $id = $this->getVisitorActivityTracker()->track($this->visitorActivityData);
0 ignored issues
show
$id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
193
        }
194 6
    }
195
196
    /**
197
     * Track the matched route.
198
     *
199
     * @param  \Illuminate\Routing\Route  $route
200
     * @param  \Illuminate\Http\Request   $request
201
     */
202 6
    public function trackMatchedRoute(Route $route, Request $request)
203
    {
204 6
        if ( ! $this->isEnabled()) return;
205
206 6
        $tracker = $this->getRouteTracker();
207
208 6
        if ($tracker->isTrackable($route)) {
209 6
            $this->mergeVisitorActivityData([
210 6
                'route_path_id' => $tracker->track($route, $request),
211
            ]);
212
        }
213
        else
214
            $this->disable();
215 6
    }
216
217
    /**
218
     * Track the exception.
219
     *
220
     * @param  \Exception  $exception
221
     */
222
    public function trackException(Exception $exception)
223
    {
224 3
        $id = $this->trackIfEnabled('errors', function () use ($exception) {
225 3
            $this->getErrorTracker()->track($exception);
226 3
        });
227
228 3
        $this->mergeVisitorActivityData(['error_id' => $id]);
229 3
    }
230
231
    /**
232
     * Enable the tracking.
233
     */
234 117
    public function enable()
235
    {
236 117
        if ( ! $this->isEnabled()) $this->enabled = true;
237 117
    }
238
239
    /**
240
     * Disable the tracking.
241
     */
242 3
    public function disable()
243
    {
244 3
        if ($this->isEnabled()) $this->enabled = false;
245 3
    }
246
247
    /* -----------------------------------------------------------------
248
     |  Check Methods
249
     | -----------------------------------------------------------------
250
     */
251
252
    /**
253
     * Check if the tracker is enabled.
254
     *
255
     * @return bool
256
     */
257 117
    public function isEnabled()
258
    {
259 117
        return $this->enabled;
260
    }
261
262
    /**
263
     * Track the trackable if enabled.
264
     *
265
     * @param  string      $key
266
     * @param  \Closure    $callback
267
     * @param  mixed|null  $default
268
     *
269
     * @return mixed
270
     */
271 9
    private function trackIfEnabled($key, \Closure $callback, $default = null)
272
    {
273 9
        return $this->isEnabled()
274 9
            ? ($this->getConfig("tracking.$key", false) ? $callback() : $default)
275 9
            : $default;
276
    }
277
278
    /* -----------------------------------------------------------------
279
     |  Other Methods
280
     | -----------------------------------------------------------------
281
     */
282
283
    /**
284
     * Merge visitor data.
285
     *
286
     * @param  array  $data
287
     *
288
     * @return self
289
     */
290 6
    private function mergeVisitorData(array $data)
291
    {
292 6
        $this->visitorData = array_merge($this->visitorData, $data);
293
294 6
        return $this;
295
    }
296
297
    /**
298
     * Merge visitor activity data.
299
     *
300
     * @param  array  $data
301
     *
302
     * @return self
303
     */
304 9
    private function mergeVisitorActivityData(array $data)
305
    {
306 9
        $this->visitorActivityData = array_merge($this->visitorActivityData, $data);
307
308 9
        return $this;
309
    }
310
311
    /**
312
     * Get the stored visitor id.
313
     *
314
     * @return int
315
     */
316 6
    private function getVisitorId()
317
    {
318 6
        $tracker = $this->getVisitorTracker();
319 6
        $data    = $tracker->checkData($this->visitorData, [
320 6
            'user_id'     => $this->getUserId(),
321 6
            'device_id'   => $this->getDeviceId(),
322 6
            'client_ip'   => $this->request->getClientIp(),
323 6
            'geoip_id'    => $this->getGeoIpId(),
324 6
            'agent_id'    => $this->getAgentId(),
325 6
            'referer_id'  => $this->getRefererId(),
326 6
            'cookie_id'   => $this->getCookieId(),
327 6
            'language_id' => $this->getLanguageId(),
328 6
            'is_robot'    => $this->isRobot(),
329 6
            'user_agent'  => $this->getUserAgentTracker()->getUserAgentParser()->getOriginalUserAgent(),
330
        ]);
331
332 6
        $this->mergeVisitorData($data);
333
334 6
        return $tracker->track($this->visitorData);
335
    }
336
337
    /**
338
     * Track the path.
339
     *
340
     * @return int|null
341
     */
342
    private function getPathId()
343
    {
344 6
        return $this->trackIfEnabled('paths', function () {
345 6
            return $this->getPathTracker()->track(
346 6
                $this->request->path()
347
            );
348 6
        });
349
    }
350
351
    /**
352
     * Track the query.
353
     *
354
     * @return int|null
355
     */
356
    private function getQueryId()
357
    {
358 6
        return $this->trackIfEnabled('path-queries', function () {
359 6
            return $this->getQueryTracker()->track(
360 6
                $this->request->query()
361
            );
362 6
        });
363
    }
364
365
    /**
366
     * Get the user id.
367
     *
368
     * @return int|null
369
     */
370
    private function getUserId()
371
    {
372 6
        return $this->trackIfEnabled('users', function () {
373 6
            return $this->getUserTracker()->track();
374 6
        });
375
    }
376
377
    /**
378
     * Get the tracked device id.
379
     *
380
     * @return int|null
381
     */
382
    private function getDeviceId()
383
    {
384 6
        return $this->trackIfEnabled('devices', function () {
385 6
            return $this->getDeviceTracker()->track();
386 6
        });
387
    }
388
389
    /**
390
     * Get the tracked ip address ip.
391
     *
392
     * @return int|null
393
     */
394
    private function getGeoIpId()
395
    {
396 6
        return $this->trackIfEnabled('geoip', function () {
397 6
            return $this->getGeoIpTracker()->track(
398 6
                $this->request->getClientIp()
399
            );
400 6
        });
401
    }
402
403
    /**
404
     * Get the tracked user agent id.
405
     *
406
     * @return int|null
407
     */
408
    private function getAgentId()
409
    {
410 6
        return $this->trackIfEnabled('user-agents', function () {
411 6
            return $this->getUserAgentTracker()->track();
412 6
        });
413
    }
414
415
    /**
416
     * Get the tracked referer id.
417
     *
418
     * @return int|null
419
     */
420
    private function getRefererId()
421
    {
422 6
        return $this->trackIfEnabled('referers', function () {
423 6
            return $this->getRefererTracker()->track(
424 6
                $this->request->headers->get('referer'),
425 6
                $this->request->url()
426
            );
427 6
        });
428
    }
429
430
    /**
431
     * Get the tracked cookie id.
432
     *
433
     * @return int|null
434
     */
435
    private function getCookieId()
436
    {
437 6
        return $this->trackIfEnabled('cookies', function () {
438 6
            return ! is_null($name = $this->getConfig('cookie.name'))
439
                ? $this->getCookieTracker()->track($this->request->cookie($name))
440 6
                : null;
441 6
        });
442
    }
443
444
    /**
445
     * Get the tracked language id.
446
     *
447
     * @return int|null
448
     */
449
    private function getLanguageId()
450
    {
451 6
        return $this->trackIfEnabled('languages', function () {
452 6
            return $this->getLanguageTracker()->track();
453 6
        });
454
    }
455
456
    /**
457
     * Check if the visitor is a robot.
458
     *
459
     * @return bool
460
     */
461 6
    protected function isRobot()
462
    {
463
        /** @var  \Arcanedev\LaravelTracker\Contracts\Detectors\CrawlerDetector  $crawler */
464 6
        $crawler = $this->make(Contracts\Detectors\CrawlerDetector::class);
465
466 6
        return $crawler->isRobot();
467
    }
468
}
469