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.
1 | <?php |
||
2 | /** |
||
3 | * Teampass - a collaborative passwords manager. |
||
4 | * --- |
||
5 | * This library is distributed in the hope that it will be useful, |
||
6 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
7 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
8 | * --- |
||
9 | * |
||
10 | * @project Teampass |
||
11 | * @version API |
||
12 | * |
||
13 | * @file ItemControler.php |
||
14 | * --- |
||
15 | * |
||
16 | * @author Nils Laumaillé ([email protected]) |
||
17 | * |
||
18 | * @copyright 2009-2025 Teampass.net |
||
19 | * |
||
20 | * @license https://spdx.org/licenses/GPL-3.0-only.html#licenseText GPL-3.0 |
||
21 | * --- |
||
22 | * |
||
23 | * @see https://www.teampass.net |
||
24 | */ |
||
25 | |||
26 | use Symfony\Component\HttpFoundation\Request AS symfonyRequest; |
||
27 | |||
28 | class ItemController extends BaseController |
||
0 ignored issues
–
show
|
|||
29 | { |
||
30 | |||
31 | |||
32 | /** |
||
33 | * Manage case inFolder - get items inside an array of folders |
||
34 | * |
||
35 | * @param array $userData |
||
36 | */ |
||
37 | public function inFoldersAction(array $userData): void |
||
38 | { |
||
39 | $request = symfonyRequest::createFromGlobals(); |
||
40 | $requestMethod = $request->getMethod(); |
||
41 | $strErrorDesc = $responseData = $strErrorHeader = ''; |
||
42 | |||
43 | // get parameters |
||
44 | $arrQueryStringParams = $this->getQueryStringParams(); |
||
45 | |||
46 | if (strtoupper($requestMethod) === 'GET') { |
||
47 | // define WHERE clause |
||
48 | $sqlExtra = ''; |
||
49 | if (empty($userData['folders_list']) === false) { |
||
50 | $userData['folders_list'] = explode(',', $userData['folders_list']); |
||
51 | } else { |
||
52 | $userData['folders_list'] = []; |
||
53 | } |
||
54 | |||
55 | // SQL where clause with folders list |
||
56 | if (isset($arrQueryStringParams['folders']) === true) { |
||
57 | // convert the folders to an array |
||
58 | $arrQueryStringParams['folders'] = explode(',', str_replace( array('[',']') , '' , $arrQueryStringParams['folders'])); |
||
59 | |||
60 | // ensure to only use the intersection |
||
61 | $foldersList = implode(',', array_intersect($arrQueryStringParams['folders'], $userData['folders_list'])); |
||
62 | |||
63 | // build sql where clause |
||
64 | if (!empty($foldersList)) { |
||
65 | // build sql where clause |
||
66 | $sqlExtra = ' WHERE id_tree IN ('.$foldersList.')'; |
||
67 | } else { |
||
68 | // Send error |
||
69 | $this->sendOutput( |
||
70 | json_encode(['error' => 'Folders are mandatory']), |
||
71 | ['Content-Type: application/json', 'HTTP/1.1 401 Expected parameters not provided'] |
||
72 | ); |
||
73 | } |
||
74 | } else { |
||
75 | // Send error |
||
76 | $this->sendOutput( |
||
77 | json_encode(['error' => 'Folders are mandatory']), |
||
78 | ['Content-Type: application/json', 'HTTP/1.1 401 Expected parameters not provided'] |
||
79 | ); |
||
80 | } |
||
81 | |||
82 | // SQL LIMIT |
||
83 | $intLimit = 0; |
||
84 | if (isset($arrQueryStringParams['limit']) === true) { |
||
85 | $intLimit = $arrQueryStringParams['limit']; |
||
86 | } |
||
87 | |||
88 | // send query |
||
89 | try { |
||
90 | $itemModel = new ItemModel(); |
||
91 | |||
92 | $arrItems = $itemModel->getItems($sqlExtra, $intLimit, $userData['private_key'], $userData['id']); |
||
93 | if (!empty($arrItems)) { |
||
94 | $responseData = json_encode($arrItems); |
||
95 | } else { |
||
96 | $strErrorDesc = 'No content for this label'; |
||
97 | $strErrorHeader = 'HTTP/1.1 204 No Content'; |
||
98 | } |
||
99 | } catch (Error $e) { |
||
100 | $strErrorDesc = $e->getMessage().'. Something went wrong! Please contact support.4'; |
||
101 | $strErrorHeader = 'HTTP/1.1 500 Internal Server Error'; |
||
102 | } |
||
103 | } else { |
||
104 | $strErrorDesc = 'Method not supported'; |
||
105 | $strErrorHeader = 'HTTP/1.1 422 Unprocessable Entity'; |
||
106 | } |
||
107 | |||
108 | // send output |
||
109 | if (empty($strErrorDesc) === true) { |
||
110 | $this->sendOutput( |
||
111 | $responseData, |
||
112 | ['Content-Type: application/json', 'HTTP/1.1 200 OK'] |
||
113 | ); |
||
114 | } else { |
||
115 | $this->sendOutput( |
||
116 | json_encode(['error' => $strErrorDesc]), |
||
117 | ['Content-Type: application/json', $strErrorHeader] |
||
118 | ); |
||
119 | } |
||
120 | } |
||
121 | //end InFoldersAction() |
||
122 | |||
123 | private function checkNewItemData(array $arrQueryStringParams, array $userData): array |
||
124 | { |
||
125 | if (isset($arrQueryStringParams['label']) === true |
||
126 | && isset($arrQueryStringParams['folder_id']) === true |
||
127 | && isset($arrQueryStringParams['password']) === true |
||
128 | && isset($arrQueryStringParams['login']) === true |
||
129 | && isset($arrQueryStringParams['email']) === true |
||
130 | && isset($arrQueryStringParams['url']) === true |
||
131 | && isset($arrQueryStringParams['tags']) === true |
||
132 | && isset($arrQueryStringParams['anyone_can_modify']) === true |
||
133 | ) { |
||
134 | // |
||
135 | if (in_array($arrQueryStringParams['folder_id'], $userData['folders_list']) === false && $userData['user_can_create_root_folder'] === 0) { |
||
136 | return [ |
||
137 | 'error' => true, |
||
138 | 'strErrorDesc' => 'User is not allowed in this folder', |
||
139 | 'strErrorHeader' => 'HTTP/1.1 401 Unauthorized', |
||
140 | ]; |
||
141 | } else if (empty($arrQueryStringParams['label']) === true) { |
||
142 | return [ |
||
143 | 'error' => true, |
||
144 | 'strErrorDesc' => 'Label is mandatory', |
||
145 | 'strErrorHeader' => 'HTTP/1.1 401 Expected parameters not provided', |
||
146 | ]; |
||
147 | } else { |
||
148 | return [ |
||
149 | 'error' => false, |
||
150 | ]; |
||
151 | } |
||
152 | } |
||
153 | |||
154 | return [ |
||
155 | 'error' => true, |
||
156 | 'strErrorDesc' => 'All fields have to be provided even if empty (refer to documentation).', |
||
157 | 'strErrorHeader' => 'HTTP/1.1 401 Expected parameters not provided', |
||
158 | ]; |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * Manage case Add |
||
163 | * |
||
164 | * @param array $userData |
||
165 | */ |
||
166 | public function createAction(array $userData) |
||
167 | { |
||
168 | $request = symfonyRequest::createFromGlobals(); |
||
169 | $requestMethod = $request->getMethod(); |
||
170 | $strErrorDesc = $strErrorHeader = $responseData = ''; |
||
171 | |||
172 | if (strtoupper($requestMethod) === 'POST') { |
||
173 | // Is user allowed to create a folder |
||
174 | // We check if allowed_to_create |
||
175 | if ((int) $userData['allowed_to_create'] !== 1) { |
||
176 | $strErrorDesc = 'User is not allowed to create an item'; |
||
177 | $strErrorHeader = 'HTTP/1.1 401 Unauthorized'; |
||
178 | } else { |
||
179 | if (empty($userData['folders_list']) === false) { |
||
180 | $userData['folders_list'] = explode(',', $userData['folders_list']); |
||
181 | } else { |
||
182 | $userData['folders_list'] = []; |
||
183 | } |
||
184 | |||
185 | // get parameters |
||
186 | $arrQueryStringParams = $this->getQueryStringParams(); |
||
187 | |||
188 | // Check that the parameters are indeed an array before using them |
||
189 | if (is_array($arrQueryStringParams)) { |
||
190 | // check parameters |
||
191 | $arrCheck = $this->checkNewItemData($arrQueryStringParams, $userData); |
||
192 | |||
193 | if ($arrCheck['error'] === true) { |
||
194 | $strErrorDesc = $arrCheck['strErrorDesc']; |
||
195 | $strErrorHeader = $arrCheck['strErrorHeader']; |
||
196 | } else { |
||
197 | // launch |
||
198 | $itemModel = new ItemModel(); |
||
199 | $ret = $itemModel->addItem( |
||
200 | (int) $arrQueryStringParams['folder_id'], |
||
201 | (string) $arrQueryStringParams['label'], |
||
202 | (string) $arrQueryStringParams['password'], |
||
203 | (string) $arrQueryStringParams['description'], |
||
204 | (string) $arrQueryStringParams['login'], |
||
205 | (string) $arrQueryStringParams['email'], |
||
206 | (string) $arrQueryStringParams['url'], |
||
207 | (string) $arrQueryStringParams['tags'], |
||
208 | (string) $arrQueryStringParams['anyone_can_modify'], |
||
209 | (string) $arrQueryStringParams['icon'], |
||
210 | (int) $userData['id'], |
||
211 | (string) $userData['username'], |
||
212 | ); |
||
213 | $responseData = json_encode($ret); |
||
214 | } |
||
215 | |||
216 | } else { |
||
217 | // Gérer le cas où les paramètres ne sont pas un tableau |
||
218 | $strErrorDesc = 'Data not consistent'; |
||
219 | $strErrorHeader = 'Expected array, received ' . gettype($arrQueryStringParams); |
||
220 | } |
||
221 | } |
||
222 | } else { |
||
223 | $strErrorDesc = 'Method not supported'; |
||
224 | $strErrorHeader = 'HTTP/1.1 422 Unprocessable Entity'; |
||
225 | } |
||
226 | |||
227 | // send output |
||
228 | if (empty($strErrorDesc) === true) { |
||
229 | $this->sendOutput( |
||
230 | $responseData, |
||
231 | ['Content-Type: application/json', 'HTTP/1.1 200 OK'] |
||
232 | ); |
||
233 | } else { |
||
234 | $this->sendOutput( |
||
235 | json_encode(['error' => $strErrorDesc]), |
||
236 | ['Content-Type: application/json', $strErrorHeader] |
||
237 | ); |
||
238 | } |
||
239 | } |
||
240 | //end addAction() |
||
241 | |||
242 | |||
243 | /** |
||
244 | * Manage case get - get an item |
||
245 | * |
||
246 | * @param array $userData |
||
247 | */ |
||
248 | public function getAction(array $userData): void |
||
249 | { |
||
250 | |||
251 | $request = symfonyRequest::createFromGlobals(); |
||
252 | $requestMethod = $request->getMethod(); |
||
253 | $strErrorDesc = ''; |
||
254 | $sqlExtra = ''; |
||
255 | $responseData = ''; |
||
256 | $strErrorHeader = ''; |
||
257 | $sql_constraint = ' AND (i.id_tree IN ('.$userData['folders_list'].')'; |
||
258 | if (!empty($userData['restricted_items_list'])) { |
||
259 | $sql_constraint .= 'OR i.id IN ('.$userData['restricted_items_list'].')'; |
||
260 | } |
||
261 | $sql_constraint .= ')'; |
||
262 | |||
263 | // get parameters |
||
264 | $arrQueryStringParams = $this->getQueryStringParams(); |
||
265 | |||
266 | if (strtoupper($requestMethod) === 'GET') { |
||
267 | // SQL where clause with item id |
||
268 | if (isset($arrQueryStringParams['id']) === true) { |
||
269 | // build sql where clause by ID |
||
270 | $sqlExtra = ' WHERE i.id = '.$arrQueryStringParams['id'] . $sql_constraint; |
||
271 | } else if (isset($arrQueryStringParams['label']) === true) { |
||
272 | // build sql where clause by LABEL |
||
273 | $sqlExtra = ' WHERE i.label '.(isset($arrQueryStringParams['like']) === true && (int) $arrQueryStringParams['like'] === 1 ? ' LIKE '.$arrQueryStringParams['label'] : ' = '.$arrQueryStringParams['label']) . $sql_constraint; |
||
274 | } else if (isset($arrQueryStringParams['description']) === true) { |
||
275 | // build sql where clause by LABEL |
||
276 | $sqlExtra = ' WHERE i.description '.(isset($arrQueryStringParams['like']) === true && (int) $arrQueryStringParams['like'] === 1 ? ' LIKE '.$arrQueryStringParams['description'] : ' = '.$arrQueryStringParams['description']).$sql_constraint; |
||
277 | } else { |
||
278 | // Send error |
||
279 | $this->sendOutput( |
||
280 | json_encode(['error' => 'Item id, label or description is mandatory']), |
||
281 | ['Content-Type: application/json', 'HTTP/1.1 401 Expected parameters not provided'] |
||
282 | ); |
||
283 | } |
||
284 | |||
285 | // send query |
||
286 | try { |
||
287 | $itemModel = new ItemModel(); |
||
288 | |||
289 | $arrItems = $itemModel->getItems($sqlExtra, 0, $userData['private_key'], $userData['id']); |
||
290 | $responseData = json_encode($arrItems); |
||
291 | } catch (Error $e) { |
||
292 | $strErrorDesc = $e->getMessage().'. Something went wrong! Please contact support.6'; |
||
293 | $strErrorHeader = 'HTTP/1.1 500 Internal Server Error'; |
||
294 | } |
||
295 | } else { |
||
296 | $strErrorDesc = 'Method not supported'; |
||
297 | $strErrorHeader = 'HTTP/1.1 422 Unprocessable Entity'; |
||
298 | } |
||
299 | |||
300 | // send output |
||
301 | if (empty($strErrorDesc) === true) { |
||
302 | $this->sendOutput( |
||
303 | $responseData, |
||
304 | ['Content-Type: application/json', 'HTTP/1.1 200 OK'] |
||
305 | ); |
||
306 | } else { |
||
307 | $this->sendOutput( |
||
308 | json_encode(['error' => $strErrorDesc]), |
||
309 | ['Content-Type: application/json', $strErrorHeader] |
||
310 | ); |
||
311 | } |
||
312 | } |
||
313 | //end getAction() |
||
314 | } |
||
315 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths