Mostrar el estado de seguridad en todos los enlaces externos usando la API de búsqueda de Google Safe Browsing

Hace un tiempo, buscaba una estrategia para proteger mi sitio web de enlaces externos proporcionados por miembros del foro. Estoy intentando crear mi propia base de datos de URL dañinas. Pero es más difícil de lo que parece. El gran volumen de enlaces es difícil de clasificar. Así que busqué un servicio de API que pudiera satisfacer mis necesidades y descubrí la API de Google Safe Browsing, un servicio de API gratuito proporcionado por Google, y intenté agregarlo al foro Discourse.

Resultado en mi foro
al pasar el ratón por encima

Así es como.
Para agregar un ícono después de todos los enlaces externos en Discourse y mostrar tooltips que muestren el estado de seguridad de los enlaces utilizando la API de Google Safe Browsing Lookup (v4), siga estos pasos:

  1. Cree una clave de API para Google Safe Browsing:

    • Vaya a la Google Cloud Console
    • Cree un nuevo proyecto o use uno existente
    • Habilite la API de Safe Browsing
    • Cree una clave de API para este proyecto
      *Todo es gratis.
  2. Inicie sesión en Discourse Admin:

    • Inicie sesión en Discourse con su cuenta de administrador
  3. Acceda a la personalización del tema:

    • Vaya a “Admin” → “Customize” → “Themes”
    • Seleccione el tema que desea editar o cree un nuevo tema o componente de tema
  4. Agregue CSS:

    • Haga clic en “Edit CSS/HTML” para el tema deseado

    • En la pestaña “CSS”, agregue el siguiente código:

      a[target="_blank"]:after {
          content: url('https://example.com/icon.png'); /* Reemplace con la URL de su ícono deseado */
          margin-left: 5px; /* Espaciado entre el enlace y el ícono */
          display: inline-block;
      }
      
      .tooltip {
          position: relative;
          display: inline-block;
      }
      
      .tooltip .tooltiptext {
          visibility: hidden;
          width: 200px;
          background-color: #555;
          color: #fff;
          text-align: center;
          border-radius: 6px;
          padding: 5px;
          position: absolute;
          z-index: 1;
          bottom: 125%; /* Posición del tooltip */
          left: 50%;
          margin-left: -100px;
          opacity: 0;
          transition: opacity 0.3s;
      }
      
      .tooltip:hover .tooltiptext {
          visibility: visible;
          opacity: 1;
      }
      
  5. Agregue JavaScript:

    • En la pestaña “Header” del tema, agregue el siguiente código:

      <script type="text/discourse-plugin" version="0.8">
        api.onPageChange(() => {
          const externalLinks = document.querySelectorAll('a[href^="http"]:not([href*="' + window.location.hostname + '"])');
          const apiKey = 'YOUR_GOOGLE_API_KEY'; // Reemplace con su clave de API
          const lookupUrl = 'https://safebrowsing.googleapis.com/v4/threatMatches:find?key=' + apiKey;
      
          externalLinks.forEach(link => {
            link.setAttribute('target', '_blank');
            link.classList.add('tooltip');
      
            const tooltipText = document.createElement('span');
            tooltipText.className = 'tooltiptext';
            tooltipText.innerText = 'Checking link safety...';
            link.appendChild(tooltipText);
      
            fetch(lookupUrl, {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json'
              },
              body: JSON.stringify({
                client: {
                  clientId: 'yourcompany',
                  clientVersion: '1.5.2'
                },
                threatInfo: {
                  threatTypes: ['MALWARE', 'SOCIAL_ENGINEERING'],
                  platformTypes: ['ANY_PLATFORM'],
                  threatEntryTypes: ['URL'],
                  threatEntries: [
                    { url: link.href }
                  ]
                }
              })
            })
            .then(response => response.json())
            .then(data => {
              if (data.matches && data.matches.length > 0) {
                tooltipText.innerText = 'Warning: This link may be unsafe!';
                tooltipText.style.backgroundColor = '#ff0000';
              } else {
                tooltipText.innerText = 'This link is safe.';
              }
            })
            .catch(error => {
              tooltipText.innerText = 'Error checking link safety.';
            });
          });
        });
      </script>
      

      Este JavaScript:

      • Buscará todos los enlaces externos y los configurará para que se abran en una nueva pestaña
      • Agregará un ícono después del enlace
      • Verificará el enlace utilizando la API de Google Safe Browsing y mostrará el resultado en un tooltip
  6. Guarde y aplique el tema:

    • Haga clic en “Save” para guardar sus cambios
    • Si creó un nuevo tema, configúrelo como el tema predeterminado o asígnelo a los grupos de usuarios deseados

