Issues (4967)

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.

src/wp-includes/bookmark.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
 * Link/Bookmark API
4
 *
5
 * @package WordPress
6
 * @subpackage Bookmark
7
 */
8
9
/**
10
 * Retrieve Bookmark data
11
 *
12
 * @since 2.1.0
13
 *
14
 * @global wpdb $wpdb WordPress database abstraction object.
15
 *
16
 * @param int|stdClass $bookmark
17
 * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
18
 *                       an stdClass object, an associative array, or a numeric array, respectively. Default OBJECT.
19
 * @param string $filter Optional, default is 'raw'.
20
 * @return array|object|null Type returned depends on $output value.
21
 */
22
function get_bookmark($bookmark, $output = OBJECT, $filter = 'raw') {
23
	global $wpdb;
24
25
	if ( empty($bookmark) ) {
26
		if ( isset($GLOBALS['link']) )
27
			$_bookmark = & $GLOBALS['link'];
28
		else
29
			$_bookmark = null;
30
	} elseif ( is_object($bookmark) ) {
31
		wp_cache_add($bookmark->link_id, $bookmark, 'bookmark');
32
		$_bookmark = $bookmark;
33
	} else {
34
		if ( isset($GLOBALS['link']) && ($GLOBALS['link']->link_id == $bookmark) ) {
35
			$_bookmark = & $GLOBALS['link'];
36
		} elseif ( ! $_bookmark = wp_cache_get($bookmark, 'bookmark') ) {
37
			$_bookmark = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->links WHERE link_id = %d LIMIT 1", $bookmark));
38
			if ( $_bookmark ) {
39
				$_bookmark->link_category = array_unique( wp_get_object_terms( $_bookmark->link_id, 'link_category', array( 'fields' => 'ids' ) ) );
40
				wp_cache_add( $_bookmark->link_id, $_bookmark, 'bookmark' );
41
			}
42
		}
43
	}
44
45
	if ( ! $_bookmark )
46
		return $_bookmark;
47
48
	$_bookmark = sanitize_bookmark($_bookmark, $filter);
49
50
	if ( $output == OBJECT ) {
51
		return $_bookmark;
52
	} elseif ( $output == ARRAY_A ) {
53
		return get_object_vars($_bookmark);
54
	} elseif ( $output == ARRAY_N ) {
55
		return array_values(get_object_vars($_bookmark));
56
	} else {
57
		return $_bookmark;
58
	}
59
}
60
61
/**
62
 * Retrieve single bookmark data item or field.
63
 *
64
 * @since 2.3.0
65
 *
66
 * @param string $field The name of the data field to return
67
 * @param int $bookmark The bookmark ID to get field
68
 * @param string $context Optional. The context of how the field will be used.
69
 * @return string|WP_Error
70
 */
71 View Code Duplication
function get_bookmark_field( $field, $bookmark, $context = 'display' ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
	$bookmark = (int) $bookmark;
73
	$bookmark = get_bookmark( $bookmark );
74
75
	if ( is_wp_error($bookmark) )
76
		return $bookmark;
77
78
	if ( !is_object($bookmark) )
79
		return '';
80
81
	if ( !isset($bookmark->$field) )
82
		return '';
83
84
	return sanitize_bookmark_field($field, $bookmark->$field, $bookmark->link_id, $context);
85
}
86
87
/**
88
 * Retrieves the list of bookmarks
89
 *
90
 * Attempts to retrieve from the cache first based on MD5 hash of arguments. If
91
 * that fails, then the query will be built from the arguments and executed. The
92
 * results will be stored to the cache.
93
 *
94
 * @since 2.1.0
95
 *
96
 * @global wpdb $wpdb WordPress database abstraction object.
97
 *
98
 * @param string|array $args {
99
 *     Optional. String or array of arguments to retrieve bookmarks.
100
 *
101
 *     @type string   $orderby        How to order the links by. Accepts post fields. Default 'name'.
102
 *     @type string   $order          Whether to order bookmarks in ascending or descending order.
103
 *                                    Accepts 'ASC' (ascending) or 'DESC' (descending). Default 'ASC'.
104
 *     @type int      $limit          Amount of bookmarks to display. Accepts 1+ or -1 for all.
105
 *                                    Default -1.
106
 *     @type string   $category       Comma-separated list of category ids to include links from.
107
 *                                    Default empty.
108
 *     @type string   $category_name  Category to retrieve links for by name. Default empty.
109
 *     @type int|bool $hide_invisible Whether to show or hide links marked as 'invisible'. Accepts
110
 *                                    1|true or 0|false. Default 1|true.
111
 *     @type int|bool $show_updated   Whether to display the time the bookmark was last updated.
112
 *                                    Accepts 1|true or 0|false. Default 0|false.
113
 *     @type string   $include        Comma-separated list of bookmark IDs to include. Default empty.
114
 *     @type string   $exclude        Comma-separated list of bookmark IDs to exclude. Default empty.
115
 * }
116
 * @return array List of bookmark row objects.
117
 */
