Issues (2473)

Branch: master

Security Analysis    no vulnerabilities found

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.

mod/blog/lib/blog.php (4 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
 * Blog helper functions
4
 *
5
 * @package Blog
6
 */
7
8
9
/**
10
 * Get page components to view a blog post.
11
 *
12
 * @param int $guid GUID of a blog entity.
13
 * @return array
14
 */
15
function blog_get_page_content_read($guid = NULL) {
16
17
	$return = array();
18
	$lang = get_current_language();
19
	elgg_entity_gatekeeper($guid, 'object', 'blog');
20
	$blog = get_entity($guid);
21
22
	// no header or tabs for viewing an individual blog
23
	$return['filter'] = '';
24
	elgg_set_page_owner_guid($blog->container_guid);
25
	elgg_group_gatekeeper();
26
 	$lang = get_current_language();
27
 	$container = $blog->getContainerEntity();
28
29
	
30
	$return['title'] =  gc_explode_translation($blog->title, $lang);
31
32
	if (!$container->title){
33
		$crumbs_title = gc_explode_translation($container->name,$lang);
34
	}else{
35
		$crumbs_title = gc_explode_translation($container->title,$lang);
36
	}
37
	
38
39
	
40
	if (elgg_instanceof($container, 'group')) {
41
		elgg_push_breadcrumb($crumbs_title, "blog/group/$container->guid/all");
42
	} else {
43
		elgg_push_breadcrumb($crumbs_title, "blog/owner/$container->username");
44
	}
45
46
	
47
	elgg_push_breadcrumb(gc_explode_translation($blog->title,$lang));
48
49
	
50
	$return['content'] = elgg_view_entity($blog, array('full_view' => true));
51
	// check to see if we should allow comments
52
	if ($blog->comments_on != 'Off' && $blog->status == 'published') {
53
		$return['content'] .= elgg_view_comments($blog);
54
	}
55
56
	return $return;
57
}
58
59
/**
60
 * Get page components to list a user's or all blogs.
61
 *
62
 * @param int $container_guid The GUID of the page owner or NULL for all blogs
63
 * @return array
64
 */
65
function blog_get_page_content_list($container_guid = NULL) {
66
67
	$return = array();
68
	$lang = get_current_language();
69
	$return['filter_context'] = $container_guid ? 'mine' : 'all';
70
71
	$options = array(
72
		'type' => 'object',
73
		'subtype' => 'blog',
74
		'full_view' => false,
75
		'no_results' => elgg_echo('blog:none'),
76
		'preload_owners' => true,
77
		'distinct' => false,
78
	);
79
80
	$current_user = elgg_get_logged_in_user_entity();
81
82
	if ($container_guid) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $container_guid of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
83
		// access check for closed groups
84
		elgg_group_gatekeeper();
85
		$options['container_guid'] = $container_guid;
86
		$container = get_entity($container_guid);
87
		
88
        $return['title'] = elgg_echo('blog:title:user_blogs', array(gc_explode_translation($container->name, $lang)));
89
90
		$crumbs_title = gc_explode_translation($container->name, $lang);
91
		elgg_push_breadcrumb($crumbs_title);
92
93 View Code Duplication
		if ($current_user && ($container_guid == $current_user->guid)) {
94
			$return['filter_context'] = 'mine';
95
		} else if (elgg_instanceof($container, 'group')) {
96
			$return['filter'] = false;
97
		} else {
98
			// do not show button or select a tab when viewing someone else's posts
99
			$return['filter_context'] = 'none';
100
		}
101
	} else {
102
		$options['preload_containers'] = true;
103
		$return['filter_context'] = 'all';
104
		$return['title'] = elgg_echo('blog:title:all_blogs');
105
		elgg_pop_breadcrumb();
106
		elgg_push_breadcrumb(elgg_echo('blog:blogs'));
107
	}
108
109
	elgg_register_title_button();
110
	// show all posts for admin or users looking at their own blogs
111
	// show only published posts for other users.
112
	$show_only_published = true;
113
	if ($current_user) {
114
		if (($current_user->guid == $container_guid) || $current_user->isAdmin()) {
115
			$show_only_published = false;
116
		}
117
	}
118
119
	if ($show_only_published) {
120
		$options['metadata_name_value_pairs'] = array(
121
			array('name' => 'status', 'value' => 'published'),
122
		);
123
124
		$options['metadata_name_value_pairs'] .= array(
125
			array('name' => 'status', 'value' => 'draft', 'owner_guid' => $current_user->guid),
126
		);
127
	}
128
129
	$return['content'] = elgg_list_entities($options);
130
131
	return $return;
132
}
133
134
/**
135
 * Get page components to list of the user's friends' posts.
136
 *
137
 * @param int $user_guid
138
 * @return array
139
 */
