This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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
|
|||
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() |
|
0 ignored issues
–
show
It seems like
$this->request->query() targeting Illuminate\Http\Concerns...ractsWithInput::query() can also be of type string ; however, Arcanedev\LaravelTracker...s\QueryTracker::track() does only seem to accept array , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
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'), |
|
0 ignored issues
–
show
It seems like
$this->request->headers->get('referer') targeting Symfony\Component\HttpFoundation\HeaderBag::get() can also be of type array<integer,string> ; however, Arcanedev\LaravelTracker...RefererTracker::track() does only seem to accept string , maybe add an additional type check?
This check looks at variables that are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble. ![]() |
|||
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 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
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.