jamie toro
Estoy tratando de agregar un enlace de marcador de javascript a una publicación en mi sitio de WordPress. Sin embargo, no sale en la vista previa de la publicación. Cuando reviso el enlace que WordPress agrega a la publicación, lo ha convertido en javascript:void(0)
. Este sencillo ejemplo reproduce el problema.
<a href="https://stackoverflow.com/questions/19844641/javascript:alert("Alert!');">Search Scholar</a>
Hay algunas otras personas que han tenido el mismo problema. aquí, aquíaquí y aquí pero nadie parece haber encontrado una solución más allá de simplemente dar su código de bookmarklet para que la gente copie y pegue y cree su propio bookmarklet.
La causa de este problema es que la protección XSS de Chrome elimina el javascript del enlace al enviarlo a través de wp-admin. Una “solución” es agregar la línea header("X-XSS-Protection: 0");
a wp-blog-header.php en la carpeta raíz. Esto es inseguro ya que desactiva la protección XSS en su sitio de WordPress, pero permite que el código del bookmarklet se represente cuando se carga la página.
¿Existen soluciones reales a este problema que no impliquen desactivar la protección XSS? ¿Hay algún complemento que pueda instalar en mi WordPress para permitirme agregar javascript:
enlaces dentro de mis publicaciones?
cmptrgeekken
EDITAR 2 Después de investigar aún más, esto en realidad es causado por la detección XSS del navegador como lo menciona el OP (a diferencia de cualquier funcionalidad específica de WordPress). El problema solo surge cuando haces clic en el Preview
botón en WordPress, y solo en esa carga de página inicial. Aparentemente, WordPress envía parte del HTML en los encabezados de solicitud, y eso activa la funcionalidad XSS en el navegador. Si carga la vista previa y luego actualiza la página, el problema de XSS desaparece y el javascript:
El enlace se muestra tal como se guardó. Al ver el sitio real, después de publicar la página, este problema de XSS nunca se encuentra presente.
EDITAR Después de una investigación más profunda (trabajando con @gnarf), resulta que el problema real se reduce a la forma en que WordPress maneja javascript:
enlaces en su función de vista previa. Parecería que WordPress tiene un Javascript personalizado que ejecuta y convierte todos javascript:
vínculos a javascript:void(0)
enlaces (eliminando cualquier código personalizado), pero solo si está obteniendo una vista previa de la página. Después de publicar la página, el javascript:
los enlaces se representan correctamente.
Publicación original (describe cómo evitar que WordPress elimine javascript:
enlaces al guardar una publicación como usuario no administrador, que es lo que supuse que podría haber sido el problema original)
Parece que WordPress elimina el HTML en el content_save_pre
filtrar. En concreto, llama a la wp_kses_bad_protocol
método en 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;
}
los $allowed_protocols
El parámetro se recupera a través del wp_allowed_protocols()
método que aplica la kses_allowed_protocols
filtrar a la lista de protocolos.
Con esta información, debería ser capaz de conectarse con el kses_allowed_protocols
filtro para agregar javascript
como válido (tenga en cuenta que esto, por supuesto, abriría problemas de seguridad):
add_filter( 'kses_allowed_protocols', function ($protocols) {
$protocols[] = 'javascript';
return $protocols;
});
Una forma de mejorar la seguridad de este enfoque sería agregar una verificación para usuarios específicos o roles específicos (de manera predeterminada, parece que este filtro realmente no es se ejecuta en cuentas administrativas, por lo que puede usar javascript:
enlaces al contenido de su corazón como administrador) antes de permitir el javascript
protocolo.
-
A una parte de mí le encanta que la solución final sea que en realidad nunca hubo un problema, solo la "vista previa" lo mostró. Espero que esto resuelva el problema para el OP también...
- gnarf
12 de noviembre de 2013 a las 6:12
-
Confirmado, solucionado. Al cargar una vista previa de una página publicada anteriormente, se muestra la
javascript:void(0)
. Después de actualizar la página de vista previa, el código aparece como se esperaba. Me alegro de haber llegado al fondo de eso.– Jaime Toro
12 de noviembre de 2013 a las 8:49
El problema inicial es, por supuesto, debido a esto:
No se puede agregar JavaScript al contenido de la publicación sin un complemento especial de WordPress que elimine los filtros que evitan el código no deseado dentro del área de contenido de la publicación para la protección del usuario.
Para evitar la instalación de un complemento, puede utilizar el método recomendado:
El método seguro y recomendado para agregar JavaScript a una página generada por WordPress y un tema o complemento de WordPress es mediante el uso de
wp_enqueue_script()
. Esta función incluye el script si aún no se ha incluido y maneja las dependencias de manera segura.
Aquí están todos los detalles para wp_enqueue_script()
:
http://codex.wordpress.org/Function_Reference/wp_enqueue_script
Luego debe crear un archivo JavaScript personalizado que incluya y registre con las funciones que necesita para sus publicaciones.
Puede en ese archivo hacer una función que, por ejemplo, tome su enlace de bookmarklet como argumento y haga una document.write
(o adjunta un nodo como hijo a un elemento conocido) a la ubicación actual.
Luego incluya el script y llame a la función en la publicación como:
<script type="text/javascript" src="https://stackoverflow.com/scripts/myscript.js"></script>
<script type="text/javascript">
<!--
bookmarklet(myLink);
//--></script>
solo necesita vincular los scripts en la misma publicación; si usa este script en cada publicación, probablemente sea mejor vincularlo en el encabezado (header.php
archivo de plantilla, entre las etiquetas meta y el enlace de la hoja de estilo).
<script type="text/javascript" src="https://stackoverflow.com/scripts/myscript.js"></script>
o alternativamente si lo anterior no funciona:
<script type="text/javascript" src="https://stackoverflow.com/questions/19844641/<?php bloginfo("template_url'); ?>/pathto/myscript.js"></script>
También tenga en cuenta que si el src
el atributo se elimina, debe ir a Usuarios y Opciones personales en el tablero para desactivar el editor enriquecido.
Fuente y más información sobre cómo usar JavaScript en WordPress globalmente y en publicaciones:
http://codex.wordpress.org/Using_Javascript#Javascript_in_Posts
-
Gracias por la información, +1 aunque siento que esto no responde a la pregunta. ¿Conoce un complemento que podría hacer esto que ya existe? Preferiría no piratear mi propio tema solo para poder agregar un enlace de bookmarklet a una de mis publicaciones de wp. ¿Estás sugiriendo tal vez algo como
<a href="#" data-bookmarklet="alert('boo')">bookmarklet</a>
y algo de JS que se incluye para hacer$("a[data-bookmarklet]").each(function() { this.href = 'javascript:' + $(this).data('bookmarklet'); });
dentro del cuerpo de la publicación? ¿Puede darnos algunos pasos mejores para crear este complemento/solucionar esto?- gnarf
11 de noviembre de 2013 a las 23:17
-
@gnarf En realidad estaba buscando un complemento para hacer esto antes de responder y no pude encontrar ninguno. Encontré complementos genéricos para compartir la página/publicación, pero ninguno en el que pudieras personalizarlos con tu propio enlace/script. Estaba considerando hacer una demostración en mi propio blog de WP, pero no puedo hacerlo hoy. Intentaré actualizar mi respuesta con un ejemplo y una demostración mañana. Dicho esto, no poder hacer esto (al menos a nivel de publicación, sin complemento, sin enfoque de configuración) también es una respuesta si ese es el caso, en mi opinión.
– usuario1693593
11 de noviembre de 2013 a las 23:32
-
¡Gracias por el compromiso! Una respuesta que puedo implementar siguiendo algunos pasos es lo que quiero ver para la recompensa. Siento que probablemente tenga los conocimientos para llevar esto a casa y ser una respuesta de estilo "guía para agregar un bookmarklet a una publicación de wp" (con o sin un complemento personalizado) :)
- gnarf
12 de noviembre de 2013 a las 4:05
Nunca he usado WordPress, pero mi primer instinto sería buscar en el código “void(0)”.
– DG.
8 de noviembre de 2013 a las 2:27
¿Estás seguro de que es Chrome el que lo está eliminando y no WordPress? ¿Solo ves este comportamiento en Chrome?
– Persona especial
11 de noviembre de 2013 a las 18:48
Otros navegadores (IE8+, probablemente otros) entienden este encabezado, aunque no hay ninguna especificación que diga lo que debería hacer que yo pueda encontrar. Chrome podría ser el único que elimina javascript de los bookmarklets, pero me imagino que todos hacen cosas como eliminar
- gnarf
11 de noviembre de 2013 a las 19:04