Issues (4122)

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.

includes/Feed.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
 * Basic support for outputting syndication feeds in RSS, other formats.
4
 *
5
 * Contain a feed class as well as classes to build rss / atom ... feeds
6
 * Available feeds are defined in Defines.php
7
 *
8
 * Copyright © 2004 Brion Vibber <[email protected]>
9
 * https://www.mediawiki.org/
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License along
22
 * with this program; if not, write to the Free Software Foundation, Inc.,
23
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
 * http://www.gnu.org/copyleft/gpl.html
25
 *
26
 * @file
27
 */
28
29
/**
30
 * @defgroup Feed Feed
31
 */
32
33
/**
34
 * A base class for basic support for outputting syndication feeds in RSS and other formats.
35
 *
36
 * @ingroup Feed
37
 */
38
class FeedItem {
39
	/** @var Title */
40
	public $title;
41
42
	public $description;
43
44
	public $url;
45
46
	public $date;
47
48
	public $author;
49
50
	public $uniqueId;
51
52
	public $comments;
53
54
	public $rssIsPermalink = false;
55
56
	/**
57
	 * Constructor
58
	 *
59
	 * @param string|Title $title Item's title
60
	 * @param string $description
61
	 * @param string $url URL uniquely designating the item.
62
	 * @param string $date Item's date
63
	 * @param string $author Author's user name
64
	 * @param string $comments
65
	 */
66
	function __construct( $title, $description, $url, $date = '', $author = '', $comments = '' ) {
67
		$this->title = $title;
68
		$this->description = $description;
69
		$this->url = $url;
70
		$this->uniqueId = $url;
71
		$this->date = $date;
72
		$this->author = $author;
73
		$this->comments = $comments;
74
	}
75
76
	/**
77
	 * Encode $string so that it can be safely embedded in a XML document
78
	 *
79
	 * @param string $string String to encode
80
	 * @return string
81
	 */
82
	public function xmlEncode( $string ) {
83
		$string = str_replace( "\r\n", "\n", $string );
84
		$string = preg_replace( '/[\x00-\x08\x0b\x0c\x0e-\x1f]/', '', $string );
85
		return htmlspecialchars( $string );
86
	}
87
88
	/**
89
	 * Get the unique id of this item
90
	 *
91
	 * @return string
92
	 */
93
	public function getUniqueId() {
94
		if ( $this->uniqueId ) {
95
			return $this->xmlEncode( wfExpandUrl( $this->uniqueId, PROTO_CURRENT ) );
0 ignored issues
show
It seems like wfExpandUrl($this->uniqueId, PROTO_CURRENT) targeting wfExpandUrl() can also be of type false; however, FeedItem::xmlEncode() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
96
		}
97
	}
98
99
	/**
100
	 * Set the unique id of an item
101
	 *
102
	 * @param string $uniqueId Unique id for the item
103
	 * @param bool $rssIsPermalink Set to true if the guid (unique id) is a permalink (RSS feeds only)
104
	 */
105
	public function setUniqueId( $uniqueId, $rssIsPermalink = false ) {
106
		$this->uniqueId = $uniqueId;
107
		$this->rssIsPermalink = $rssIsPermalink;
108
	}
109
110
	/**
111
	 * Get the title of this item; already xml-encoded
112
	 *
113
	 * @return string
114
	 */
115
	public function getTitle() {
116
		return $this->xmlEncode( $this->title );
117
	}
118
119
	/**
120
	 * Get the URL of this item; already xml-encoded
121
	 *
122
	 * @return string
123
	 */
124
	public function getUrl() {
125
		return $this->xmlEncode( $this->url );
126
	}
127
128
	/**
129
	 * Get the description of this item; already xml-encoded
130
	 *
131
	 * @return string
132
	 */
133
	public function getDescription() {
134
		return $this->xmlEncode( $this->description );
135
	}
136
137
	/**
138
	 * Get the language of this item
139
	 *
140
	 * @return string
141
	 */
142
	public function getLanguage() {
143
		global $wgLanguageCode;
144
		return wfBCP47( $wgLanguageCode );
145
	}
146
147
	/**
148
	 * Get the date of this item
149
	 *
150
	 * @return string
151
	 */
152
	public function getDate() {
153
		return $this->date;
154
	}
155
156
	/**
157
	 * Get the author of this item; already xml-encoded
158
	 *
159
	 * @return string
160
	 */
161
	public function getAuthor() {
162
		return $this->xmlEncode( $this->author );
163
	}
164
165
	/**
166
	 * Get the comment of this item; already xml-encoded
167
	 *
168
	 * @return string
169
	 */
170
	public function getComments() {
171
		return $this->xmlEncode( $this->comments );
172
	}
173
174
	/**
175
	 * Quickie hack... strip out wikilinks to more legible form from the comment.
176
	 *
177
	 * @param string $text Wikitext
178
	 * @return string
179
	 */
180
	public static function stripComment( $text ) {
181
		return preg_replace( '/\[\[([^]]*\|)?([^]]+)\]\]/', '\2', $text );
182
	}
183
	/**#@-*/
184
}
185
186
/**
187
 * Class to support the outputting of syndication feeds in Atom and RSS format.
188
 *
189
 * @ingroup Feed
190
 */