140
function blog_get_page_content_friends($user_guid) {
141
142
	$user = get_user($user_guid);
143
	if (!$user) {
144
		forward('blog/all');
145
	}
146
147
	$return = array();
148
	$return['filter_context'] = 'friends';
149
	$return['title'] = elgg_echo('blog:title:friends');
150
	$crumbs_title = $user->name;
151
	elgg_push_breadcrumb($crumbs_title, "blog/owner/{$user->username}");
152
	elgg_push_breadcrumb(elgg_echo('friends'));
153
	elgg_register_title_button();
154
155
	$options = array(
156
		'type' => 'object',
157
		'subtype' => 'blog',
158
		'full_view' => false,
159
		'relationship' => 'friend',
160
		'relationship_guid' => $user_guid,
161
		'relationship_join_on' => 'container_guid',
162
		'no_results' => elgg_echo('blog:none'),
163
		'preload_owners' => true,
164
		'preload_containers' => true,
165
	);
166
167
	$return['content'] = elgg_list_entities_from_relationship($options);
168
169
	return $return;
170
}
171
172
/**
173
 * Get page components to show blogs with publish dates between $lower and $upper
174
 *
175
 * @param int $owner_guid The GUID of the owner of this page
176
 * @param int $lower      Unix timestamp
177
 * @param int $upper      Unix timestamp
178
 * @return array
179
 */
180
function blog_get_page_content_archive($owner_guid, $lower = 0, $upper = 0) {
181
182
	$owner = get_entity($owner_guid);
183
	elgg_set_page_owner_guid($owner_guid);
184
	$crumbs_title = $owner->name;
185
186
	if (elgg_instanceof($owner, 'user')) {
187
		$url = "blog/owner/{$owner->username}";
188
	} else {
189
		$url = "blog/group/$owner->guid/all";
190
	}
191
	elgg_push_breadcrumb($crumbs_title, $url);
192
	elgg_push_breadcrumb(elgg_echo('blog:archives'));
193
194
	if ($lower) {
195
		$lower = (int)$lower;
196
	}
197
198
	if ($upper) {
199
		$upper = (int)$upper;
200
	}
201
202
	$options = array(
203
		'type' => 'object',
204
		'subtype' => 'blog',
205
		'full_view' => false,
206
		'no_results' => elgg_echo('blog:none'),
207
		'preload_owners' => true,
208
		'distinct' => false,
209
	);
210
211
	if ($owner_guid) {
212
		$options['container_guid'] = $owner_guid;
213
	}
214
215
	if ($lower) {
216
		$options['created_time_lower'] = $lower;
217
	}
218
219
	if ($upper) {
220
		$options['created_time_upper'] = $upper;
221
	}
222
223
	$content = elgg_list_entities($options);
224
	$title = elgg_echo('date:month:' . date('m', $lower), array(date('Y', $lower)));
225
226
	return array(
227
		'content' => $content,
228
		'title' => $title,
229
		'filter' => '',
230
	);
231
}
232
233
/**
234
 * Get page components to edit/create a blog post.
235
 *
236
 * @param string  $page     'edit' or 'new'
237
 * @param int     $guid     GUID of blog post or container
238
 * @param int     $revision Annotation id for revision to edit (optional)
239
 * @return array
240
 */
