Issues (847)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

inc/Ui/Recent.php (2 issues)

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
namespace dokuwiki\Ui;
4
5
use dokuwiki\ChangeLog\MediaChangeLog;
6
use dokuwiki\Form\Form;
7
8
/**
9
 * DokuWiki Recent Interface
10
 *
11
 * @package dokuwiki\Ui
12
 */
13
class Recent extends Ui
14
{
15
    protected $first;
16
    protected $show_changes;
17
18
    /** 
19
     * Recent Ui constructor
20
     *
21
     * @param int $first  skip the first n changelog lines
22
     * @param string $show_changes  type of changes to show; pages, mediafiles, or both
23
     */
24
    public function __construct($first = 0, $show_changes = 'both')
25
    {
26
        $this->first        = $first;
27
        $this->show_changes = $show_changes;
28
    }
29
30
    /**
31
     * Display recent changes
32
     *
33
     * @author Andreas Gohr <[email protected]>
34
     * @author Matthias Grimm <[email protected]>
35
     * @author Ben Coburn <[email protected]>
36
     * @author Kate Arzamastseva <[email protected]>
37
     * @author Satoshi Sahara <[email protected]>
38
     *
39
     * @return void
40
     */
41
    public function show()
42
    {
43
        global $conf, $lang;
44
        global $ID;
45
46
        // get recent items, and set correct pagenation parameters (first, hasNext)
47
        $first = $this->first;
48
        $hasNext = false;
49
        $recents = $this->getRecents($first, $hasNext);
50
51
        // print intro
52
        print p_locale_xhtml('recent');
53
54
        if (getNS($ID) != '') {
55
            print '<div class="level1"><p>'
56
                . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent'))
57
                .'</p></div>';
58
        }
59
60
        // create the form
61
        $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']);
62
        $form->addTagOpen('div')->addClass('no');
63
        $form->setHiddenField('sectok', null);
64
        $form->setHiddenField('do', 'recent');
65
        $form->setHiddenField('id', $ID);
66
67
        // show dropdown selector, whether include not only recent pages but also recent media files?
68
        if ($conf['mediarevisions']) {
69
            $this->addRecentItemSelector($form);
70
        }
71
72
        // start listing of recent items
73
        $form->addTagOpen('ul');
74
        foreach ($recents as $recent) {
75
            $objRevInfo = $this->getObjRevInfo($recent);
76
            $class = ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': '';
77
            $form->addTagOpen('li')->addClass($class);
78
            $form->addTagOpen('div')->addClass('li');
79
            $html = implode(' ', [
80
                $objRevInfo->itemIcon(),          // filetype icon
81
                $objRevInfo->editDate(),          // edit date and time
82
                $objRevInfo->difflink(),          // link to diffview icon
83
                $objRevInfo->revisionlink(),      // linkto revisions icon
84
                $objRevInfo->itemName(),          // name of page or media
85
                $objRevInfo->editSummary(),       // edit summary
86
                $objRevInfo->editor(),            // editor info
87
                $objRevInfo->sizechange(),        // size change indicator
88
            ]);
89
            $form->addHTML($html);
90
            $form->addTagClose('div');
91
            $form->addTagClose('li');
92
        }
93
        $form->addTagClose('ul');
94
95
        $form->addTagClose('div'); // close div class=no
96
97
        // provide navigation for pagenated recent list (of pages and/or media files)
98
        $form->addHTML($this->htmlNavigation($first, $hasNext));
99
100
        print $form->toHTML('Recent');
101
    }
102
103
    /**
104
     * Get recent items, and set correct pagenation parameters (first, hasNext)
105
     *
106
     * @param int  $first
107
     * @param bool $hasNext
108
     * @return array  recent items to be shown in a pagenated list
109
     *
110
     * @see also dokuwiki\Changelog::getRevisionInfo()
111
     */
112
    protected function getRecents(&$first, &$hasNext)
113
    {
114
        global $ID, $conf;
115
116
        $flags = 0;
117
        if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) {
118
            $flags = RECENTS_MEDIA_CHANGES;
119
        } elseif ($this->show_changes == 'pages') {
120
            $flags = 0;
121
        } elseif ($conf['mediarevisions']) {
122
            $flags = RECENTS_MEDIA_PAGES_MIXED;
123
        }
124
125
        /* we need to get one additionally log entry to be able to
126
         * decide if this is the last page or is there another one.
127
         * This is the cheapest solution to get this information.
128
         */
129
        $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
It seems like getNS($ID) targeting getNS() can also be of type false; however, getRecents() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
130
        if (count($recents) == 0 && $first != 0) {
131
            $first = 0;
132
            $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
0 ignored issues
show
It seems like getNS($ID) targeting getNS() can also be of type false; however, getRecents() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
133
        }
134
135
        $hasNext = false;
136
        if (count($recents) > $conf['recent']) {
137
            $hasNext = true;
138
            array_pop($recents); // remove extra log entry
139
        }
140
        return $recents;
141
    }