191
abstract class ChannelFeed extends FeedItem {
192
	/**
193
	 * Generate Header of the feed
194
	 * @par Example:
195
	 * @code
196
	 * print "<feed>";
197
	 * @endcode
198
	 */
199
	abstract public function outHeader();
200
201
	/**
202
	 * Generate an item
203
	 * @par Example:
204
	 * @code
205
	 * print "<item>...</item>";
206
	 * @endcode
207
	 * @param FeedItem $item
208
	 */
209
	abstract public function outItem( $item );
210
211
	/**
212
	 * Generate Footer of the feed
213
	 * @par Example:
214
	 * @code
215
	 * print "</feed>";
216
	 * @endcode
217
	 */
218
	abstract public function outFooter();
219
220
	/**
221
	 * Setup and send HTTP headers. Don't send any content;
222
	 * content might end up being cached and re-sent with
223
	 * these same headers later.
224
	 *
225
	 * This should be called from the outHeader() method,
226
	 * but can also be called separately.
227
	 */
228
	public function httpHeaders() {
229
		global $wgOut, $wgVaryOnXFP;
230
231
		# We take over from $wgOut, excepting its cache header info
232
		$wgOut->disable();
233
		$mimetype = $this->contentType();
234
		header( "Content-type: $mimetype; charset=UTF-8" );
235
		if ( $wgVaryOnXFP ) {
236
			$wgOut->addVaryHeader( 'X-Forwarded-Proto' );
237
		}
238
		$wgOut->sendCacheControl();
239
	}
240
241
	/**
242
	 * Return an internet media type to be sent in the headers.
243
	 *
244
	 * @return string
245
	 */
246
	private function contentType() {
247
		global $wgRequest;
248
249
		$ctype = $wgRequest->getVal( 'ctype', 'application/xml' );
250
		$allowedctypes = [
251
			'application/xml',
252
			'text/xml',
253
			'application/rss+xml',
254
			'application/atom+xml'
255
		];
256
257
		return ( in_array( $ctype, $allowedctypes ) ? $ctype : 'application/xml' );
258
	}
259
260
	/**
261
	 * Output the initial XML headers.
262
	 */
263
	protected function outXmlHeader() {
264
		$this->httpHeaders();
265
		echo '<?xml version="1.0"?>' . "\n";
266
	}
267
}
268
269
/**
270
 * Generate a RSS feed
271
 *
272
 * @ingroup Feed
273
 */
274
class RSSFeed extends ChannelFeed {
275
276
	/**
277
	 * Format a date given a timestamp
278
	 *
279
	 * @param int $ts Timestamp
280
	 * @return string Date string
281
	 */
282
	function formatTime( $ts ) {
283
		return gmdate( 'D, d M Y H:i:s \G\M\T', wfTimestamp( TS_UNIX, $ts ) );
284
	}
285
286
	/**
287
	 * Output an RSS 2.0 header
288
	 */
289
	function outHeader() {
290
		global $wgVersion;
291
292
		$this->outXmlHeader();
293
		?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
294
	<channel>
295
		<title><?php print $this->getTitle() ?></title>
296
		<link><?php print wfExpandUrl( $this->getUrl(), PROTO_CURRENT ) ?></link>
297
		<description><?php print $this->getDescription() ?></description>
298
		<language><?php print $this->getLanguage() ?></language>
299
		<generator>MediaWiki <?php print $wgVersion ?></generator>
300
		<lastBuildDate><?php print $this->formatTime( wfTimestampNow() ) ?></lastBuildDate>
301
<?php
302
	}
303
304
	/**
305
	 * Output an RSS 2.0 item
306
	 * @param FeedItem $item Item to be output
307
	 */
308
	function outItem( $item ) {
309
		// @codingStandardsIgnoreStart Ignore long lines and formatting issues.
310
	?>
311
		<item>
312
			<title><?php print $item->getTitle(); ?></title>
313
			<link><?php print wfExpandUrl( $item->getUrl(), PROTO_CURRENT ); ?></link>
314
			<guid<?php if ( !$item->rssIsPermalink ) { print ' isPermaLink="false"'; } ?>><?php print $item->getUniqueId(); ?></guid>
315
			<description><?php print $item->getDescription() ?></description>
316
			<?php if ( $item->getDate() ) { ?><pubDate><?php print $this->formatTime( $item->getDate() ); ?></pubDate><?php } ?>
317
			<?php if ( $item->getAuthor() ) { ?><dc:creator><?php print $item->getAuthor(); ?></dc:creator><?php }?>
318
			<?php if ( $item->getComments() ) { ?><comments><?php print wfExpandUrl( $item->getComments(), PROTO_CURRENT ); ?></comments><?php }?>
319
		</item>
320
<?php
321
		// @codingStandardsIgnoreEnd
322
	}
323
324
	/**
325
	 * Output an RSS 2.0 footer
326
	 */
327
	function outFooter() {
328
	?>
329
	</channel>
330
</rss><?php
331
	}
332
}
333
334
/**
335
 * Generate an Atom feed
336
 *
337
 * @ingroup Feed
338
 */
