Completed
Push — development ( 2c05ec...a5a40b )
by Nils
07:16
created

suggestion.php (1 issue)

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
 * @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>&nbsp;';
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("&", "&amp;", $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'].'&nbsp;&nbsp;&nbsp;
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
    '&nbsp;
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>&nbsp;'.$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;">&nbsp;</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>&nbsp;'.$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;">&nbsp;</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
Security Cross-Site Scripting introduced by
' <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

  1. Read from $_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:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

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...
234
        <script language="javascript" type="text/javascript">
235
        <!--
236
        openKB('.filter_var($_GET['id'], FILTER_SANITIZE_NUMBER_INT).');
237
        -->
238
        </script>';
239
}
240