241
function blog_get_page_content_edit($page, $guid = 0, $revision = NULL) {
242
243
	elgg_require_js('elgg/blog/save_draft');
244
245
	$return = array(
246
		'filter' => '',
247
	);
248
249
	$vars = array();
250
	$vars['id'] = 'blog-post-edit';
251
	$vars['class'] = 'elgg-form-alt';
252
	$sidebar = '';
253
254
	if ($page == 'edit') {
255
		$blog = get_entity((int)$guid);
256
		$title = elgg_echo('blog:edit');
257
258
		if (elgg_instanceof($blog, 'object', 'blog') && $blog->canEdit()) {
259
			$vars['entity'] = $blog;
260
			$title .= ": \"$blog->title\"";
261
262 View Code Duplication
			if ($revision) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $revision of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
263
				$revision = elgg_get_annotation_from_id((int)$revision);
264
				$vars['revision'] = $revision;
265
				$title .= ' ' . elgg_echo('blog:edit_revision_notice');
266
267
				if (!$revision || !($revision->entity_guid == $guid)) {
268
					$content = elgg_echo('blog:error:revision_not_found');
269
					$return['content'] = $content;
270
					$return['title'] = $title;
271
					return $return;
272
				}
273
			}
274
			$body_vars = blog_prepare_form_vars($blog, $revision);
0 ignored issues
show
$blog is of type object<ElggEntity>, but the function expects a object<ElggBlog>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
It seems like $revision can also be of type integer or object<ElggExtender>; however, blog_prepare_form_vars() does only seem to accept object<ElggAnnotation>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
275
			elgg_push_breadcrumb($blog->title, $blog->getURL());
276
			elgg_push_breadcrumb(elgg_echo('edit'));
277
			elgg_require_js('elgg/blog/save_draft');
278
			$content = elgg_view_form('blog/save', $vars, $body_vars);
279
			$sidebar = elgg_view('blog/sidebar/revisions', $vars);
280
281
		} else {
282
			$content = elgg_echo('blog:error:cannot_edit_post');
283
		}
284
	} else {
285
		elgg_push_breadcrumb(elgg_echo('blog:add'));
286
		$body_vars = blog_prepare_form_vars(null);
287
		$title = elgg_echo('blog:add');
288
		$content = elgg_view_form('blog/save', $vars, $body_vars);
289
	}
290
291
	$return['title'] = $title;
292
	$return['content'] = $content;
293
	$return['sidebar'] = $sidebar;
294
	return $return;
295
}
296
297
/**
298
 * Pull together blog variables for the save form
299
 *
300
 * @param ElggBlog       $post
301
 * @param ElggAnnotation $revision
302
 * @return array
303
 */
304
function blog_prepare_form_vars($post = NULL, $revision = NULL) {
305
306
	// input names => defaults
307
	$values = array(
308
		'title' => NULL,
309
		'title2' => NULL,
310
		'description' => NULL,
311
		'description2' => NULL,
312
		'description3' => NULL,
313
		'status' => 'published',
314
		'access_id' => ACCESS_DEFAULT,
315
		'comments_on' => 'On',
316
		'excerpt' => NULL,
317
		'excerpt2' => NULL,
318
		'excerpt3' => NULL,
319
		'tags' => NULL,
320
		'container_guid' => NULL,
321
		'guid' => NULL,
322
		'draft_warning' => '',
323
	);
324
325
	if ($post) {
326
		foreach (array_keys($values) as $field) {
327
			if (isset($post->$field)) {
328
				$values[$field] = $post->$field;
329
			}
330
		}
331
332
		if ($post->status == 'draft') {
333
			$values['access_id'] = $post->future_access;
334
		}
335
	}
336
337
	if (elgg_is_sticky_form('blog')) {
338
		$sticky_values = elgg_get_sticky_values('blog');
339
		foreach ($sticky_values as $key => $value) {
340
			$values[$key] = $value;
341
		}
342
	}
343
	
344
	elgg_clear_sticky_form('blog');
345
346
	if (!$post) {
347
		return $values;
348
	}
349
350
	// load the revision annotation if requested
351 View Code Duplication
	if ($revision instanceof ElggAnnotation && $revision->entity_guid == $post->getGUID()) {
352
		$values['revision'] = $revision;
353
		$values['description'] = $revision->value;
354
	}
355
356
	// display a notice if there's an autosaved annotation
357
	// and we're not editing it.
358
	$auto_save_annotations = $post->getAnnotations(array(
359
		'annotation_name' => 'blog_auto_save',
360
		'limit' => 1,
361
	));
362
363
	if ($auto_save_annotations) {
364
		$auto_save = $auto_save_annotations[0];
365
	} else {
366
		$auto_save = false;
367
	}
368
369
	if ($auto_save && $auto_save->id != $revision->id) {
370
		$values['draft_warning'] = elgg_echo('blog:messages:warning:draft');
371
	}
372
373
	return $values;
374
}
375