339
class AtomFeed extends ChannelFeed {
340
	/**
341
	 * Format a date given timestamp.
342
	 *
343
	 * @param string|int $timestamp
344
	 * @return string
345
	 */
346
	function formatTime( $timestamp ) {
347
		// need to use RFC 822 time format at least for rss2.0
348
		return gmdate( 'Y-m-d\TH:i:s', wfTimestamp( TS_UNIX, $timestamp ) );
349
	}
350
351
	/**
352
	 * Outputs a basic header for Atom 1.0 feeds.
353
	 */
354
	function outHeader() {
355
		global $wgVersion;
356
357
		$this->outXmlHeader();
358
		// @codingStandardsIgnoreStart Ignore long lines and formatting issues.
359
		?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="<?php print $this->getLanguage() ?>">
360
		<id><?php print $this->getFeedId() ?></id>
361
		<title><?php print $this->getTitle() ?></title>
362
		<link rel="self" type="application/atom+xml" href="<?php print wfExpandUrl( $this->getSelfUrl(), PROTO_CURRENT ) ?>"/>
363
		<link rel="alternate" type="text/html" href="<?php print wfExpandUrl( $this->getUrl(), PROTO_CURRENT ) ?>"/>
364
		<updated><?php print $this->formatTime( wfTimestampNow() ) ?>Z</updated>
365
		<subtitle><?php print $this->getDescription() ?></subtitle>
366
		<generator>MediaWiki <?php print $wgVersion ?></generator>
367
368
<?php
369
		// @codingStandardsIgnoreEnd
370
	}
371
372
	/**
373
	 * Atom 1.0 requires a unique, opaque IRI as a unique identifier
374
	 * for every feed we create. For now just use the URL, but who
375
	 * can tell if that's right? If we put options on the feed, do we
376
	 * have to change the id? Maybe? Maybe not.
377
	 *
378
	 * @return string
379
	 */
380
	private function getFeedId() {
381
		return $this->getSelfUrl();
382
	}
383
384
	/**
385
	 * Atom 1.0 requests a self-reference to the feed.
386
	 * @return string
387
	 */
388
	private function getSelfUrl() {
389
		global $wgRequest;
390
		return htmlspecialchars( $wgRequest->getFullRequestURL() );
391
	}
392
393
	/**
394
	 * Output a given item.
395
	 * @param FeedItem $item
396
	 */
397
	function outItem( $item ) {
398
		global $wgMimeType;
399
		// @codingStandardsIgnoreStart Ignore long lines and formatting issues.
400
	?>
401
	<entry>
402
		<id><?php print $item->getUniqueId(); ?></id>
403
		<title><?php print $item->getTitle(); ?></title>
404
		<link rel="alternate" type="<?php print $wgMimeType ?>" href="<?php print wfExpandUrl( $item->getUrl(), PROTO_CURRENT ); ?>"/>
405
		<?php if ( $item->getDate() ) { ?>
406
		<updated><?php print $this->formatTime( $item->getDate() ); ?>Z</updated>
407
		<?php } ?>
408
409
		<summary type="html"><?php print $item->getDescription() ?></summary>
410
		<?php if ( $item->getAuthor() ) { ?><author><name><?php print $item->getAuthor(); ?></name></author><?php }?>
411
	</entry>
412
413
<?php /* @todo FIXME: Need to add comments
414
	<?php if( $item->getComments() ) { ?><dc:comment><?php print $item->getComments() ?></dc:comment><?php }?>
415
	  */
416
	}
417
418
	/**
419
	 * Outputs the footer for Atom 1.0 feed (basically '\</feed\>').
420
	 */
421
	function outFooter() {?>
422
	</feed><?php
423
		// @codingStandardsIgnoreEnd
424
	}
425
}
426