Estos pasos asegurarán que todos los enlaces externos en su instancia de Discourse tengan un ícono después de ellos, y los tooltips mostrarán el estado de seguridad de los enlaces utilizando la API de Google Safe Browsing.

Edición para seguridad
Debe agregar su sitio web a la sección de límites del sitio web para el uso de la API de Google.

Opción

Usar ícono de Font Awesome

Para usar un ícono de Font Awesome. Aquí está el CSS actualizado:

CSS actualizado con íconos de Font Awesome

/* Asegúrese de que Font Awesome esté incluido */
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css');

/* Agregue el ícono de Font Awesome después de los enlaces externos */
a[target="_blank"]:after {
    content: "\\f35d"; /* Unicode para el ícono de enlace externo de Font Awesome */
    font-family: 'Font Awesome 5 Free'; /* Familia de Font Awesome */
    font-weight: 900; /* Peso sólido de Font Awesome */
    margin-left: 5px; /* Espaciado entre el enlace y el ícono */
    display: inline-block;
}

Explicación:

  1. Importación de Font Awesome:

    • El CSS comienza importando el CSS de Font Awesome desde una CDN.
  2. Adición de ícono:

    • La propiedad content en el selector a[target="_blank"]:after se establece en \"\\f35d\", que es el Unicode para el ícono de enlace externo de Font Awesome.
    • La font-family se establece en ‘Font Awesome 5 Free’ y font-weight en 900 para usar la versión sólida del ícono.

Espero que esto sea útil para aquellos que buscan lo mismo que yo.

3 Me gusta

¡Esta es una idea muy genial!

:warning: Ten en cuenta que al incluir tu clave API de Google Cloud en un componente temático, la expones al mundo. Cuando las personas tengan acceso a tu clave API, potencialmente podrían generarte una factura muy grande. :warning:
Debes asegurarte de que tu clave API esté suficientemente acotada (por ejemplo, solo puede acceder a la API de Safe Browsing) o debes agregar un proxy del lado del servidor para mantener la clave API segura en tu servidor.

3 Me gusta

O… convierte esto en un plugin y mantén la conversación de la API sucediendo detrás de escena donde nadie pueda ver.

1 me gusta

Eso es lo que intenté decir :wink:

2 Me gusta

Bueno, un proxy es un tipo especial de intermediario y también una buena idea.

Definitivamente fue un OR.

1 me gusta

Gracias por el gran consejo. :blush: Creo que hay un mecanismo para bloquear el acceso a la API en la Consola de Google Cloud; añade tu sitio web allí.

Porque carezco de las habilidades necesarias para escribir plugins. Creo que esta estrategia es básica y sencilla. Pero si hay personas que desean crear, creo que es superior a mi manera. Y estaré muy emocionado.

1 me gusta

Y mientras tanto, incluso propondría que esto podría valer la pena para una solicitud de función.

(Si ese servicio es responsable, eso no lo sé)

3 Me gusta

No hago promesas, pero cuando tenga algo de tiempo libre en los próximos meses, definitivamente lo consideraré.

2 Me gusta

Me alegra haber captado tu atención y aprecio el interés que mostraste en crear este plugin.

Espero y me complace ver esto también en la función.

¿Alguien sabe si esto funciona con la versión autoalojada de Discourse? No parece haber una opción en Administración para “Personalizar” la configuración del tema.

No hay Configuración de Tema en ese tema, el archivo de configuración está vacío:

Además, para cambiar un Tema descargado de GitHub, necesitas bifurcarlo, editar tu bifurcación y usar tu bifurcación.

2 Me gusta

Puedes crear un nuevo componente de tema y añadirlo a tu tema.

2 Me gusta