<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Miguel Angel Falcón Muñoz</title>
    <description>The latest articles on DEV Community by Miguel Angel Falcón Muñoz (@falconmfm).</description>
    <link>https://dev.to/falconmfm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F680715%2Fd8511bc1-0cef-4003-97f5-8f1b181cd72f.jpeg</url>
      <title>DEV Community: Miguel Angel Falcón Muñoz</title>
      <link>https://dev.to/falconmfm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/falconmfm"/>
    <language>en</language>
    <item>
      <title>Limitar ataques a xmlrpc en Kubernetes</title>
      <dc:creator>Miguel Angel Falcón Muñoz</dc:creator>
      <pubDate>Thu, 26 Aug 2021 17:00:51 +0000</pubDate>
      <link>https://dev.to/falconmfm/limitar-ataques-a-xmlrpc-en-kubernetes-4ip7</link>
      <guid>https://dev.to/falconmfm/limitar-ataques-a-xmlrpc-en-kubernetes-4ip7</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fggm3Srf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcqfaqzxxktgsirkwr7x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fggm3Srf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jcqfaqzxxktgsirkwr7x.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Si has montado un wordpress en un cluster de Kubernetes y lo has publicado, habrás notado que al poco tiempo comienza a dar algunos problemas. No te preocupes no es tu fallo, puedes estar sufriendo un ataque de denegación de servicio. En esta entrada vamos a explicar cómo mitigarlo.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Por si no te suenan las sigas &lt;a href="https://es.wikipedia.org/wiki/Ataque_de_denegaci%C3%B3n_de_servicio"&gt;DDoS ( Denial Of Services )&lt;/a&gt; es un tipo de ataque que consigue que un servicio publicado en internet deje de funcionar de forma adecuada. En algunas ocasiones puede ser un ataque completamente dirigido con un objetivo claro y en otras puede ser un daño colateral de cualquier otra actividad. Si se trata del primer caso , la solución puede ser un poco más compleja que la que planteamos hoy aquí , en mi caso se trata de un escaneo masivo desde distintas IP’s a un recurso que está accesible por defecto en WordPress , es “/xmlrpc.php” .&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué hay detrás de &lt;a href="https://codex.wordpress.org/XML-RPC_WordPress_API"&gt;XML RPC&lt;/a&gt; en WordPress ?
&lt;/h2&gt;

&lt;p&gt;Se trata de un servicio de acceso remoto que permite interactuar con nuestro wordpress. Ideado en 2016 e incluido en la versión 2.6 de WordPress ha sido recientemente “reemplazado” por la &lt;a href="https://codex.wordpress.org/WordPress.org_API"&gt;API REST&lt;/a&gt;. Por tanto es muy probable que no lo necesites más.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué es un peligro tenerlo activo?
&lt;/h2&gt;

&lt;p&gt;Desde hace años es posible empleando este servicio que tu WordPress envíe “pings” a otras direcciones web. Un atacante puede usando tu sitio y otros que tengan XML-RPC activo lanzar ataques masivos sobre una Web concreta , por lo que sería partícipe, inconscientemente, del primer caso de &lt;a href="https://es.wikipedia.org/wiki/Ataque_de_denegaci%C3%B3n_de_servicio"&gt;DDoS&lt;/a&gt; que hemos comentado.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué me afecta a mi sitio?
&lt;/h2&gt;

&lt;p&gt;Cuando estos ataques emplean tu web consumen los recursos de tu sistema por lo que puedes experimentar problemas de uso de memoria o lentitud en tu web por falta de CPU. Si prestas atención a tu fichero de logs podrás observar muchas entradas como esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;1XX.XXX.XXX.XXX - - &lt;span class="o"&gt;[&lt;/span&gt;01/Jan/2021:00:00:01 +0000] &lt;span class="s2"&gt;"POST /xmlrpc.php HTTP/1.1"&lt;/span&gt; 200 222
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ¿Cómo puede verificar si está accesible el recurso xmlrpc ?
&lt;/h2&gt;