142
143
    /**
144
     * Navigation buttons for Pagenation (prev/next)
145
     *
146
     * @param int  $first
147
     * @param bool $hasNext
148
     * @return array  html
149
     */
150
    protected function htmlNavigation($first, $hasNext)
151
    {
152
        global $conf, $lang;
153
154
        $last = $first + $conf['recent'];
155
        $html = '<div class="pagenav">';
156
        if ($first > 0) {
157
            $first = max($first - $conf['recent'], 0);
158
            $html.= '<div class="pagenav-prev">';
159
            $html.= '<button type="submit" name="first['.$first.']" accesskey="n"'
160
                  . ' title="'.$lang['btn_newer'].' [N]" class="button show">'
161
                  . $lang['btn_newer']
162
                  . '</button>';
163
            $html.= '</div>';
164
        }
165
        if ($hasNext) {
166
            $html.= '<div class="pagenav-next">';
167
            $html.= '<button type="submit" name="first['.$last.']" accesskey="p"'
168
                  . ' title="'.$lang['btn_older'].' [P]" class="button show">'
169
                  . $lang['btn_older']
170
                  . '</button>';
171
            $html.= '</div>';
172
        }
173
        $html.= '</div>';
174
        return $html;
175
    }
176
177
    /**
178
     * Add dropdown selector of item types to the form instance
179
     *
180
     * @param Form $form
181
     * @return void
182
     */
183
    protected function addRecentItemSelector(Form $form)
184
    {
185
        global $lang;
186
187
        $form->addTagOpen('div')->addClass('changeType');
188
        $options = array(
189
                    'pages'      => $lang['pages_changes'],
190
                    'mediafiles' => $lang['media_changes'],
191
                    'both'       => $lang['both_changes'],
192
        );
193
        $form->addDropdown('show_changes', $options, $lang['changes_type'])
194
                ->val($this->show_changes)->addClass('quickselect');
195
        $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit');
196
        $form->addTagClose('div');
197
    }
198
199
    /**
200
     * Returns instance of objRevInfo
201
     * @param array $info  Revision info structure of page or media
202
     * @return objRevInfo object (anonymous class)
203
     */
204
    protected function getObjRevInfo(array $info)