118
function get_bookmarks( $args = '' ) {
119
	global $wpdb;
120
121
	$defaults = array(
122
		'orderby' => 'name', 'order' => 'ASC',
123
		'limit' => -1, 'category' => '',
124
		'category_name' => '', 'hide_invisible' => 1,
125
		'show_updated' => 0, 'include' => '',
126
		'exclude' => '', 'search' => ''
127
	);
128
129
	$r = wp_parse_args( $args, $defaults );
130
131
	$key = md5( serialize( $r ) );
132
	$cache = false;
133
	if ( 'rand' !== $r['orderby'] && $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ) ) {
134
		if ( is_array( $cache ) && isset( $cache[ $key ] ) ) {
135
			$bookmarks = $cache[ $key ];
136
			/**
137
			 * Filters the returned list of bookmarks.
138
			 *
139
			 * The first time the hook is evaluated in this file, it returns the cached
140
			 * bookmarks list. The second evaluation returns a cached bookmarks list if the
141
			 * link category is passed but does not exist. The third evaluation returns
142
			 * the full cached results.
143
			 *
144
			 * @since 2.1.0
145
			 *
146
			 * @see get_bookmarks()
147
			 *
148
			 * @param array $bookmarks List of the cached bookmarks.
149
			 * @param array $r         An array of bookmark query arguments.
150
			 */
151
			return apply_filters( 'get_bookmarks', $bookmarks, $r );
152
		}
153
	}
154
155
	if ( ! is_array( $cache ) ) {
156
		$cache = array();
157
	}
158
159
	$inclusions = '';
160
	if ( ! empty( $r['include'] ) ) {
161
		$r['exclude'] = '';  //ignore exclude, category, and category_name params if using include
162
		$r['category'] = '';
163
		$r['category_name'] = '';
164
		$inclinks = preg_split( '/[\s,]+/', $r['include'] );
165
		if ( count( $inclinks ) ) {
166
			foreach ( $inclinks as $inclink ) {
167
				if ( empty( $inclusions ) ) {
168
					$inclusions = ' AND ( link_id = ' . intval( $inclink ) . ' ';
169
				} else {
170
					$inclusions .= ' OR link_id = ' . intval( $inclink ) . ' ';
171
				}
172
			}
173
		}
174
	}
175
	if (! empty( $inclusions ) ) {
176
		$inclusions .= ')';
177
	}
178
179
	$exclusions = '';
180 View Code Duplication
	if ( ! empty( $r['exclude'] ) ) {
181
		$exlinks = preg_split( '/[\s,]+/', $r['exclude'] );
182
		if ( count( $exlinks ) ) {
183
			foreach ( $exlinks as $exlink ) {
184
				if ( empty( $exclusions ) ) {
185
					$exclusions = ' AND ( link_id <> ' . intval( $exlink ) . ' ';
186
				} else {
187
					$exclusions .= ' AND link_id <> ' . intval( $exlink ) . ' ';
188
				}
189
			}
190
		}
191
	}
192
	if ( ! empty( $exclusions ) ) {
193
		$exclusions .= ')';
194
	}
195
196
	if ( ! empty( $r['category_name'] ) ) {
197
		if ( $r['category'] = get_term_by('name', $r['category_name'], 'link_category') ) {
198
			$r['category'] = $r['category']->term_id;
199
		} else {
200
			$cache[ $key ] = array();
201
			wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
202
			/** This filter is documented in wp-includes/bookmark.php */
203
			return apply_filters( 'get_bookmarks', array(), $r );
204
		}
205
	}
206
207
	$search = '';
