These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * @file suggestion.php |
||
4 | * @author Nils Laumaillé |
||
5 | * @version 2.1.27 |
||
6 | * @copyright (c) 2009-2017 Nils Laumaillé |
||
7 | * @licensing GNU AFFERO GPL 3.0 |
||
8 | * @link http://www.teampass.net |
||
9 | * |
||
10 | * This library is distributed in the hope that it will be useful, |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
13 | */ |
||
14 | |||
15 | View Code Duplication | if ( |
|
16 | !isset($_SESSION['CPM']) || $_SESSION['CPM'] != 1 || |
||
17 | !isset($_SESSION['user_id']) || empty($_SESSION['user_id']) || |
||
18 | !isset($_SESSION['key']) || empty($_SESSION['key']) |
||
19 | || !isset($_SESSION['settings']['enable_suggestion']) |
||
20 | || $_SESSION['settings']['enable_suggestion'] != 1) |
||
21 | { |
||
22 | die('Hacking attempt...'); |
||
23 | } |
||
24 | |||
25 | /* do checks */ |
||
26 | require_once $_SESSION['settings']['cpassman_dir'].'/sources/checks.php'; |
||
27 | if (!checkUser($_SESSION['user_id'], $_SESSION['key'], curPage())) { |
||
28 | $_SESSION['error']['code'] = ERR_NOT_ALLOWED; //not allowed page |
||
29 | include $_SESSION['settings']['cpassman_dir'].'/error.php'; |
||
30 | exit(); |
||
31 | } |
||
32 | |||
33 | require_once $_SESSION['settings']['cpassman_dir'].'/sources/SplClassLoader.php'; |
||
34 | |||
35 | //Build tree |
||
36 | $tree = new SplClassLoader('Tree\NestedTree', './includes/libraries'); |
||
37 | $tree->register(); |
||
38 | $tree = new Tree\NestedTree\NestedTree($pre.'nested_tree', 'id', 'parent_id', 'title'); |
||
39 | $tree->rebuild(); |
||
40 | $folders = $tree->getDescendants(); |
||
41 | |||
42 | // prepare folders list |
||
43 | View Code Duplication | if (isset($_SESSION['list_folders_limited']) && count($_SESSION['list_folders_limited']) > 0) { |
|
44 | $listFoldersLimitedKeys = @array_keys($_SESSION['list_folders_limited']); |
||
45 | } else { |
||
46 | $listFoldersLimitedKeys = array(); |
||
47 | } |
||
48 | // list of items accessible but not in an allowed folder |
||
49 | View Code Duplication | if (isset($_SESSION['list_restricted_folders_for_items']) |
|
50 | && count($_SESSION['list_restricted_folders_for_items']) > 0) { |
||
51 | $listRestrictedFoldersForItemsKeys = @array_keys($_SESSION['list_restricted_folders_for_items']); |
||
52 | } else { |
||
53 | $listRestrictedFoldersForItemsKeys = array(); |
||
54 | } |
||
55 | $selectVisibleFoldersOptions = "<option value=\"\">--".$LANG['select']."--</option>"; |
||
56 | foreach ($folders as $folder) { |
||
57 | // Be sure that user can only see folders he/she is allowed to |
||
58 | if ( |
||
59 | !in_array($folder->id, $_SESSION['forbiden_pfs']) |
||
60 | || in_array($folder->id, $_SESSION['groupes_visibles']) |
||
61 | || in_array($folder->id, $listFoldersLimitedKeys) |
||
62 | || in_array($folder->id, $listRestrictedFoldersForItemsKeys) |
||
63 | ) { |
||
64 | $displayThisNode = false; |
||
65 | $hide_node = false; |
||
66 | $nbChildrenItems = 0; |
||
67 | // Check if any allowed folder is part of the descendants of this node |
||
68 | $nodeDescendants = $tree->getDescendants($folder->id, true, false, true); |
||
69 | foreach ($nodeDescendants as $node) { |
||
70 | if ( |
||
71 | ($listFoldersLimitedKeys != null || is_array($listFoldersLimitedKeys)) && |
||
72 | ( |
||
73 | in_array( |
||
74 | $node, |
||
75 | array_merge($_SESSION['groupes_visibles'], $_SESSION['list_restricted_folders_for_items']) |
||
76 | ) |
||
77 | || in_array($node, $listFoldersLimitedKeys) |
||
78 | || in_array($node, $listRestrictedFoldersForItemsKeys) |
||
79 | ) |
||
80 | ) { |
||
81 | $displayThisNode = true; |
||
82 | } |
||
83 | } |
||
84 | |||
85 | if ($displayThisNode === true) { |
||
86 | $ident = ""; |
||
87 | for ($x = 1; $x < $folder->nlevel; $x++) { |
||
88 | $ident .= '<i class="fa fa-angle-right"></i> '; |
||
89 | } |
||
90 | // get 1st folder |
||
91 | if (empty($firstGroup)) { |
||
92 | $firstGroup = $folder->id; |
||
93 | } |
||
94 | // If personal Folder, convert id into user name |
||
95 | if (!($folder->title == $_SESSION['user_id'] && $folder->nlevel == 1)) { |
||
96 | $fldTitle = str_replace("&", "&", $folder->title); |
||
97 | |||
98 | // build select for all visible folders |
||
99 | if (in_array($folder->id, $_SESSION['groupes_visibles'])) { |
||
100 | $selectVisibleFoldersOptions .= '<option value="'.$folder->id.'">'.$ident.$fldTitle.'</option>'; |
||
101 | } else { |
||
102 | $selectVisibleFoldersOptions .= '<option value="'.$folder->id.'" disabled="disabled">'.$ident.$fldTitle.'</option>'; |
||
103 | } |
||
104 | } |
||
105 | |||
106 | $prevLevel = $folder->nlevel; |
||
107 | } |
||
108 | } |
||
109 | } |
||
110 | |||
111 | echo ' |
||
112 | <div class="title ui-widget-content ui-corner-all"> |
||
113 | '.$LANG['suggestion'].' |
||
114 | <button title="'.$LANG['suggestion_add'].'" onclick="OpenDialog(\'suggestion_form\'); $(\'#tabs\').tabs({ active: 0 });" class="button" style="font-size:16px;"> |
||
115 | <i class="fa fa-plus"></i> |
||
116 | </button> |
||
117 | </div>'; |
||
118 | |||
119 | // prepare tabs |
||
120 | echo ' |
||
121 | <div id="tabs"> |
||
122 | <ul> |
||
123 | <li><a href="#tabs-1">'.$LANG['show_suggestions'].'</a></li> |
||
124 | <li><a href="#tabs-2">'.$LANG['show_changes'].'</a></li> |
||
125 | </ul> |
||
126 | <div id="tabs-1"> |
||
127 | <div style="margin:10px auto 25px auto;min-height:250px;" id="kb_page"> |
||
128 | <table id="t_suggestion" class="hover items_table" width="100%"> |
||
129 | <thead><tr> |
||
130 | <th></th> |
||
131 | <th>'.$LANG['label'].'</th> |
||
132 | <th>'.$LANG['description'].'</th> |
||
133 | <th>'.$LANG['group'].'</th> |
||
134 | <th>'.$LANG['author'].'</th> |
||
135 | <th>'.$LANG['comment'].'</th> |
||
136 | </tr></thead> |
||
137 | <tbody> |
||
138 | <tr><td></td></tr> |
||
139 | </tbody> |
||
140 | </table> |
||
141 | </div> |
||
142 | </div> |
||
143 | <div id="tabs-2"> |
||
144 | <div style="margin:10px auto 25px auto;min-height:250px;" id="kb_page_changes"> |
||
145 | <table id="t_change" class="hover items_table" width="100%" style=""> |
||
146 | <thead><tr> |
||
147 | <th></th> |
||
148 | <th>'.$LANG['author'].'</th> |
||
149 | <th>'.$LANG['date'].'</th> |
||
150 | <th>'.$LANG['item_id'].'</th> |
||
151 | <th>'.$LANG['label'].'</th> |
||
152 | <th>'.$LANG['group'].'</th> |
||
153 | <th>'.$LANG['comment'].'</th> |
||
154 | </tr></thead> |
||
155 | <tbody> |
||
156 | <tr><td></td></tr> |
||
157 | </tbody> |
||
158 | </table> |
||
159 | </div> |
||
160 | </div> |
||
161 | </div>'; |
||
162 | |||
163 | /* DIV FOR ADDING A SUGGESTION */ |
||
164 | echo ' |
||
165 | <div id="suggestion_form" style="display:none;"> |
||
166 | <div id="suggestion_error" class="ui-widget-content ui-corner-all" style="display:none;padding:3px;"></div> |
||
167 | |||
168 | <label for="suggestion_label" class="label_cpm">'.$LANG['label'].'</label> |
||
169 | <input type="text" id="suggestion_label" class="input text ui-widget-content ui-corner-all" style="width:100%;" /> |
||
170 | |||
171 | <label for="suggestion_description" class="label_cpm">'.$LANG['description'].'</label> |
||
172 | <textarea rows="2" cols="70" name="suggestion_description" id="suggestion_description" class="input" style="width:100%;"></textarea> |
||
173 | <br /> |
||
174 | |||
175 | <label for="suggestion_folder" class="label_cpm">'.$LANG['group'].'</label> |
||
176 | <select name="suggestion_folder" id="suggestion_folder" onchange="GetRequiredComplexity()" style="width:100%;"> |
||
177 | '.$selectVisibleFoldersOptions.' |
||
178 | </select> |
||
179 | <br /><br /> |
||
180 | |||
181 | <label for="suggestion_pwd" class="label_cpm">'.$LANG['index_password']. |
||
182 | ' |
||
183 | <span id="pw_wait" style="display:none;"><span class="fa fa-cog fa-spin fa-1x"></span></span> |
||
184 | <span id="complexity_required_text"></span> |
||
185 | </label> |
||
186 | <input type="password" id="suggestion_pwd" class="input text ui-widget-content ui-corner-all" style="width:100%;" /> |
||
187 | <div style="width:100%;"> |
||
188 | <input type="hidden" id="complexity_required" /> |
||
189 | <div id="pw_strength" style="margin:5px 0 5px 120px;"></div> |
||
190 | <input type="hidden" id="password_complexity" /> |
||
191 | </div> |
||
192 | |||
193 | <label for="suggestion_comment" class="label_cpm">'.$LANG['comment'].'</label> |
||
194 | <textarea rows="2" cols="70" name="suggestion_comment" id="suggestion_comment" class="input" style="width:100%;"></textarea> |
||
195 | |||
196 | <div style="padding:5px; z-index:9999999; width:100%;" class="ui-widget-content ui-state-focus ui-corner-all" id="add_suggestion_wait"> |
||
197 | <i class="fa fa-cog fa-spin fa-2x"></i> '.$LANG['please_wait'].' |
||
198 | </div> |
||
199 | </div>'; |
||
200 | |||
201 | //DELETE DIALOG |
||
202 | echo ' |
||
203 | <div id="div_suggestion_delete" style="display:none;"> |
||
204 | <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"> </span>'.$LANG['confirm_deletion'].'</p> |
||
205 | </div>'; |
||
206 | |||
207 | //CONFIRM DIALOG |
||
208 | echo ' |
||
209 | <div id="div_suggestion_validate" style="display:none;"> |
||
210 | <div style="padding:5px; z-index:9999999;" class="ui-widget-content ui-state-focus ui-corner-all" id="suggestion_edit_wait"> |
||
211 | <i class="fa fa-cog fa-spin fa-2x"></i> '.$LANG['please_wait'].' |
||
212 | </div> |
||
213 | <div style="margin:5px 0 5px 0; text-align:center; font-size:15px; font-weight:bold;" id="suggestion_add_label"></div> |
||
214 | <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"> </span>'.$LANG['suggestion_validate'].'</p> |
||
215 | <div style="display:none;margin-top:10px;" id="suggestion_is_duplicate">'.$LANG['suggestion_is_duplicate'].'</div> |
||
216 | </div>'; |
||
217 | |||
218 | //VIEW DIALOG |
||
219 | echo ' |
||
220 | <div id="div_suggestion_view" style="display:none;"> |
||
221 | <div style=" margin-top:10px;" id="div_suggestion_html"></div> |
||
222 | </div>'; |
||
223 | |||
224 | // hidden |
||
225 | echo ' |
||
226 | <input type="hidden" id="suggestion_id" />'; |
||
227 | |||
228 | //Call javascript stuff |
||
229 | require_once 'suggestion.load.php'; |
||
230 | |||
231 | //If redirection is done to a speoific KB then open it |
||
232 | View Code Duplication | if (isset($_GET['id']) && !empty($_GET['id'])) { |
|
233 | echo ' |
||
0 ignored issues
–
show
|
|||
234 | <script language="javascript" type="text/javascript"> |
||
235 | <!-- |
||
236 | openKB('.filter_var($_GET['id'], FILTER_SANITIZE_NUMBER_INT).'); |
||
237 | --> |
||
238 | </script>'; |
||
239 | } |
||
240 |
' <script langua... --> </script>'
can contain request data and is used in output context(s) leading to a potential security vulnerability.1 path for user data to reach this point
$_GET,
and$_GET['id']
is passed through filter_var()in suggestion.php on line 236
Preventing Cross-Site-Scripting Attacks
Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.
In order to prevent this, make sure to escape all user-provided data:
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:
For numeric data, we recommend to explicitly cast the data: