GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (4873)

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/common/frs/FRSFile.class.php (3 issues)

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
 * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
4
 * Copyright (c) Enalean, 2015. All Rights Reserved.
5
 *
6
 * This file is a part of Tuleap.
7
 *
8
 * Tuleap is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * Tuleap is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
require_once('common/include/Error.class.php');
23
require_once('FRSReleaseFactory.class.php');
24
require_once('common/include/Codendi_HTTP_Download.php');
25
26
class FRSFile extends Error {
27
28
    const EVT_CREATE  = 301;
29
    const EVT_UPDATE  = 302;
30
    const EVT_DELETE  = 303;
31
    const EVT_RESTORE = 304;
32
33
    /**
34
     * This is an arbitrary chosen hard coded limit in order to avoid
35
     * download of files that exceed the php memory_limit
36
     * set to 196M using the standard download mechanism
37
     * which places these files in the memory causing overflows.
38
     * It will use php-pear-HTTP-download instead if it is installed
39
     * on the system.
40
     */
41
    const HARD_CODED_150MB_MEMORY_LIMIT = 157286400;
42
43
    /**
44
     * A 8 kb buffer size
45
     */
46
    const PEAR_BUFFER_SIZE = 8192;
47
48
	/**
49
     * @var int $file_id the ID of this FRSFile
50
     */
51
    var $file_id;	
52
    /**
53
     * @var String $filename the name of this FRSFile
54
     */
55
    var $filename;
56
    /**
57
     * @var String $filepath the full path where the file is created  
58
     */
59
    var $filepath;
60
    /**
61
     * @var int $release_id the ID of the release this FRSFile belong to
62
     */
63
    var $release_id;
64
    /**
65
     * @var int $type_id the ID of the type of this FRSFile
66
     */
67
    var $type_id;
68
    /**
69
     * @var int $processor_id the ID of the processor to use with this FRSFile
70
     */
71
    var $processor_id;
72
    /**
73
     * @var int $release_time the ??? of this FRSFile
74
     */
75
    var $release_time;
76
    /**
77
     * @var int $file_size the size of this FRSFile
78
     */
79
    var $file_size;
80
    /**
81
     * @var int $post_date the ??? of this FRSFile
82
     */
83
    var $post_date;
84
    /**
85
     * @var string $status the status of this FRSFile (A=>Active; D=>Deleted)
86
     */
87
    var $status;
88
    /**
89
     * @var string $computed_md5 hash of the file computed in server side
90
     */
91
    var $computed_md5;
92
    /**
93
     * @var string $reference_md5 hash of the file submited by user (calculated in client side)
94
     */
95
    var $reference_md5;
96
    /**
97
     * @var integer $user_id id of user that created the file
98
     */
99
    var $user_id;
100
    /**
101
     * @var string $file_location the full path of this FRSFile
102
     */
103
    var $file_location;
104
105
    /**
106
     *
107
     * @var string comment/description of the file
108
     */
109
    private $comment;
110
111
    /**
112
     * @var FRSRelease $release The release the file belongs to
113
     */
114
    protected $release;
115
    
116
    function FRSFile($data_array = null) {
117
        $this->file_id       = null;
118
        $this->filename     = null;
119
        $this->filepath     = null;
120
        $this->release_id    = null;
121
        $this->type_id       = null;
122
        $this->processor_id  = null;
123
        $this->release_time  = null;
124
        $this->file_size     = null;
125
        $this->post_date     = null;
126
        $this->status        = null;
127
        $this->computed_md5  = null;
128
        $this->reference_md5 = null;
129
        $this->user_id       = null;
130
        $this->file_location = null;
131
        $this->comment       = null;
132
133
        if ($data_array) {
134
            $this->initFromArray($data_array);
135
        }
136
    }
137
    
138
    function getFileID() {
139
        return $this->file_id;
140
    }
141
    
142
    function setFileID($file_id) {
143
        $this->file_id = (int) $file_id;
144
    }
145
    
146
    function getFileName() {
147
        return $this->filename;
148
    }
149
150
    function setFileName($filename) {
151
        $this->filename = $filename;
152
    }
153
154
    /**
155
     * Obtain the name of the file as stored in filesystem
156
     * Old files are stored in the filesystem as uploaded by the user
157
     * In that case filepath == NULL then the returned value is filename
158
     *
159
     * @return String
160
     */
161
    function getFilePath() {
162
        if ($this->filepath == null) {
163
            return $this->filename;
164
        } else {
165
            return $this->filepath;
166
        }
167
    }
168
169
    function setFilePath($filepath) {
170
        $this->filepath = $filepath;
171
    }
172
173
    function getReleaseID() {
174
        return $this->release_id;
175
    }
176
    
177
    function setReleaseID($release_id) {
178
        $this->release_id = (int) $release_id;
179
    }
180
    
181
    function getTypeID() {
182
        return $this->type_id;
183
    }
184
    
185
    function setTypeID($type_id) {
186
        $this->type_id = (int) $type_id;
187
    }
188
    
189
    function getProcessorID() {
190
        return $this->processor_id;
191
    }
192
    
193
    function setProcessorID($processor_id) {
194
        $this->processor_id = (int) $processor_id;
195
    }
196
    
197
    function getReleaseTime() {
198
        return $this->release_time;
199
    }
200
    
201
    function setReleaseTime($release_time) {
202
        $this->release_time = (int) $release_time;
203
    }
204
    
205
    function setFileLocation($location) {
206
        $this->file_location = $location;
207
    }
208
    
209
    /**
210
     * Returns the location of the file on the server
211
     *
212
     * @global $GLOBALS['ftp_frs_dir_prefix']
213
     * @return string the location of this file on the server
214
     */
215
    function getFileLocation() {
216
        if ($this->file_location == null) {
217
            $group = $this->getGroup();
218
            $group_unix_name = $group->getUnixName(false);
219
            $basename = $this->getFilePath();
220
            $this->file_location = $GLOBALS['ftp_frs_dir_prefix'].'/'.$group_unix_name.'/'.$basename;
221
        }
222
        return $this->file_location;
223
    }
224
225
    function getFileSize() {
226
        if ($this->file_size == null) {
227
            $file_location = $this->getFileLocation();
228
            // Use file_utils to provide a workaround for the 2 GB limitation
229
            $this->file_size = file_utils_get_size($file_location);
230
        }
231
        return $this->file_size;
232
    }
233
    
234
    function setFileSize($file_size) {
235
        $this->file_size = $file_size;
236
    }
237
    
238
    static function convertBytesToKbytes($size_in_bytes, $decimals_precision = 0) {
239
        $size_in_kbytes = $size_in_bytes / 1024;
240
        
241
        $decimal_separator = $GLOBALS['Language']->getText('system','decimal_separator');
242
        $thousand_separator = $GLOBALS['Language']->getText('system','thousand_separator'); 
243
        // because I don't know how to specify a space in a .tab file
244
        if ($thousand_separator == "' '") {
245
            $thousand_separator = ' ';  
246
        }
247
        return number_format($size_in_kbytes, $decimals_precision, $decimal_separator, $thousand_separator); 
248
    }
249
250
    function getDisplayFileSize() {
251
        $decimals_precision = 0;
252
        if ($this->getFileSize() < 1024) {
253
            $decimals_precision = 2;
254
        }
255
        return $this->convertBytesToKbytes($this->getFileSize(), $decimals_precision);
256
    }
257
    
258
    function getPostDate() {
259
        return $this->post_date;
260
    }
261
    
262
    function setPostDate($post_date) {
263
        $this->post_date = (int) $post_date;
264
    }
265
    
266
    function getStatus() {
267
        return $this->status;
268
    }
269
    
270
    function setStatus($status) {
271
        $this->status = $status;
272
    }
273
    
274
    function isActive() {
275
        return ($this->status == 'A');
276
    }
277
    
278
    function isDeleted() {
279
        return ($this->status == 'D');
280
    }
281
282
    function setComputedMd5($computedMd5) {
283
        $this->computed_md5 = $computedMd5;
284
    }
285
286
    function getComputedMd5() {
287
        return $this->computed_md5;
288
    }
289
290
    function setReferenceMd5($referenceMd5) {
291
        $this->reference_md5 = $referenceMd5;
292
    }
293
294
    function getReferenceMd5() {
295
        return $this->reference_md5;
296
    }
297
298
    function setUserID($userId) {
299
        $this->user_id = $userId;
300
    }
301
302
    function getUserID() {
303
        return $this->user_id;
304
    }
305
306
    function setRelease($release) {
307
        $this->release    = $release;
308
        $this->release_id = $release->getReleaseID();
309
    }
310
311
    function getRelease() {
312
        return $this->release;
313
    }
314
315
    public function getComment() {
316
        return $this->comment;
317
    }
318
319
    public function setComment($comment) {
320
        $this->comment = $comment;
321
    }
322
323
	function initFromArray($array) {
324
		if (isset($array['file_id']))       $this->setFileID($array['file_id']);
325
		if (isset($array['filename']))      $this->setFileName($array['filename']);
326
        if (isset($array['filepath']))      $this->setFilePath($array['filepath']);
327
		if (isset($array['release_id']))    $this->setReleaseID($array['release_id']);
328
        if (isset($array['type_id']))       $this->setTypeID($array['type_id']);
329
        if (isset($array['processor_id']))  $this->setProcessorID($array['processor_id']);
330
        if (isset($array['release_time']))  $this->setReleaseTime($array['release_time']);
331
        if (isset($array['file_size']))     $this->setFileSize($array['file_size']);
332
        if (isset($array['post_date']))     $this->setPostDate($array['post_date']);
333
        if (isset($array['status']))        $this->setStatus($array['status']);
334
        if (isset($array['computed_md5']))  $this->setComputedMd5($array['computed_md5']);
335
        if (isset($array['reference_md5'])) $this->setReferenceMd5($array['reference_md5']);
336
        if (isset($array['user_id']))       $this->setUserID($array['user_id']);
337
        if (isset($array['comment']))       $this->setComment($array['comment']);
338
    }
339
340
    function toArray() {
341
        $array = array();
342
        $array['file_id']       = $this->getFileID();
343
        $array['filename']      = $this->getFileName();
344
        $array['filepath']      = $this->getFilePath();
345
        $array['release_id']    = $this->getReleaseID();
346
        $array['type_id']       = $this->getTypeID();
347
        $array['processor_id']  = $this->getProcessorID();
348
        $array['release_time']  = $this->getReleaseTime();
349
        $array['file_location'] = $this->getFileLocation();
350
        $array['file_size']     = $this->getFileSize();
351
        $array['post_date']     = $this->getPostDate();
352
        $array['status']        = $this->getStatus();
353
        $array['computed_md5']  = $this->getComputedMd5();
354
        $array['reference_md5'] = $this->getReferenceMd5();
355
        $array['user_id']       = $this->getUserID();
356
        $array['comment']       = $this->getComment();
357
        
358
        return $array;
359
    }
360
    
361
    var $dao;
362
    
363
    function &_getFRSFileDao() {
364
        if (!$this->dao) {
365
            $this->dao = new FRSFileDao(CodendiDataAccess::instance());
366
        }
367
        return $this->dao;
368
    }
369
    
370
    /**
371
     * Determine if the file exists really on the server or not
372
     *
373
     * @return boolean true if the file exists on the server, false otherwise
374
     */
375
    function fileExists() {
376
        return file_exists($this->getFileLocation());
377
    }
378
    
379
    /**
380
     * Get the Package ID of this File
381
     *
382
     * @return int the packahe ID of this file
383
     */
384
    function getPackageID() {
385
        // retrieve the release the file belongs to
386
        $release_id = $this->getReleaseID();
387
        $release_fact = new FRSReleaseFactory();
388
        $release =& $release_fact->getFRSReleaseFromDb($release_id);
389
        $package_id = $release->getPackageID();
390
        return $package_id;
391
    }
392
    
393
    
394
    /**
395
     * Get the Group (the project) of this File
396
     *
397
     * @return Object{Group} the group the file belongs to
0 ignored issues
show
The doc-type Object{Group} could not be parsed: Unknown type name "Object{Group}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
398
     */
399
    function getGroup() {
400
        $pm = ProjectManager::instance();
401
        // retrieve the release the file belongs to
402
        $release_id = $this->getReleaseID();
403
        $release_fact = new FRSReleaseFactory();
404
        $release = $release_fact->getFRSReleaseFromDb($release_id, null, null, FRSReleaseDao::INCLUDE_DELETED);
405
        $group_id = $release->getGroupID();
406
        $group = $pm->getProject($group_id);
407
        return $group;
408
    }
409
410
    /**
411
     * Returns the content of the file, in a raw resource
412
     *
413
     * +2GB safe
414
     *
415
     * @return mixed the content of the file
416
     */
417
    function getContent($offset=0, $size=-1) {
418
        if ($size == -1) {
419
            $size = $this->getFileSize();
420
        }
421
        $path = PHP_BigFile::stream(realpath($this->getFileLocation()));
422
        return file_get_contents($path, false, NULL, $offset, $size);
423
    }
424
425
    /**
426
     * Log the download of the file in the log system
427
     * 
428
     * Only log one download attempt per file/user/hour. Driven by SOAP:getFileChunk
429
     * in order to reduce the amount of download attempt logged.
430
     * 
431
     * @param int $user_id the user that download the file (if 0, the current user will be taken)
432
     * @return boolean true if there is no error, false otherwise
433
     */
434
    function LogDownload($user_id = 0) {
435
        if ($user_id == 0) {
436
            $user_id = UserManager::instance()->getCurrentUser()->getId();
437
        }
438
        $time = $_SERVER['REQUEST_TIME'] - 3600;
439
        $dao  = $this->_getFrsFileDao();
440
        if (!$dao->existsDownloadLogSince($this->getFileID(), $user_id, $time)) {
441
            return $dao->logDownload($this, $user_id);
442
        }
443
        return true;
444
    }
445
446
    /**
447
     * userCanDownload : determine if the user can download the file or not
448
     *
449
     * WARNING : for the moment, user can download the file if the user can view the package and can view the release the file belongs to.  
450
     *  
451
     * @param int $user_id the ID of the user. If $user_id is 0, then we take the current user.
452
     * @return boolean true if the user has permissions to download the file, false otherwise
453
     */
454
    function userCanDownload($user_id = 0) {
455
        if ($user_id == 0) {
456
            $user_id = user_getid();
457
        }
458
        
459
        $user = UserManager::instance()->getUserById($user_id);
460
        if ($user) {
461
            if ($user->isSuperUser()) {
462
                return true;
463
            }
464
        }
465
        
466
        $user_can_download = false;
467
        if (! $this->isDeleted()) { 
468
            $group = $this->getGroup();
469
            $group_id = $group->getID();
470
            if (permission_exist('RELEASE_READ', $this->getReleaseID())) {
471
                if (permission_is_authorized('RELEASE_READ',$this->getReleaseID(),$user_id,$group_id)) {
472
                    $user_can_download = true;
473
                } 
474
            } else if (permission_is_authorized('PACKAGE_READ',$this->getPackageID(),$user_id,$group_id)) {
475
                $user_can_download = true;
476
            }
477
        }
478
        return $user_can_download; 	
0 ignored issues
show
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
479
    }
480
  
481
    /**
482
     * download : download the file, i.e. print it to stdout
483
     *
484
     * WARNING : this function does not check permissions, nor does it log the download  
485
     *  
486
     * @return boolean true if the user has permissions to download the file, false otherwise
487
     */
488
    function download() {
489
        $file_location = $this->getFileLocation();
490
        if ($this->fileSizeExceedsMemoryLimit() && $this->phpPearHttpDownloadExtensionIsInstalled()) {
491
            return !PEAR::isError(Codendi_HTTP_Download::staticSend(array(
492
                'file'               => $this->getFileLocation(),
493
                'cache'              => false,
494
                'contentdisposition' => array(HTTP_DOWNLOAD_ATTACHMENT, basename($this->getFileName())),
495
                'buffersize'         => self::PEAR_BUFFER_SIZE,
496
                )
497
            ));
498
        } else { //old school to be removed in 4.2
499
        $file_size = $this->getFileSize();
500
501
        // Make sure this URL is not cached anywhere otherwise download
502
        // would be wrong
503
        header('Expires: Mon, 26 Nov 1962 00:00:00 GMT');
504
        header('Pragma: private');
505
        header('Cache-control: private, must-revalidate');
506
        
507
        header("Content-Type: application/octet-stream");
508
        header('Content-Disposition: attachment; filename="'. basename($this->getFileName()) .'"');
509
        if ($file_size > 0){
510
            header("Content-Length:  $file_size");
511
        }
512
        header("Content-Transfer-Encoding: binary\n");
513
514
        //reset time limit for big files
515
        set_time_limit(0);
516
        flush();
517
518
        // Now transfer the file to the client
519
520
        // Check the 2 GB limit (2^31 -1)
521
        if ($file_size > 2147483647) {
522
            if ($fp=popen('/bin/cat "' . escapeshellarg($file_location) . '"',"rb")) {
523
                $blocksize = (2 << 20); //2M chunks
524
                while(!feof($fp)) {
525
                    print(fread($fp, $blocksize));
526
                }
527
                flush();
528
                pclose($fp);
529
            } else return false;
530
        } else if (readfile($file_location) == false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing readfile($file_location) of type integer to the boolean false. If you are specifically checking for 0, consider using something more explicit like === 0 instead.
Loading history...
531
            return false;
532
        }
533
            
534
        return true;
535
        }
536
    }
537
538
    private function fileSizeExceedsMemoryLimit() {
539
        return $this->getFileSize() > self::HARD_CODED_150MB_MEMORY_LIMIT;
540
    }
541
542
    private function phpPearHttpDownloadExtensionIsInstalled() {
543
        return class_exists('Codendi_HTTP_Download');
544
    }
545
    
546
    /**
547
     * Returns the HTML content for tooltip when hover a reference with the nature file
548
     * @returns string HTML content for file tooltip
549
     */
550
    function getReferenceTooltip() {
551
        $tooltip = '';
552
        $rf = new FRSReleaseFactory();
553
        $pf = new FRSPackageFactory();
554
        $release_id = $this->getReleaseID();
555
        $release = $rf->getFRSReleaseFromDb($release_id);
556
        $package_id = $release->getPackageID();
557
        $package = $pf->getFRSPackageFromDb($package_id);
558
        $tooltip .= '<table>';
559
        $tooltip .= ' <tr>';
560
        $tooltip .= '  <td><strong>' . $GLOBALS['Language']->getText('file_admin_editreleases', 'filename') . ':</strong></td>';
561
        $tooltip .= '  <td>'.basename($this->getFileName()).'</td>';
562
        $tooltip .= ' </tr>';
563
        $tooltip .= ' <tr>';
564
        $tooltip .= '  <td><strong>' . $GLOBALS['Language']->getText('file_ref_tooltip', 'package_release') . ':</strong></td>';
565
        $tooltip .= '  <td>'.$package->getName().' / '.$release->getName().'</td>';
566
        $tooltip .= ' </tr>';
567
        $tooltip .= ' <tr>';
568
        $tooltip .= '  <td><strong>' . $GLOBALS['Language']->getText('file_showfiles', 'date') . ':</strong></td>';
569
        $tooltip .= '  <td>'.format_date($GLOBALS['Language']->getText('system', 'datefmt_short'), $release->getReleaseDate()).'</td>';
570
        $tooltip .= ' </tr>';
571
        $tooltip .= ' <tr>';
572
        $tooltip .= '  <td><strong>' . $GLOBALS['Language']->getText('file_showfiles', 'size') . ':</strong></td>';
573
        $tooltip .= '  <td>'.$this->getDisplayFileSize().'</td>';
574
        $tooltip .= ' </tr>';
575
        $tooltip .= '</table>';
576
        return $tooltip;
577
    }
578
    
579
}
580
581
?>
582