208
	if ( ! empty( $r['search'] ) ) {
209
		$like = '%' . $wpdb->esc_like( $r['search'] ) . '%';
210
		$search = $wpdb->prepare(" AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ", $like, $like, $like );
211
	}
212
213
	$category_query = '';
214
	$join = '';
215 View Code Duplication
	if ( ! empty( $r['category'] ) ) {
216
		$incategories = preg_split( '/[\s,]+/', $r['category'] );
217
		if ( count($incategories) ) {
218
			foreach ( $incategories as $incat ) {
219
				if ( empty( $category_query ) ) {
220
					$category_query = ' AND ( tt.term_id = ' . intval( $incat ) . ' ';
221
				} else {
222
					$category_query .= ' OR tt.term_id = ' . intval( $incat ) . ' ';
223
				}
224
			}
225
		}
226
	}
227
	if ( ! empty( $category_query ) ) {
228
		$category_query .= ") AND taxonomy = 'link_category'";
229
		$join = " INNER JOIN $wpdb->term_relationships AS tr ON ($wpdb->links.link_id = tr.object_id) INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id";
230
	}
231
232
	if ( $r['show_updated'] ) {
233
		$recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated ";
234
	} else {
235
		$recently_updated_test = '';
236
	}
237
238
	$get_updated = ( $r['show_updated'] ) ? ', UNIX_TIMESTAMP(link_updated) AS link_updated_f ' : '';
239
240
	$orderby = strtolower( $r['orderby'] );
241
	$length = '';
242
	switch ( $orderby ) {
243
		case 'length':
244
			$length = ", CHAR_LENGTH(link_name) AS length";
245
			break;
246
		case 'rand':
247
			$orderby = 'rand()';
248
			break;
249
		case 'link_id':
250
			$orderby = "$wpdb->links.link_id";
251
			break;
252
		default:
253
			$orderparams = array();
254
			$keys = array( 'link_id', 'link_name', 'link_url', 'link_visible', 'link_rating', 'link_owner', 'link_updated', 'link_notes', 'link_description' );
255
			foreach ( explode( ',', $orderby ) as $ordparam ) {
256
				$ordparam = trim( $ordparam );
257
258
				if ( in_array( 'link_' . $ordparam, $keys ) ) {
259
					$orderparams[] = 'link_' . $ordparam;
260
				} elseif ( in_array( $ordparam, $keys ) ) {
261
					$orderparams[] = $ordparam;
262
				}
263
			}
264
			$orderby = implode( ',', $orderparams );
265
	}
266
267
	if ( empty( $orderby ) ) {
268
		$orderby = 'link_name';
269
	}
270
271
	$order = strtoupper( $r['order'] );
272
	if ( '' !== $order && ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
273
		$order = 'ASC';
274
	}
275
276
	$visible = '';
277
	if ( $r['hide_invisible'] ) {
278
		$visible = "AND link_visible = 'Y'";
279
	}
280
281
	$query = "SELECT * $length $recently_updated_test $get_updated FROM $wpdb->links $join WHERE 1=1 $visible $category_query";
282
	$query .= " $exclusions $inclusions $search";
283
	$query .= " ORDER BY $orderby $order";
284
	if ( $r['limit'] != -1 ) {
285
		$query .= ' LIMIT ' . $r['limit'];
286
	}
287
288
	$results = $wpdb->get_results( $query );
289
290
	if ( 'rand()' !== $orderby ) {
291
		$cache[ $key ] = $results;
292
		wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
293
	}
294
295
	/** This filter is documented in wp-includes/bookmark.php */
296
	return apply_filters( 'get_bookmarks', $results, $r );
297
}
298
299
/**
300
 * Sanitizes all bookmark fields
301
 *
302
 * @since 2.3.0
303
 *
304
 * @param stdClass|array $bookmark Bookmark row
305
 * @param string $context Optional, default is 'display'. How to filter the
306
 *		fields
307
 * @return stdClass|array Same type as $bookmark but with fields sanitized.
308
 */
