Completed
Push — V6 ( 23eee8...7e10de )
by Georges
02:57
created

IOHelperTrait::cleanFileName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * This file is part of phpFastCache.
5
 *
6
 * @license MIT License (MIT)
7
 *
8
 * For full copyright and license information, please see the docs/CREDITS.txt file.
9
 *
10
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
15
namespace phpFastCache\Core\Pool\IO;
16
17
use phpFastCache\Core\Pool\ExtendedCacheItemPoolInterface;
18
use phpFastCache\Exceptions\phpFastCacheIOException;
19
use phpFastCache\Util\Directory;
20
21
trait IOHelperTrait
22
{
23
    /**
24
     * @var array
25
     */
26
    public $tmp = [];
27
28
    /**
29
     * @param bool $skip_create_path
0 ignored issues
show
Bug introduced by
There is no parameter named $skip_create_path. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
30
     * @param $config
31
     * @return string
32
     * @throws phpFastCacheIOException
33
     */
34
    public function getPath($getBasePath = false)
35
    {
36
        $tmp_dir = rtrim(ini_get('upload_tmp_dir') ? ini_get('upload_tmp_dir') : sys_get_temp_dir(), '\\/') . DIRECTORY_SEPARATOR . 'phpfastcache';
37
38
        if (!isset($this->config[ 'path' ]) || $this->config[ 'path' ] == '') {
39
            if (self::isPHPModule()) {
40
                $path = $tmp_dir;
41
            } else {
42
                $document_root_path = rtrim($_SERVER[ 'DOCUMENT_ROOT' ], '/') . '/../';
43
                $path = isset($_SERVER[ 'DOCUMENT_ROOT' ]) && is_writable($document_root_path) ? $document_root_path : rtrim(__DIR__, '/') . 'PathSeekerTrait.php/';
44
            }
45
46
            if ($this->config[ 'path' ] != '') {
47
                $path = $this->config[ 'path' ];
48
            }
49
50
        } else {
51
            $path = $this->config[ 'path' ];
52
        }
53
54
        if ($getBasePath === true) {
55
            return $path;
56
        }
57
58
        $securityKey = array_key_exists('securityKey', $this->config) ? $this->config[ 'securityKey' ] : '';
59
        if (!$securityKey || $securityKey === 'auto') {
60
            if (isset($_SERVER[ 'HTTP_HOST' ])) {
61
                $securityKey = preg_replace('/^www./', '', strtolower(str_replace(':', '_', $_SERVER[ 'HTTP_HOST' ])));
62
            } else {
63
                $securityKey = ($this->isPHPModule() ? 'web' : 'cli');
64
            }
65
        }
66
67
        if ($securityKey !== '') {
68
            $securityKey .= '/';
69
        }
70
71
        $securityKey = static::cleanFileName($securityKey);
72
73
        $full_path = rtrim($path, '/') . '/' . $securityKey;
74
        $full_pathx = md5($full_path);
75
76
77
        if (!isset($this->tmp[ $full_pathx ])) {
78
79
            if (!@file_exists($full_path) || !@is_writable($full_path)) {
80
                if (!@file_exists($full_path)) {
81
                    @mkdir($full_path, $this->setChmodAuto(), true);
0 ignored issues
show
Security File Manipulation introduced by
$full_path can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER, and $_SERVER['HTTP_HOST'] is passed through str_replace(), and str_replace(':', '_', $_SERVER['HTTP_HOST']) is passed through strtolower(), and strtolower(str_replace(':', '_', $_SERVER['HTTP_HOST'])) is passed through preg_replace(), and $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 61
  2. Data is passed through trim(), and Data is passed through preg_replace()
    in vendor/src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 195
  3. $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 71
  4. $full_path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 73

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
82
                }
83
                if (!@is_writable($full_path)) {
84
                    @chmod($full_path, $this->setChmodAuto());
0 ignored issues
show
Security File Manipulation introduced by
$full_path can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER, and $_SERVER['HTTP_HOST'] is passed through str_replace(), and str_replace(':', '_', $_SERVER['HTTP_HOST']) is passed through strtolower(), and strtolower(str_replace(':', '_', $_SERVER['HTTP_HOST'])) is passed through preg_replace(), and $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 61
  2. Data is passed through trim(), and Data is passed through preg_replace()
    in vendor/src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 195
  3. $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 71
  4. $full_path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 73

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
85
                }
86
                if (!@is_writable($full_path)) {
87
                    // switch back to tmp dir again if the path is not writeable
88
                    $full_path = rtrim($tmp_dir, '/') . '/' . $securityKey;
89
                    if (!@file_exists($full_path)) {
90
                        @mkdir($full_path, $this->setChmodAuto(), true);
0 ignored issues
show
Security File Manipulation introduced by
$full_path can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER, and $_SERVER['HTTP_HOST'] is passed through str_replace(), and str_replace(':', '_', $_SERVER['HTTP_HOST']) is passed through strtolower(), and strtolower(str_replace(':', '_', $_SERVER['HTTP_HOST'])) is passed through preg_replace(), and $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 61
  2. Data is passed through trim(), and Data is passed through preg_replace()
    in vendor/src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 195
  3. $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 71
  4. $full_path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 88

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
91
                    }
92
                    if (!@is_writable($full_path)) {
93
                        @chmod($full_path, $this->setChmodAuto());
0 ignored issues
show
Security File Manipulation introduced by
$full_path can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER, and $_SERVER['HTTP_HOST'] is passed through str_replace(), and str_replace(':', '_', $_SERVER['HTTP_HOST']) is passed through strtolower(), and strtolower(str_replace(':', '_', $_SERVER['HTTP_HOST'])) is passed through preg_replace(), and $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 61
  2. Data is passed through trim(), and Data is passed through preg_replace()
    in vendor/src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 195
  3. $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 71
  4. $full_path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 88

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
94
                    }
95
                }
96
                if (!@file_exists($full_path) || !@is_writable($full_path)) {
97
                    throw new phpFastCacheIOException('PLEASE CREATE OR CHMOD ' . $full_path . ' - 0777 OR ANY WRITABLE PERMISSION!', 92);
98
                }
99
            }
100
101
            $this->tmp[ $full_pathx ] = true;
102
            $this->htaccessGen($full_path, array_key_exists('htaccess', $this->config) ? $this->config[ 'htaccess' ] : false);
103
        }
104
105
        return realpath($full_path);
106
    }
107
108
    /**
109
     * @param $keyword
110
     * @return string
111
     */
112
    protected function encodeFilename($keyword)
113
    {
114
        return md5($keyword);
115
    }
116
117
    /**
118
     * @return bool
119
     */
120
    public function isExpired()
121
    {
122
        trigger_error(__FUNCTION__ . '() is deprecated, use ExtendedCacheItemInterface::isExpired() instead.', E_USER_DEPRECATED);
123
124
        return true;
125
    }
126
127
128
    /**
129
     * @return string
130
     * @throws \phpFastCache\Exceptions\phpFastCacheCoreException
131
     */
132
    public function getFileDir()
133
    {
134
        return $this->getPath() . DIRECTORY_SEPARATOR . self::FILE_DIR;
135
    }
136
137
    /**
138
     * @param $keyword
139
     * @param bool $skip
140
     * @return string
141
     * @throws phpFastCacheIOException
142
     */
143
    private function getFilePath($keyword, $skip = false)
144
    {
145
        $path = $this->getFileDir();
146
147
        if ($keyword === false) {
148
            return $path;
149
        }
150
151
        $filename = $this->encodeFilename($keyword);
152
        $folder = substr($filename, 0, 2);
153
        $path = rtrim($path, '/') . '/' . $folder;
154
        /**
155
         * Skip Create Sub Folders;
156
         */
157
        if ($skip == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
158
            if (!file_exists($path)) {
159
                if (@!mkdir($path, $this->setChmodAuto(), true)) {
160
                    throw new phpFastCacheIOException('PLEASE CHMOD ' . $this->getPath() . ' - ' . $this->setChmodAuto() . ' OR ANY WRITABLE PERMISSION!');
161
                }
162
            }
163
        }
164
165
        return $path . '/' . $filename . '.txt';
166
    }
167
168
169
    /**
170
     * @param $this ->config
171
     * @return int
172
     */
173
    public function setChmodAuto()
174
    {
175
        if (!isset($this->config[ 'default_chmod' ]) || $this->config[ 'default_chmod' ] == '' || is_null($this->config[ 'default_chmod' ])) {
176
            return 0777;
177
        } else {
178
            return $this->config[ 'default_chmod' ];
179
        }
180
    }
181
182
    /**
183
     * @param $filename
184
     * @return mixed
185
     */
186
    protected static function cleanFileName($filename)
187
    {
188
        $regex = [
189
          '/[\?\[\]\/\\\=\<\>\:\;\,\'\"\&\$\#\*\(\)\|\~\`\!\{\}]/',
190
          '/\.$/',
191
          '/^\./',
192
        ];
193
        $replace = ['-', '', ''];
194
195
        return trim(preg_replace($regex, $replace, trim($filename)), '-');
196
    }
197
198
    /**
199
     * @param $path
200
     * @param bool $create
201
     * @throws phpFastCacheIOException
202
     */
203
    protected function htaccessGen($path, $create = true)
204
    {
205
        if ($create === true) {
206
            if (!is_writable($path)) {
207
                try {
208
                    if(!chmod($path, 0777)){
209
                        throw new phpFastCacheIOException('Chmod failed on : ' . $path);
210
                    }
211
                } catch (phpFastCacheIOException $e) {
212
                    throw new phpFastCacheIOException('PLEASE CHMOD ' . $path . ' - 0777 OR ANY WRITABLE PERMISSION!', 0, $e);
213
                }
214
            }
215
216
            if (!file_exists($path . "/.htaccess")) {
217
                $html = "order deny, allow \r\n
218
deny from all \r\n
219
allow from 127.0.0.1";
220
221
                $file = @fopen($path . '/.htaccess', 'w+');
222
                if (!$file) {
223
                    throw new phpFastCacheIOException('PLEASE CHMOD ' . $path . ' - 0777 OR ANY WRITABLE PERMISSION!');
224
                }
225
                fwrite($file, $html);
226
                fclose($file);
227
            }
228
        }
229
    }
230
231
232
    /**
233
     * @param $file
234
     * @return string
235
     * @throws phpFastCacheIOException
236
     */
237
    protected function readfile($file)
238
    {
239
        if (function_exists('file_get_contents')) {
240
            return file_get_contents($file);
0 ignored issues
show
Security File Exposure introduced by
$file can contain request data and is used in file inclusion context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER, and $_SERVER['HTTP_HOST'] is passed through str_replace(), and str_replace(':', '_', $_SERVER['HTTP_HOST']) is passed through strtolower(), and strtolower(str_replace(':', '_', $_SERVER['HTTP_HOST'])) is passed through preg_replace(), and $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 61
  2. Data is passed through trim(), and Data is passed through preg_replace()
    in vendor/src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 195
  3. $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 71
  4. $full_path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 88
  5. $full_path is passed through realpath()
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 105
  6. IOHelperTrait::getPath() returns tainted data
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 134
  7. IOHelperTrait::getFileDir() returns tainted data, and $path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 145
  8. IOHelperTrait::getFilePath() returns tainted data, and $file_path is assigned
    in src/phpFastCache/Drivers/Files/Driver.php on line 98
  9. $file_path is passed to IOHelperTrait::readfile()
    in src/phpFastCache/Drivers/Files/Driver.php on line 103

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
241
        } else {
242
            $string = '';
243
244
            $file_handle = @fopen($file, 'r');
245
            if (!$file_handle) {
246
                throw new phpFastCacheIOException("Cannot read file located at: {$file}");
247
            }
248
            while (!feof($file_handle)) {
249
                $line = fgets($file_handle);
250
                $string .= $line;
251
            }
252
            fclose($file_handle);
253
254
            return $string;
255
        }
256
    }
257
258
    /**
259
     * @param string $file
260
     * @param string $data
261
     * @param bool $secureFileManipulation
262
     * @return bool
263
     * @throws phpFastCacheIOException
264
     */
265
    protected function writefile($file, $data, $secureFileManipulation = false)
266
    {
267
        /**
268
         * @eventName CacheWriteFileOnDisk
269
         * @param ExtendedCacheItemPoolInterface $this
270
         * @param string $file
271
         * @param bool $secureFileManipulation
272
         *
273
         */
274
        $this->eventManager->dispatch('CacheWriteFileOnDisk', $this, $file, $secureFileManipulation);
0 ignored issues
show
Bug introduced by
The property eventManager does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
275
276
        if($secureFileManipulation){
277
            $tmpFilename = Directory::getAbsolutePath(dirname($file) . '/tmp_' . md5(
278
                str_shuffle(uniqid($this->getDriverName(), false))
279
                . str_shuffle(uniqid($this->getDriverName(), false))
280
              ));
281
282
            $f = fopen($tmpFilename, 'w+');
283
            flock($f, LOCK_EX);
284
            $octetWritten = fwrite($f, $data);
285
            flock($f, LOCK_UN);
286
            fclose($f);
287
288
            if(!rename($tmpFilename, $file)){
0 ignored issues
show
Security File Manipulation introduced by
$file can contain request data and is used in file manipulation context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Fetching key HTTP_HOST from $_SERVER, and $_SERVER['HTTP_HOST'] is passed through str_replace(), and str_replace(':', '_', $_SERVER['HTTP_HOST']) is passed through strtolower(), and strtolower(str_replace(':', '_', $_SERVER['HTTP_HOST'])) is passed through preg_replace(), and $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 61
  2. Data is passed through trim(), and Data is passed through preg_replace()
    in vendor/src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 195
  3. $securityKey is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 71
  4. $full_path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 88
  5. $full_path is passed through realpath()
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 105
  6. IOHelperTrait::getPath() returns tainted data
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 134
  7. IOHelperTrait::getFileDir() returns tainted data, and $path is assigned
    in src/phpFastCache/Core/Pool/IO/IOHelperTrait.php on line 145
  8. IOHelperTrait::getFilePath() returns tainted data, and $file_path is assigned
    in src/phpFastCache/Drivers/Files/Driver.php on line 73
  9. $file_path is passed to IOHelperTrait::writefile()
    in src/phpFastCache/Drivers/Files/Driver.php on line 80

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
289
                throw new phpFastCacheIOException(sprintf('Failed to rename %s to %s', $tmpFilename, $file));
290
            }
291
        }else{
292
            $f = fopen($file, 'w+');
293
            $octetWritten = fwrite($f, $data);
294
            fclose($f);
295
        }
296
297
        return $octetWritten !== false;
298
    }
299
}