Completed
Push — development ( 8fd89f...6a24df )
by Nils
07:31
created

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          kb.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_kb'])
20
        || $_SESSION['settings']['enable_kb'] != 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
//load language
34
require_once $_SESSION['settings']['cpassman_dir'].'/includes/language/'.$_SESSION['user_language'].'_kb.php';
35
require_once $_SESSION['settings']['cpassman_dir'].'/sources/main.functions.php';
36
37
//build list of categories
38
$tab_users = array();
39
$rows = DB::query(
40
    "SELECT id, login FROM ".prefix_table("users")." ORDER BY login ASC"
41
);
42
$counter = DB::count();
43
if ($counter>0) {
44
    foreach ($rows as $reccord) {
45
        $tab_users[$reccord['login']] = array(
46
            'id'=>$reccord['id'],
47
            'login'=>$reccord['login']
48
        );
49
    }
50
}
51
52
echo '
53
<div class="title ui-widget-content ui-corner-all">
54
    '.$LANG['kb'].'&nbsp;&nbsp;&nbsp;
55
    <button title="'.$LANG['new_kb'].'" onclick="OpenDialog(\'kb_form\')" class="button" style="font-size:16px;">
56
        <i class="fa fa-plus"></i>
57
    </button>
58
</div>';
59
60
//Show the KB in a table view
61
echo '
62
<div style="margin:10px auto 25px auto;min-height:250px;" id="kb_page">
63
<table id="t_kb" cellspacing="0" cellpadding="5" width="100%">
64
    <thead><tr>
65
        <th style="width:50px;"></th>
66
        <th style="width:25%;">'.$LANG['category'].'</th>
67
        <th style="width:50%;">'.$LANG['label'].'</th>
68
        <th style="width:15%;">'.$LANG['author'].'</th>
69
    </tr></thead>
70
    <tbody>
71
        <tr><td></td></tr>
72
    </tbody>
73
</table>
74
</div>';
75
76
//Hidden things
77
echo '
78
<input type="hidden" id="kb_id" value="" />';
79
80
/* DIV FOR ADDING A KN */
81
echo '
82
<div id="kb_form" style="display:none;">
83
    <label for="kb_label" class="label">'.$LANG['label'].'</label>
84
    <input type="text" id="kb_label" class="input text ui-widget-content ui-corner-all" />
85
    <br />
86
87
    <div style="width:100%;">
88
        <div style="float:left;width:50%;">
89
            <label for="kb_category" class="label">'.$LANG['category'].'</label>
90
            <input name="kb_category" id="kb_category" class="kb_text ui-widget-content ui-corner-all" style="width: 300px;" value="" />
91
        </div>
92
        <div style="float:right;width:50%;">
93
            <label class="modify_kb_label">'.$LANG['kb_anyone_can_modify'].' : </label>
94
            <span class="div_radio">
95
                <input type="radio" id="modify_kb_yes" name="modify_kb" value="1" checked="checked" /><label for="modify_kb_yes">'.$LANG['yes'].'</label>
96
                <input type="radio" id="modify_kb_no" name="modify_kb" value="0" /><label for="modify_kb_no">'.$LANG['no'].'</label>
97
            </span>
98
        </div>
99
    </div>
100
101
    <div style="float:left;width:100%;">
102
        <label for="kb_description" class="label">'.$LANG['description'].'</label>
103
        <textarea rows="5" name="kb_description" id="kb_description" class="input" cols="70"></textarea>
104
    </div>
105
106
    <div style="float:left;width:100%;margin-top:15px;">
107
        <label for="kb_associated_to" class="label">'.$LANG['associate_kb_to_items'].'</label>
108
        <select id="kb_associated_to" class="multiselect" multiple="multiple" name="kb_associated_to[]" style="width: 860px; height: 150px;">';
109
            //get list of available items
110
            $items_id_list = array();
111
            if (empty($_SESSION['list_folders_limited'])) {
112
                $_SESSION['list_folders_limited'] = array();
113
            }
114
            $rows = DB::query(
115
                "SELECT i.id as id, i.restricted_to as restricted_to, i.perso as perso, i.label as label, i.description as description, i.pw as pw, i.login as login, i.anyone_can_modify as anyone_can_modify,
116
                    l.date as date
117
                FROM ".prefix_table("items")." as i
118
                INNER JOIN ".prefix_table("log_items")." as l ON (i.id = l.id_item)
119
                WHERE i.inactif = %i
120
                AND (l.action = %s OR (l.action = %s AND l.raison LIKE %s))
121
                AND i.id_tree IN %ls
122
                ORDER BY i.label ASC, l.date DESC",
123
                '0',
124
                'at_creation',
125
                'at_modification',
126
                'at_pw :%',
127
                array_unique(
128
                    array_merge(
129
                        $_SESSION['all_non_personal_folders'],
130
                        $_SESSION['list_folders_editable_by_role'],
131
                        $_SESSION['list_restricted_folders_for_items'],
132
                        $_SESSION['list_folders_limited']
133
                    )
134
                )
135
            );
136
            foreach ($rows as $reccord) {
137
                if (!in_array($reccord['id'], $items_id_list) && !empty($reccord['label'])) {
138
                    // exclude item if it is restricted to a group the user doesn't have
139
                    $include_item = false;
140
                    if (empty($reccord['restricted_to'])) {
141
                        $include_item = true;
142
                    } else if (count(array_intersect(explode(";", $reccord['restricted_to']), $_SESSION['user_roles'])) !== 0) {
143
                        $include_item = true;
144
                    }
145
                    if ($include_item === true) {
146
                        echo '
147
                        <option value="'.$reccord['id'].'">'.$reccord['label'].'</option>';
148
                        array_push($items_id_list, $reccord['id']);
149
                    }
150
                }
151
            }
152
        echo '
153
        </select>
154
    </div>
155
</div>';
156
157
//DELETE DIALOG
158
echo '
159
<div id="div_kb_delete" style="display:none;">
160
    <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;">&nbsp;</span>'.$LANG['confirm_deletion'].'</p>
161
</div>';
162
163
//Hidden things
164
echo '
165
<input type="hidden" id="kb_id" value="" />';
166
167
//Call javascript stuff
168
require_once 'kb.load.php';
169
170
//If redirection is done to a speoific KB then open it
171 View Code Duplication
if (isset($_GET['id']) && !empty($_GET['id'])) {
172
    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 kb.php on line 175

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...
173
        <script language="javascript" type="text/javascript">
174
        <!--
175
        openKB('.filter_var($_GET['id'], FILTER_SANITIZE_NUMBER_INT).');
176
        -->
177
        </script>';
178
}
179