205
    {
206
        return new class ($info) // anonymous class (objRevInfo)
207
        {
208
            protected $info;
209
210
            public function __construct(array $info)
211
            {
212
                $this->info = $info;
213
            }
214
215
            // fileicon of the page or media file
216
            public function itemIcon()
217
            {
218
                $id = $this->info['id'];
219
                if (isset($this->info['media'])) {
220
                    $html = media_printicon($id);
221
                } else {
222
                    $html = '<img class="icon" src="'.DOKU_BASE.'lib/images/fileicons/file.png" alt="'.$id.'" />';
223
                }
224
                return $html;
225
            }
226
227
            // edit date and time of the page or media file
228
            public function editDate()
229
            {
230
                return '<span class="date">'. dformat($this->info['date']) .'</span>';
231
            }
232
233
            // edit summary
234
            public function editSummary()
235
            {
236
                return '<span class="sum">'.' – '. hsc($this->info['sum']).'</span>';
237
            }
238
239
            // editor of the page or media file
240
            public function editor()
241
            {
242
                $html = '<span class="user">';
243
                if ($this->info['user']) {
244
                    $html.= '<bdi>'. editorinfo($this->info['user']) .'</bdi>';
245
                    if (auth_ismanager()) $html.= ' <bdo dir="ltr">('. $this->info['ip'] .')</bdo>';
246
                } else {
247
                    $html.= '<bdo dir="ltr">'. $this->info['ip'] .'</bdo>';
248
                }
249
                $html.= '</span>';
250
                return $html;
251
            }
252
253
            // name of the page or media file
254
            public function itemName()
255
            {
256
                $id = $this->info['id'];
257
                if (isset($this->info['media'])) {
258
                    $href = media_managerURL(['tab_details'=>'view', 'image'=> $id, 'ns'=> getNS($id)], '&');
259
                    $class = file_exists(mediaFN($id)) ? 'wikilink1' : 'wikilink2';
260
                    $html = '<a href="'.$href.'" class="'.$class.'">'.$id.'</a>';
261
                } else {
262
                    $html = html_wikilink(':'.$id, (useHeading('navigation') ? null : $id));
263
                }
264
                return $html;
265
            }
266
267
            // icon difflink
268
            public function difflink()
269
            {
270
                global $lang;
271
                $id = $this->info['id'];
272
273
                if (isset($this->info['media'])) {
274
                    $revs = (new MediaChangeLog($id))->getRevisions(0, 1);
275
                    $diff = (count($revs) && file_exists(mediaFN($id)));
276
                    if ($diff) {
277
                        $href = media_managerURL(
278
                            ['tab_details'=>'history', 'mediado'=>'diff', 'image'=> $id, 'ns'=> getNS($id)], '&'
279
                        );
280
                    } else {
281
                        $href = '';
282
                    }
283
                } else {
284
                    $href = wl($id, "do=diff", false, '&');
285
                }
286
287
                if ($href) {
288
                    $html = '<a href="'.$href.'" class="diff_link">'
289
                          . '<img src="'.DOKU_BASE.'lib/images/diff.png" width="15" height="11"'
290
                          . ' title="'.$lang['diff'].'" alt="'.$lang['diff'].'" />'
291
                          . '</a>';
292
                } else {
293
                    $html = '<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />';
294
                }
295
                return $html;
296
            }
297
298
            // icon revision link
299
            public function revisionlink()
300
            {
301
                global $lang;
302
                $id = $this->info['id'];
303
                if (isset($this->info['media'])) {
304
                    $href = media_managerURL(['tab_details'=>'history', 'image'=> $id, 'ns'=> getNS($id)], '&');
305
                } else {
306
                    $href = wl($id, "do=revisions", false, '&');
307
                }
308
                $html = '<a href="'.$href.'" class="revisions_link">'
309
                      . '<img src="'.DOKU_BASE.'lib/images/history.png" width="12" height="14"'
310
                      . ' title="'.$lang['btn_revs'].'" alt="'.$lang['btn_revs'].'" />'
311
                      . '</a>';
312
                return $html;
313
            }
314
315
            // size change
316
            public function sizeChange()
317
            {
318
                $class = 'sizechange';
319
                $value = filesize_h(abs($this->info['sizechange']));
320
                if ($this->info['sizechange'] > 0) {
321
                    $class .= ' positive';
322
                    $value = '+' . $value;
323
                } elseif ($this->info['sizechange'] < 0) {
324
                    $class .= ' negative';
325
                    $value = '-' . $value;
326
                } else {
327
                    $value = '±' . $value;
328
                }
329
                return '<span class="'.$class.'">'.$value.'</span>';
330
            }
331
        }; // end of anonymous class (objRevInfo)
332
    }
333
334
}
335