&lt;p&gt;Una forma muy sencilla es acudir a un &lt;a href="https://xmlrpc.eritreo.it/"&gt;servicio de validación&lt;/a&gt;, que comprobará tu sitio y te dirá si xmlrpc.php está habilitado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CvA0tRd---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5gg6075180pg8y00rfq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CvA0tRd---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5gg6075180pg8y00rfq.png" alt="WordPress XML-RPC Validation Service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cuando indique la url de tu wordpress, si el sitio puede acceder a tu xmlrpc te lo indicará con una pantalla como esta.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--odIjZ4TZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7il3zenfqopi2tes6u8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--odIjZ4TZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7il3zenfqopi2tes6u8s.png" alt="XML-RPC está accesible y supone un riesgo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En el caso de que esta no sea accesible la pantalla será como la siguiente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eVE-g3s4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzc0dnwa6ehpym6x0t2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eVE-g3s4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzc0dnwa6ehpym6x0t2j.png" alt="XML-RPC ha sido desactivado"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Como puedo eliminar el acceso a este recurso?
&lt;/h2&gt;

&lt;p&gt;Cuando se trata de un WordPress alojado en un servicidor VPC , la solución es bastante fácil. Tan solo tenemos que denegar el acceso a este recurso en la configuración de nuestro servidor web. Ya sea mediante configuración o mediante el fichero .htaccess , vamos a indicar como:&lt;/p&gt;

&lt;p&gt;En el caso del fichero .htaccess debemos añadir lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="c"&gt;# Block WordPress xmlrpc.php requests&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;Files&lt;/span&gt;&lt;span class="sr"&gt; xmlrpc.php&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="nc"&gt;order&lt;/span&gt; deny,allow
&lt;span class="nc"&gt;deny&lt;/span&gt; &lt;span class="ss"&gt;from&lt;/span&gt; &lt;span class="ss"&gt;all&lt;/span&gt;
&lt;span class="nc"&gt;allow&lt;/span&gt; &lt;span class="ss"&gt;from&lt;/span&gt; &lt;span class="ss"&gt;none&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;Files&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En el caso de un servidor web nginx, la configuración será :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;# IMPORTANT: for security purposes, disable access to xmlrpc&lt;/span&gt;
&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;/xmlrpc.php&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kn"&gt;deny&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;log_not_found&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ¿Qué pasa cuando WordPress se publica en Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Pues en este caso es probable que emplees un balanceador de carga de tu proveedor y un controlador de ingress dentro del cluster Kubernetes para habilitar el acceso a los distintos servicios que publicas.&lt;/p&gt;

&lt;p&gt;En este caso debemos modificar el ingress asociado a WordPress para que descarte las peticiones que van dirigidas al recurso xmlrpc mediante un código de error.&lt;/p&gt;

&lt;p&gt;Si como en mi caso empleas un controlador de ingress basado en nginx , uno de los más populares y que mejor rendimiento proporcionan tendrás que seguir los siguientes pasos.&lt;/p&gt;

&lt;p&gt;Comencemos listando todos los ingress e identificando el que está asociado al dominio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get ingress                                                                                                                                                                                                     
NAME      CLASS    HOSTS             ADDRESS                                     PORTS     AGE
wordpress &amp;lt;none&amp;gt;   www.domain.com    abcdefXXXXXXX.ab-east-4.elb.amazonaws.com   80, 443   1d20h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ya hemos identificado como se llama , podemos obtener toda la configuración y enviarla a un fichero con :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get ingress wordpress &lt;span class="nt"&gt;-o&lt;/span&gt; yaml &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; wordpress.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veamos el contenido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;extensions/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;cert-manager.io/issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-issuer&lt;/span&gt;
    &lt;span class="s"&gt;kubernetes.io/ingress.class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="s"&gt;kubernetes.io/tls-acme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
    &lt;span class="s"&gt;meta.helm.sh/release-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="s"&gt;meta.helm.sh/release-namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="s"&gt;nginx.ingress.kubernetes.io/force-ssl-redirect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;app.kubernetes.io/instance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="s"&gt;app.kubernetes.io/managed-by&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Helm&lt;/span&gt;
    &lt;span class="s"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="s"&gt;helm.sh/chart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-XX.X.X&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;www.domain.com&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-service&lt;/span&gt;
          &lt;span class="na"&gt;servicePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
        &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ImplementationSpecific&lt;/span&gt;
  &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;www.domain.com&lt;/span&gt;
    &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-tls&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;loadBalancer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;abcdefXXXXXXX.ab-east-4.elb.amazonaws.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Debemos agregar a esta configuración una nueva anotación que se encargará de denegar el acceso y enviar un error 403 cuando se solicite el recurso “/xmlrcp.php”&lt;/p&gt;

