scratch – Diff between revs 91 and 93

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 91 Rev 93
1 <?php 1 <?php
2   2  
3 ########################################################################### 3 ###########################################################################
4 ## Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3 ## 4 ## Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3 ##
5 ########################################################################### 5 ###########################################################################
6   6  
7 require_once('php/pseudocrypt.php'); 7 require_once('php/pseudocrypt.php');
8 require_once('php/functions.php'); 8 require_once('php/functions.php');
9 require_once('vendor/autoload.php'); 9 require_once('vendor/autoload.php');
10   10  
11 ### Load configuration. 11 ### Load configuration.
12 $config = spyc_load_file('config.yaml'); 12 $config = spyc_load_file('config.yaml');
13   13  
14 #### POST -> upload / GET -> download 14 #### POST -> upload / GET -> download
15 switch ($_SERVER['REQUEST_METHOD']) { 15 switch ($_SERVER['REQUEST_METHOD']) {
16 case 'POST': 16 case 'POST':
-   17 #### Script restrictions.
-   18 if(
-   19 (
-   20 !isset($_SERVER['HTTP_X_REQUESTED_WITH']) ||
-   21 empty($_SERVER['HTTP_X_REQUESTED_WITH']) ||
-   22 strtoupper($_SERVER['HTTP_X_REQUESTED_WITH']) != 'XMLHTTPREQUEST'
-   23 )
-   24 ||
-   25 (
-   26 (
-   27 !isset($_SERVER['HTTP_REFERER']) ||
-   28 empty($_SERVER['HTTP_REFERER'])
-   29 )
-   30 &&
-   31 (
-   32 strtoupper($_SERVER['HTTP_REFERER']) != strtoupper($config['URL_PATH'].'FILE.HTML') ||
-   33 strtoupper($_SERVER['HTTP_REFERER']) != strtoupper($config['URL_PATH'].'TEXT.HTML')
-   34 )
-   35 )
-   36 )
-   37 {
-   38 http_response_code(403);
-   39 die('Forbidden.');
-   40 }
17 #### Retrieve uploaded file. 41 #### Retrieve uploaded file.
18 if (!empty($_FILES['file']) and 42 if (!empty($_FILES['file']) and
19 is_uploaded_file($_FILES['file']['tmp_name'])) { 43 is_uploaded_file($_FILES['file']['tmp_name'])) {
20 if($_FILES['file']['size'] > $config['ALLOWED_ASSET_SIZE'] * 1048576) { 44 if($_FILES['file']['size'] > $config['ALLOWED_ASSET_SIZE'] * 1048576) {
21 http_response_code(403); 45 http_response_code(403);
22 die('File size exceeds '.$config['ALLOWED_ASSET_SIZE'].'MiB.'); 46 die('File size exceeds '.$config['ALLOWED_ASSET_SIZE'].'MiB.');
23 } 47 }
24 # Regular multipart/form-data upload. 48 # Regular multipart/form-data upload.
25 $name = $_FILES['file']['name']; 49 $name = $_FILES['file']['name'];
26 $data = atomized_get_contents($_FILES['file']['tmp_name']); 50 $data = atomized_get_contents($_FILES['file']['tmp_name']);
27 } else { 51 } else {
28 if((int)get_file_size("php://input") > $config['ALLOWED_ASSET_SIZE'] * 1048576) { 52 if((int)get_file_size("php://input") > $config['ALLOWED_ASSET_SIZE'] * 1048576) {
29 http_response_code(403); 53 http_response_code(403);
30 die('File size exceeds '.$config['ALLOWED_ASSET_SIZE'].'MiB.'); 54 die('File size exceeds '.$config['ALLOWED_ASSET_SIZE'].'MiB.');
31 } 55 }
32 # Raw POST data. 56 # Raw POST data.
33 $name = urldecode(@$_SERVER['HTTP_X_FILE_NAME']); 57 $name = urldecode(@$_SERVER['HTTP_X_FILE_NAME']);
34 $data = atomized_get_contents("php://input"); 58 $data = atomized_get_contents("php://input");
35 } 59 }
36   60  
37 #### Grab the file extension. 61 #### Grab the file extension.
38 $fileExtension = pathinfo($name, PATHINFO_EXTENSION); 62 $fileExtension = pathinfo($name, PATHINFO_EXTENSION);
39   63  
40 #### If the extension is not allowed then change it to a text extension. 64 #### If the extension is not allowed then change it to a text extension.
41 if (!isset($fileExtension) || 65 if (!isset($fileExtension) ||
42 !in_array(strtoupper($fileExtension), 66 !in_array(strtoupper($fileExtension),
43 array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS']))) { 67 array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS']))) {
44 http_response_code(403); 68 http_response_code(403);
45 die('File extension not allowed.'); 69 die('File extension not allowed.');
46 } 70 }
47 71
48 #### Hash filename. 72 #### Hash filename.
49 $file = strtolower( 73 $file = strtolower(
50 PseudoCrypt::hash( 74 PseudoCrypt::hash(
51 preg_replace( 75 preg_replace(
52 '/\D/', 76 '/\D/',
53 '', 77 '',
54 hash( 78 hash(
55 'sha512', 79 'sha512',
56 $data 80 $data
57 ) 81 )
58 ), 82 ),
59 $config['ASSET_HASH_SIZE'] 83 $config['ASSET_HASH_SIZE']
60 ) 84 )
61 ); 85 );
62   86  
63 #### Build the user path. 87 #### Build the user path.
64 $userPath = join( 88 $userPath = join(
65 DIRECTORY_SEPARATOR, 89 DIRECTORY_SEPARATOR,
66 array( 90 array(
67 $config['STORE_FOLDER'], 91 $config['STORE_FOLDER'],
68 $file 92 $file
69 ) 93 )
70 ); 94 );
71   95  
72 #### Check for path traversals 96 #### Check for path traversals
73 $pathPart = pathinfo($userPath.'.'.$fileExtension); 97 $pathPart = pathinfo($userPath.'.'.$fileExtension);
74 if (strcasecmp( 98 if (strcasecmp(
75 realpath($pathPart['dirname']), realpath($config['STORE_FOLDER'])) != 0) { 99 realpath($pathPart['dirname']), realpath($config['STORE_FOLDER'])) != 0) {
76 http_response_code(500); 100 http_response_code(500);
77 die('Internal server error.'); 101 die('Internal server error.');
78 } 102 }
79   103  
80 #### Store the file. 104 #### Store the file.
81 $timestamp = atomized_put_contents($userPath.'.'.$fileExtension, $data); 105 $timestamp = atomized_put_contents($userPath.'.'.$fileExtension, $data);
82   106  
83 ### Hook for various file extensions. 107 ### Hook for various file extensions.
84 $opengraph = FALSE; 108 $opengraph = FALSE;
85 switch(strtoupper($fileExtension)) { 109 switch(strtoupper($fileExtension)) {
86 case 'GIF': 110 case 'GIF':
87 $opengraph = TRUE; 111 $opengraph = TRUE;
88 break; 112 break;
89 } 113 }
90   114  
91 ### Return the URL to the file. 115 ### Return the URL to the file.
92 header('Content-Type: text/plain; charset=utf-8'); 116 header('Content-Type: text/plain; charset=utf-8');
93 echo json_encode( 117 echo json_encode(
94 array( 118 array(
95 "hash" => $file, 119 "hash" => $file,
96 "timestamp" => $timestamp, 120 "timestamp" => $timestamp,
97 "opengraph" => $opengraph 121 "opengraph" => $opengraph
98 ) 122 )
99 ); 123 );
100 break; 124 break;
101 case 'GET': 125 case 'GET':
102 ### Tell browser not to cache files. 126 ### Tell browser not to cache files.
103 header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); 127 header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
104 header("Cache-Control: post-check=0, pre-check=0", false); 128 header("Cache-Control: post-check=0, pre-check=0", false);
105 header("Pragma: no-cache"); 129 header("Pragma: no-cache");
106 130
107 ### If no file has been specified for download then return. 131 ### If no file has been specified for download then return.
108 if (!isset($_GET['hash']) or empty($_GET['hash'])) { 132 if (!isset($_GET['hash']) or empty($_GET['hash'])) {
109 http_response_code(404); 133 http_response_code(404);
110 die('File not found.'); 134 die('File not found.');
111 } 135 }
112   136  
113 ### Find the requested file. 137 ### Find the requested file.
114 $file = array_shift( 138 $file = array_shift(
115 preg_grep( 139 preg_grep(
116 '/'.$_GET['hash'].'/', 140 '/'.$_GET['hash'].'/',
117 scandir($config['STORE_FOLDER']) 141 scandir($config['STORE_FOLDER'])
118 ) 142 )
119 ); 143 );
120   144  
121 if (!isset($file) or empty($file)) { 145 if (!isset($file) or empty($file)) {
122 http_response_code(404); 146 http_response_code(404);
123 die('File not found.'); 147 die('File not found.');
124 } 148 }
125 149
126 ### Check the path for path traversals. 150 ### Check the path for path traversals.
127 $fileExtension = pathinfo($file, PATHINFO_EXTENSION); 151 $fileExtension = pathinfo($file, PATHINFO_EXTENSION);
128   152  
129 #### If the extension is not allowed then return. 153 #### If the extension is not allowed then return.
130 if (!isset($fileExtension) || 154 if (!isset($fileExtension) ||
131 !in_array(strtoupper($fileExtension), 155 !in_array(strtoupper($fileExtension),
132 array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS']))) { 156 array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS']))) {
133 http_response_code(403); 157 http_response_code(403);
134 die('File extension not allowed.'); 158 die('File extension not allowed.');
135 } 159 }
136 160
137 #### Build the user path. 161 #### Build the user path.
138 $userPath = join( 162 $userPath = join(
139 DIRECTORY_SEPARATOR, 163 DIRECTORY_SEPARATOR,
140 array( 164 array(
141 $config['STORE_FOLDER'], 165 $config['STORE_FOLDER'],
142 $file 166 $file
143 ) 167 )
144 ); 168 );
145   169  
146 #### Check for path traversals 170 #### Check for path traversals
147 $pathPart = pathinfo($userPath); 171 $pathPart = pathinfo($userPath);
148 if (strcasecmp( 172 if (strcasecmp(
149 realpath($pathPart['dirname']), realpath($config['STORE_FOLDER'])) != 0) { 173 realpath($pathPart['dirname']), realpath($config['STORE_FOLDER'])) != 0) {
150 http_response_code(500); 174 http_response_code(500);
151 die('Internal server error.'); 175 die('Internal server error.');
152 } 176 }
153   177  
154 ### Hook for various file extensions. 178 ### Hook for various file extensions.
155 switch(strtoupper($fileExtension)) { 179 switch(strtoupper($fileExtension)) {
156 case "HTML": 180 case "HTML":
157 case "HTM": 181 case "HTM":
158 header('Content-type: text/html'); 182 header('Content-type: text/html');
159 break; 183 break;
160 break; 184 break;
161 case "URL": 185 case "URL":
162 if(preg_match( 186 if(preg_match(
163 "/URL=(https?:\/\/[\-_\.\+!\*'\(\),a-zA-Z0-9]+:?[0-9]{0,5}\/.*?)\n/", 187 "/URL=(https?:\/\/[\-_\.\+!\*'\(\),a-zA-Z0-9]+:?[0-9]{0,5}\/.*?)\n/",
164 file_get_contents($userPath), $matches)) { 188 file_get_contents($userPath), $matches)) {
165 header('Location: '.$matches[1]); 189 header('Location: '.$matches[1]);
166 return; 190 return;
167 } 191 }
168 break; 192 break;
169 default: 193 default:
170 ### Open MIME info database and send the content type. 194 ### Open MIME info database and send the content type.
171 $finfo = finfo_open(FILEINFO_MIME_TYPE); 195 $finfo = finfo_open(FILEINFO_MIME_TYPE);
172 if (!$finfo) { 196 if (!$finfo) {
173 http_response_code(500); 197 http_response_code(500);
174 die('Internal server error.'); 198 die('Internal server error.');
175 } 199 }
176 header('Content-type: '.finfo_file($finfo, $userPath)); 200 header('Content-type: '.finfo_file($finfo, $userPath));
177 finfo_close($finfo); 201 finfo_close($finfo);
178 break; 202 break;
179 } 203 }
180 204
181 ### Send the file along with the inline content disposition. 205 ### Send the file along with the inline content disposition.
182 header('Content-length: '.(int)get_file_size($userPath)); 206 header('Content-length: '.(int)get_file_size($userPath));
183 header('Content-Disposition: inline; filename="' . basename($userPath) . '"'); 207 header('Content-Disposition: inline; filename="' . basename($userPath) . '"');
184 header('Content-Transfer-Encoding: binary'); 208 header('Content-Transfer-Encoding: binary');
185 header('X-Sendfile: '.$userPath); 209 header('X-Sendfile: '.$userPath);
186 break; 210 break;
187 } 211 }
188   212