Adding a bookmarklet to a Wordpress message

I am trying to add a javascript bookmarklet link to a post on my WordPress site. However, this does not come out in the preview. When I check the link that WordPress adds to the post, it converts it to javascript:void(0) . This simple example reproduces the problem.

 <a href="javascript:alert('Alert!');">Search Scholar</a> 

There are several other people who have had the same problem here , here , here , and here , but no seem to have found a solution that goes beyond the simple bookmarkle code for people who copy and paste and create their own bookmarklet.

The reason for this problem is that Chrome XSS protection removes javascript from the link when submitted via wp-admin. One of the "solutions" is to add a header("X-XSS-Protection: 0"); line header("X-XSS-Protection: 0"); in wp-blog-header.php to the root folder. This is not safe as it disables XSS protection on your WordPress site, but it allows the display of the bookmarklet code when the page loads.

Are there any real solutions to this problem that are not related to disabling XSS protection? Is there a plugin that I can install in my WordPress so that I can add javascript: links javascript: inside my posts?

+6
source share
2 answers

EDIT 2 After even more research, this is actually caused by the discovery of the XSS browser as indicated by OP (unlike any WordPress-specific features). The problem only occurs when you click the Preview button in WordPress and only on this initial page load. Apparently, WordPress sends some HTML files to the request headers and runs the XSS functions in the browser. If you download the preview and then refresh the page, the XSS problem disappears and the javascript: link javascript: displayed as it is saved. When viewing the actual site after publishing the page, this problem with XSS is never encountered.

EDIT After more in-depth research (working with @gnarf ), it turns out that the actual problem comes down to WordPress handling javascript: in its preview function. It would seem that WordPress has its own Javascript, which launches and converts all javascript: links to javascript:void(0) links (removing any custom code), but only if you are viewing a page. After publishing the page, javascript: links javascript: displayed correctly.


Source mail (describes how to stop WordPress from deleting javascript: links javascript: when saving the post as a non-admin user, which I suggested that the original problem could be)

WordPress seems to be crowding out HTML in the content_save_pre filter. In particular, he calls the wp_kses_bad_protocol method in wp-includes\kses.php :

 /** * Sanitize string from bad protocols. * * This function removes all non-allowed protocols from the beginning of * $string. It ignores whitespace and the case of the letters, and it does * understand HTML entities. It does its work in a while loop, so it won't be * fooled by a string like "javascript:javascript:alert(57)". * * @since 1.0.0 * * @param string $string Content to filter bad protocols from * @param array $allowed_protocols Allowed protocols to keep * @return string Filtered content */ function wp_kses_bad_protocol($string, $allowed_protocols) { $string = wp_kses_no_null($string); $iterations = 0; do { $original_string = $string; $string = wp_kses_bad_protocol_once($string, $allowed_protocols); } while ( $original_string != $string && ++$iterations < 6 ); if ( $original_string != $string ) return ''; return $string; } 

The $allowed_protocols is retrieved using the wp_allowed_protocols() method, which applies the kses_allowed_protocols filter to the protocol list.

With this information, you can bind the kses_allowed_protocols filter to add javascript as a valid one (note that this, of course, will open up security issues):

 add_filter( 'kses_allowed_protocols', function ($protocols) { $protocols[] = 'javascript'; return $protocols; }); 

One way to increase the security of this approach would be to add validation for specific users or certain roles (by default it looks like this filter does not actually run on administrative accounts, so you can use javascript: links javascript: to your heart as an administrator) until the protocol is resolved javascript .

+5
source

The original problem, of course, is related to this:

JavaScript cannot be added to a post without a special WordPress Plugin that removes filters that prevent unwanted code inside the content area to protect the user.

To avoid installing the plugin, you can use the recommended method:

A safe and recommended method for adding JavaScript to a WordPress created page and WordPress theme or plugin using wp_enqueue_script() . This function includes a script if it is not already included and safely handles dependencies.

Here are the details for wp_enqueue_script() :
http://codex.wordpress.org/Function_Reference/wp_enqueue_script

Then you need to create your own JavaScript file that you include and register, with the functions you need for your posts.

In this file, you can make a function that, for example, takes your bookmarklet link as an argument and makes document.write (or attaches node as a child of a known element) to the current location.

Then include the script and call the function in the message like:

 <script type="text/javascript" src="/scripts/myscript.js"></script> <script type="text/javascript"> <!-- bookmarklet(myLink); //--></script> 

you only need to link the script tags in the same message - if you use this script in each column, it might be better to link it in the header ( header.php template file, between meta tags and style link).

 <script type="text/javascript" src="/scripts/myscript.js"></script> 

or if this does not work:

 <script type="text/javascript" src="<?php bloginfo('template_url'); ?>/pathto/myscript.js"></script> 

Also note that if the src attribute is removed, you need to go to "Users" and "Personal Options" in the toolbar to disable the rich editor.

Source and further information on how to use JavaScript in WordPress globally and in posts:
http://codex.wordpress.org/Using_Javascript#Javascript_in_Posts

+4
source

Source: https://habr.com/ru/post/957617/


All Articles