&lt;p&gt;Quedando el fichero así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;extensions/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;cert-manager.io/issuer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-issuer&lt;/span&gt;
    &lt;span class="s"&gt;kubernetes.io/ingress.class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="s"&gt;kubernetes.io/tls-acme&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
    &lt;span class="s"&gt;meta.helm.sh/release-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="s"&gt;meta.helm.sh/release-namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="s"&gt;nginx.ingress.kubernetes.io/force-ssl-redirect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
    &lt;span class="s"&gt;nginx.ingress.kubernetes.io/server-snippet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;location ~* "^/xmlrpc.php" {&lt;/span&gt;
          &lt;span class="s"&gt;deny all;&lt;/span&gt;
          &lt;span class="s"&gt;return 403;&lt;/span&gt;
        &lt;span class="s"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;app.kubernetes.io/instance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="s"&gt;app.kubernetes.io/managed-by&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Helm&lt;/span&gt;
    &lt;span class="s"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
    &lt;span class="s"&gt;helm.sh/chart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-XX.X.X&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;www.domain.com&lt;/span&gt;
    &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;serviceName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-service&lt;/span&gt;
          &lt;span class="na"&gt;servicePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
        &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ImplementationSpecific&lt;/span&gt;
  &lt;span class="na"&gt;tls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;www.domain.com&lt;/span&gt;
    &lt;span class="na"&gt;secretName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wordpress-tls&lt;/span&gt;
&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;loadBalancer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;abcdefXXXXXXX.ab-east-4.elb.amazonaws.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tan solo debemos aplicar la nueva configuración y de inmediato dejarán de estar accesible el recurso.&lt;/p&gt;

&lt;p&gt;Si revisar el log del pod asociado a wordpress observarás de inmediato que desaparecen las peticiones al recurso, y verás como se reduce el uso de recursos de la web.&lt;/p&gt;

&lt;p&gt;El original está disponible en &lt;a href="https://www.falc0n.es/limitar-ataques-a-xmlrpc-en-kubernetes"&gt;el blog de falc0n.es&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>wordpress</category>
      <category>nginx</category>
      <category>ddos</category>
    </item>
    <item>
      <title>Cómo mejorar la seguridad de tu API </title>
      <dc:creator>Miguel Angel Falcón Muñoz</dc:creator>
      <pubDate>Fri, 06 Aug 2021 15:47:14 +0000</pubDate>
      <link>https://dev.to/falconmfm/como-mejorar-la-seguridad-de-tu-api-56jb</link>
      <guid>https://dev.to/falconmfm/como-mejorar-la-seguridad-de-tu-api-56jb</guid>
      <description>&lt;h2&gt;
  
  
  Como mejorar la seguridad de tu API
&lt;/h2&gt;

&lt;p&gt;Existen en el mercado muchísimas herramientas que te ayudan a incrementar la seguridad de tu API, comenzando a bajo nivel mediante la revisión de vulnerabilidades de las librerías que emplea tu framework de desarrollo favorito hasta simulaciones de intentos de romper la API una vez publicada. &lt;/p&gt;

&lt;p&gt;Hoy nos centraremos en estas últimas pero empleandolas en las primeras fases del desarrollo. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hSYKZYbz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhalpg076cructhohdeg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hSYKZYbz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhalpg076cructhohdeg.png" alt="Stackhawk Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usaremos &lt;a href="https://stackhawk.com"&gt;&lt;strong&gt;stackhack&lt;/strong&gt;&lt;/a&gt; , un servicio cloud que nos permite escanear nuestra API mediante fuerza bruta para identificar ciertas vulnerabilidades que podrían ser aprovechadas por un atacante que cuando la API esté publicada y expuesta al público.&lt;/p&gt;

&lt;h2&gt;
  
  
  Accediendo al servicio
&lt;/h2&gt;

&lt;p&gt;Darse de alta en stackhawk.com es muy sencillo y en pocos minutos nos habrá proporcionado una cuenta para desarrolladores con 15 días de prueba. &lt;br&gt;
Es importante que en el proceso de registro y mientras seguimos la guía guardemos el token de acceso que nos proporciona en un lugar seguro y además lo añadamos al fichero de configuración según los pasos que se indica. &lt;/p&gt;

&lt;p&gt;Ya en el último paso nos indicará que descarguemos una plantilla del fichero de configuración.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cómo funciona stackhawk
&lt;/h2&gt;

&lt;p&gt;El funcionamiento es bien sencillo , pero no exento de cumplir unas mínimas reglas. &lt;/p&gt;

&lt;p&gt;Dispondremos en su página web de un espacio de trabajo donde se representarán los "entornos" y se asociarán los resultados de las revisiones de nuestra aplicación. &lt;/p&gt;

&lt;p&gt;Las revisiones se ejecutarán en nuestro equipo local mediante un contenedor de docker, por ello es importante que tengamos -docker- funcionando correctamente en nuestro equipo. En todo momento la url donde se encuentre publicada la API debe ser accesible desde nuestro equipo, en nuestro caso la API corre en &lt;em&gt;&lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;&lt;/em&gt; , por lo que no habrá ningún problema.&lt;/p&gt;

&lt;p&gt;Cada vez que revisamos la API desde la línea de comando recibiremos un informe y este será remitido al espacio de trabajo de &lt;strong&gt;stackhawk&lt;/strong&gt; por lo que podremos consultar los distintos informes y ver cómo afectan los cambios incorporados.&lt;/p&gt;
&lt;h2&gt;
  
  
  Por dónde comenzamos
&lt;/h2&gt;

&lt;p&gt;El primer punto es configurar mediante la plantilla unos parámetros mínimos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;applicationId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;XXXXX-XXXX-XXXX-XXXX-XXXXXXXXX&lt;/span&gt; &lt;span class="c1"&gt;# (required)&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Development&lt;/span&gt; &lt;span class="c1"&gt;# (required)&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000/'&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;./openapi.json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Habremos recibido una applicationId que representa la aplicación que vamos a testear. Podemos obtener uno desde el espacio de trabajo al pulsar sobre "Add an APP" aunque por estar en la versión demo solo podremos tener una aplicación.&lt;/p&gt;

&lt;p&gt;Es importante indicar un entorno, ya que todas las ejecuciones se agrupan por este campo. &lt;/p&gt;

&lt;p&gt;Indicaremos el &lt;strong&gt;host&lt;/strong&gt; , sin indicar la ruta a la API, pero si el puerto. &lt;br&gt;
(*) Recordar en todo momento emplear las comillas simples de lo contrario obtendréis un mensaje como este:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Error: HawkScan is unable to &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Please check the target host configuration -
        host: &lt;span class="s2"&gt;"http://localhost:3000/"&lt;/span&gt;,
Be sure to include any additional host paths with their respected keys.
&lt;span class="o"&gt;(&lt;/span&gt;e.g. &lt;span class="sb"&gt;`&lt;/span&gt;loginPath&lt;span class="sb"&gt;`&lt;/span&gt; or &lt;span class="sb"&gt;`&lt;/span&gt;schemaPath&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ahora quizás lo más complicado es que debemos disponer de la especificación &lt;strong&gt;openapi&lt;/strong&gt; o &lt;strong&gt;swagger&lt;/strong&gt; de nuestra API en formato .json o .yaml &lt;/p&gt;

&lt;p&gt;Y debemos revisar que los recursos se correspondan con el uri completo. &lt;br&gt;
En mi ejemplo la api se encuentra en &lt;strong&gt;/api&lt;/strong&gt; , y el recurso es &lt;strong&gt;/qrisk2&lt;/strong&gt; , por ello en la definición de la api se modificar por :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;paths"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/qrisk2"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;responses"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;200"&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Arrancamos
&lt;/h2&gt;

&lt;p&gt;Bien con esto preparado es el momento de recibir nuestro primer resultado, para ello ejecutamos el contenedor con la siguiente línea de comandos:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.hawk/hawk.rc &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
docker run &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HAWK_API_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/hawk:rw &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-it&lt;/span&gt; stackhawk/hawkscan:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;La primera vez que ejecutemos tardará un momento en descargar la imagen y una vez que comience la ejecución nos aparecerá algo similar a ...&lt;/p&gt;


&lt;div class="ltag_asciinema"&gt;
  
&lt;/div&gt;



&lt;p&gt;Bien , ya tenemos nuestro primer informe. Veamos que podemos mejorar.&lt;/p&gt;

&lt;p&gt;Al acceder al espacio de trabajo vemos nuestro entorno &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gyrXQ-cz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/he7bul6v4xloropnlhse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gyrXQ-cz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/he7bul6v4xloropnlhse.png" alt="Environment in StackHawk"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si pulsamos sobre el símbolo &lt;strong&gt;" ⋮ "&lt;/strong&gt; , podemos seleccionar &lt;strong&gt;View Scans&lt;/strong&gt; . &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AFSRN8ij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pwu9vdxu8li7zjleiln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AFSRN8ij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9pwu9vdxu8li7zjleiln.png" alt="Lastest Scans"&gt;&lt;/a&gt;&lt;br&gt;
Vemos al última ejecución y nos encontramos con &lt;strong&gt;6&lt;/strong&gt; incidencias de importancia media y otras &lt;strong&gt;6&lt;/strong&gt; de carácter &lt;strong&gt;Low&lt;/strong&gt; , si las revisamos nos damos cuenta pronto que en realidad una la podemos descartar porque hace referencia a que NO disponemos de un endpoint accessible mediante &lt;strong&gt;https&lt;/strong&gt; , lógico estamos en local. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2x7ouyqy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3u9a3emni637mszspgr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2x7ouyqy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m3u9a3emni637mszspgr.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Como eliminar la primera incidencia de seguridad
&lt;/h2&gt;

&lt;p&gt;Veamos otro de los aspectos que debemos revisar en nuestro desarrollo, nos centraremos en los de nivel &lt;strong&gt;Low&lt;/strong&gt; , vemos que las &lt;strong&gt;6&lt;/strong&gt; hacen referencia al mismo problema en diferentes rutas. &lt;/p&gt;

&lt;p&gt;Esta indica que mediante el uso de la cabecera "X-Powered-By" un atacante puede identificar el framework que emplea nuestra API y puede focalizar el ataque en el o identificar una vulnerabilidad de último día que pueda afectarla. En este caso lo que debemos hacer es no aportar esta información. &lt;/p&gt;

&lt;p&gt;Mi API usa &lt;a href="https://nodejs.org/es/"&gt;Node.js&lt;/a&gt; y &lt;a href="https://expressjs.com/es/"&gt;Express&lt;/a&gt; , por lo que para solventar este inconveniente puedo apoyarme en un módulo que me facilitará mucho el trabajo , llamado &lt;a href="https://helmetjs.github.io/"&gt;&lt;strong&gt;helmet&lt;/strong&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Lo instalamos en el proyecto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;helmet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;He iremos a la sección de nuestro código donde configuramos el servidor express, importamos el módulo y hacemos uso de él.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;helmet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;helmet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Hide the X-Powered-By header&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;helmet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidePoweredBy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y voilá... &lt;br&gt;
Arrancamos de nuevo nuestra api y lanzamos de nuevo el scanner desde la línea de comando.&lt;/p&gt;

&lt;p&gt;Volvemos al espacio de trabajo y podremos observar que ya no aparecen los &lt;strong&gt;6&lt;/strong&gt; fallos de tipo &lt;strong&gt;Low&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9Pdo0sRm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/act1aiuzv41y4tjm6khv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9Pdo0sRm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/act1aiuzv41y4tjm6khv.png" alt="Scanned"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Una herramienta de estas características nos permitirá revisar que mantenemos en nuestro desarrollo un cierto nivel de control sobre la seguridad. Con el tiempo y solventando las incidencias iremos incorporando de forma continua a nuestras aplicaciones &lt;strong&gt;buenas prácticas&lt;/strong&gt; que eviten exponer información comprometida a terceros o que facilite el acceso no autorizado a nuestros servicios.&lt;/p&gt;

&lt;p&gt;Evidentemente, nunca podremos estar 100% seguros pero es un paso en la buena dirección.&lt;/p&gt;

&lt;p&gt;La plataforma de &lt;a href="https://stackhawk.com"&gt;&lt;strong&gt;stackhack&lt;/strong&gt;&lt;/a&gt; permite la integración con la mayoría de soluciones de gestión de código y de despliegue, de modo que podemos validar nuestra API antes de publicarla e incluso modificando el fichero de configuración cuando esta esté publicada en su URL final.&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
      <category>node</category>
      <category>spanish</category>
    </item>
  </channel>
</rss>