309
function sanitize_bookmark($bookmark, $context = 'display') {
310
	$fields = array('link_id', 'link_url', 'link_name', 'link_image', 'link_target', 'link_category',
311
		'link_description', 'link_visible', 'link_owner', 'link_rating', 'link_updated',
312
		'link_rel', 'link_notes', 'link_rss', );
313
314
	if ( is_object($bookmark) ) {
315
		$do_object = true;
316
		$link_id = $bookmark->link_id;
317
	} else {
318
		$do_object = false;
319
		$link_id = $bookmark['link_id'];
320
	}
321
322 View Code Duplication
	foreach ( $fields as $field ) {
323
		if ( $do_object ) {
324
			if ( isset($bookmark->$field) )
325
				$bookmark->$field = sanitize_bookmark_field($field, $bookmark->$field, $link_id, $context);
326
		} else {
327
			if ( isset($bookmark[$field]) )
328
				$bookmark[$field] = sanitize_bookmark_field($field, $bookmark[$field], $link_id, $context);
329
		}
330
	}
331
332
	return $bookmark;
333
}
334
335
/**
336
 * Sanitizes a bookmark field.
337
 *
338
 * Sanitizes the bookmark fields based on what the field name is. If the field
339
 * has a strict value set, then it will be tested for that, else a more generic
340
 * filtering is applied. After the more strict filter is applied, if the `$context`
341
 * is 'raw' then the value is immediately return.
342
 *
343
 * Hooks exist for the more generic cases. With the 'edit' context, the {@see 'edit_$field'}
344
 * filter will be called and passed the `$value` and `$bookmark_id` respectively.
345
 *
346
 * With the 'db' context, the {@see 'pre_$field'} filter is called and passed the value.
347
 * The 'display' context is the final context and has the `$field` has the filter name
348
 * and is passed the `$value`, `$bookmark_id`, and `$context`, respectively.
349
 *
350
 * @since 2.3.0
351
 *
352
 * @param string $field       The bookmark field.
353
 * @param mixed  $value       The bookmark field value.
354
 * @param int    $bookmark_id Bookmark ID.
355
 * @param string $context     How to filter the field value. Accepts 'raw', 'edit', 'attribute',
356
 *                            'js', 'db', or 'display'
357
 * @return mixed The filtered value.
358
 */
359
function sanitize_bookmark_field( $field, $value, $bookmark_id, $context ) {
360
	switch ( $field ) {
361
	case 'link_id' : // ints
362
	case 'link_rating' :
363
		$value = (int) $value;
364
		break;
365
	case 'link_category' : // array( ints )
366
		$value = array_map('absint', (array) $value);
367
		// We return here so that the categories aren't filtered.
368
		// The 'link_category' filter is for the name of a link category, not an array of a link's link categories
369
		return $value;
370
371
	case 'link_visible' : // bool stored as Y|N
372
		$value = preg_replace('/[^YNyn]/', '', $value);
373
		break;
374
	case 'link_target' : // "enum"
375
		$targets = array('_top', '_blank');
376
		if ( ! in_array($value, $targets) )
377
			$value = '';
378
		break;
379
	}
380
381
	if ( 'raw' == $context )
382
		return $value;
383
384
	if ( 'edit' == $context ) {
385
		/** This filter is documented in wp-includes/post.php */
386
		$value = apply_filters( "edit_{$field}", $value, $bookmark_id );
387
388
		if ( 'link_notes' == $field ) {
389
			$value = esc_html( $value ); // textarea_escaped
390
		} else {
391
			$value = esc_attr($value);
392
		}
393
	} elseif ( 'db' == $context ) {
394
		/** This filter is documented in wp-includes/post.php */
395
		$value = apply_filters( "pre_{$field}", $value );
396
	} else {
397
		/** This filter is documented in wp-includes/post.php */
398
		$value = apply_filters( "{$field}", $value, $bookmark_id, $context );
399
400 View Code Duplication
		if ( 'attribute' == $context ) {
401
			$value = esc_attr( $value );
402
		} elseif ( 'js' == $context ) {
403
			$value = esc_js( $value );
404
		}
405
	}
406
407
	return $value;
408
}
409
410
/**
411
 * Deletes the bookmark cache.
412
 *
413
 * @since 2.7.0
414
 *
415
 * @param int $bookmark_id Bookmark ID.
416
 */
417
function clean_bookmark_cache( $bookmark_id ) {
418
	wp_cache_delete( $bookmark_id, 'bookmark' );
419
	wp_cache_delete( 'get_bookmarks', 'bookmark' );
420
	clean_object_term_cache( $bookmark_id, 'link');
421
}
422