<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Orlando Flores Teomitzi</title><description>Un blog personal sobre desarrollo web y otros temas de tecnología, por Orlando Flores Teomitzi.</description><link>https://orfloresti.dev</link><language>es</language><item><title>Bienvenido</title><link>https://orfloresti.dev/es/posts/welcome</link><guid isPermaLink="true">https://orfloresti.dev/es/posts/welcome</guid><description>Nota de bienvenida a mi sitio web</description><pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Me alegra que estés aquí. Este espacio es donde comparto mi recorrido por la tecnología, la creatividad y el aprendizaje continuo. Encontrarás publicaciones sobre desarrollo de software, proyectos personales y reflexiones sobre temas variados que me inspiran, desde la innovación y el diseño hasta la productividad y las lecciones de vida.&lt;/p&gt;
&lt;p&gt;Mi objetivo es crear contenido que no solo muestre mi trabajo, sino que también aporte valor a quienes comparten la misma curiosidad y pasión por la tecnología. Ya sea que vengas a explorar ideas, aprender algo nuevo o simplemente inspirarte, espero que disfrutes tu visita y encuentres algo significativo.&lt;/p&gt;
</content:encoded><author>Orlando Flores Teomitzi</author></item><item><title>Mis notas sobre el modelo C4</title><link>https://orfloresti.dev/es/posts/c4-model</link><guid isPermaLink="true">https://orfloresti.dev/es/posts/c4-model</guid><description>Mis notas sobre el modelo C4: cuatro niveles de diagramas para explicar un sistema de software.</description><pubDate>Wed, 19 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;C4 es una forma de dibujar un sistema de software. En lugar de un solo diagrama enorme con todo adentro, haces varios diagramas, cada uno con un nivel de detalle distinto. Funciona como un mapa: primero el país, luego la ciudad y al final la calle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    L1[1. Contexto] --&amp;gt; L2[2. Contenedores]
    L2 --&amp;gt; L3[3. Componentes]
    L3 --&amp;gt; L4[4. Código]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Los cuatro niveles&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. Contexto.&lt;/strong&gt; El sistema como una sola caja, con los usuarios y los otros sistemas a su alrededor. Muestra qué es el sistema y quién lo usa.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Contenedores.&lt;/strong&gt; Abro la caja y veo las partes que se ejecutan por sí solas: una app web, una API, una base de datos. Muestra cómo se comunican entre sí.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Componentes.&lt;/strong&gt; Abro un contenedor y veo las piezas que tiene dentro y cómo interactúan.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Código.&lt;/strong&gt; Las clases e interfaces detrás de un componente.&lt;/p&gt;
&lt;h2&gt;Cómo construir uno&lt;/h2&gt;
&lt;p&gt;Voy de afuera hacia adentro:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Defino el contexto: reúno los requisitos y decido qué queda fuera del sistema.&lt;/li&gt;
&lt;li&gt;Divido el sistema en contenedores y mapeo cómo se relacionan.&lt;/li&gt;
&lt;li&gt;Divido cada contenedor en componentes y mapeo cómo interactúan.&lt;/li&gt;
&lt;li&gt;Detallo el código, solo donde valga la pena.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Buenas prácticas&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ser consistente en la forma de dibujar.&lt;/li&gt;
&lt;li&gt;Elegir el nivel de detalle y mantenerse en él.&lt;/li&gt;
&lt;li&gt;Construir los diagramas con el equipo.&lt;/li&gt;
&lt;li&gt;Refinarlos en iteraciones.&lt;/li&gt;
&lt;li&gt;Agregar títulos y descripciones.&lt;/li&gt;
&lt;li&gt;Compartir lo que aprendes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lo que me llevo de esto&lt;/h2&gt;
&lt;p&gt;Elige el nivel que le sirva a la persona con la que estás hablando y detente ahí. Un diagrama que intenta mostrarlo todo no le sirve a nadie.&lt;/p&gt;
&lt;h2&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://c4model.com/&quot;&gt;The C4 model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><author>Orlando Flores Teomitzi</author></item><item><title>Lo que aprendí sobre XSS</title><link>https://orfloresti.dev/es/posts/xss-cross-site-scripting</link><guid isPermaLink="true">https://orfloresti.dev/es/posts/xss-cross-site-scripting</guid><description>Mis notas sobre cross-site scripting, con cinco demos pequeñas que construí: cómo ocurre, los tres tipos y qué protege realmente a un sitio.</description><pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Últimamente he estado estudiando seguridad web, y XSS es el tema que más me hizo detenerme a pensar. Para entenderlo mejor construí un repo pequeño con una demo por cada idea: &lt;a href=&quot;https://github.com/orfloresti/devtalks-xss&quot;&gt;devtalks-xss&lt;/a&gt;. Estas son mis notas, escritas tal como las entendí.&lt;/p&gt;
&lt;p&gt;:::warning
Las demos son vulnerables a propósito. Ejecútalas solo en tu propia máquina, nunca las despliegues, y prueba únicamente en sistemas donde tengas permiso de hacerlo.
:::&lt;/p&gt;
&lt;h2&gt;Qué es&lt;/h2&gt;
&lt;p&gt;El navegador no puede distinguir qué partes de una página las escribió el desarrollador y cuáles vienen de un usuario. Si una app mete datos del usuario en una página sin tratarlos antes, el navegador los ejecuta como si fueran parte del sitio. Eso es XSS.&lt;/p&gt;
&lt;p&gt;Siempre sigue el mismo camino: la app recibe algo que controla un usuario, lo pone en la página y el navegador lo ejecuta.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    A[Entrada no confiable] --&amp;gt; B[Aplicación vulnerable]
    B --&amp;gt; C[Respuesta HTML o actualización del DOM]
    C --&amp;gt; D[Navegador de la víctima]
    D --&amp;gt; E[El contenido inyectado se ejecuta]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cambiar cómo se ve una página no basta para llamarlo XSS. Eso es inyección de HTML. Solo es XSS cuando realmente se ejecuta código.&lt;/p&gt;
&lt;h2&gt;Los tres tipos&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    X[XSS] --&amp;gt; R[Reflejado]
    X --&amp;gt; S[Almacenado]
    X --&amp;gt; D[Basado en DOM]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Reflejado.&lt;/strong&gt; El servidor devuelve la entrada tal cual en la respuesta. No se guarda nada, así que la víctima tiene que abrir un enlace preparado o enviar un formulario preparado. En mi demo (&lt;code&gt;01-reflected&lt;/code&gt;) es una sola página con un input: lo que escriba va directo a la página con &lt;code&gt;innerHTML&lt;/code&gt;, sin sanitizar.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant A as Atacante
    participant V as Víctima
    participant S as Sitio vulnerable
    A-&amp;gt;&amp;gt;V: Envía un enlace manipulado
    V-&amp;gt;&amp;gt;S: Abre la URL
    S--&amp;gt;&amp;gt;V: Devuelve la entrada sin codificar
    Note over V: El navegador ejecuta el script
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Almacenado.&lt;/strong&gt; La entrada se guarda, y cada visitante que la carga la ejecuta. Este es el que más miedo me da porque nadie tiene que hacer clic en nada. Mi demo (&lt;code&gt;02-stored&lt;/code&gt;) es un chat pequeño con Express y SQLite. Los mensajes se guardan tal como llegan y se muestran con &lt;code&gt;innerHTML&lt;/code&gt;, así que un solo mensaje malicioso se dispara para todos los que abran la página.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant A as Atacante
    participant S as Aplicación
    participant D as Almacenamiento
    participant V as Visitantes
    A-&amp;gt;&amp;gt;S: Envía contenido malicioso
    S-&amp;gt;&amp;gt;D: Lo guarda
    loop En cada visita a la página
        V-&amp;gt;&amp;gt;S: Piden la página
        S-&amp;gt;&amp;gt;D: Lee el contenido
        S--&amp;gt;&amp;gt;V: Devuelve HTML sin sanitizar
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Basado en DOM.&lt;/strong&gt; Todo ocurre en el navegador. El JavaScript del propio sitio toma datos de un lugar no confiable, como la URL, y los escribe en un lugar que interpreta HTML. El servidor nunca lo ve, así que sus logs ayudan poco. Mi demo (&lt;code&gt;03-dom-based&lt;/code&gt;) es un router diminuto del lado del cliente que lee el nombre de la sección desde &lt;code&gt;location.hash&lt;/code&gt; y lo escribe con &lt;code&gt;innerHTML&lt;/code&gt;. La parte de la URL después del &lt;code&gt;#&lt;/code&gt; nunca se envía al servidor, así que todo sucede en el navegador.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    A[Origen: URL, hash o postMessage] --&amp;gt; B[JavaScript del sitio]
    B --&amp;gt; C[Destino inseguro: innerHTML o document.write]
    C --&amp;gt; D[DOM modificado]
    D --&amp;gt; E[El código inyectado se ejecuta]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Los filtros no te salvan&lt;/h2&gt;
&lt;p&gt;Mi primera idea fue simplemente bloquear las palabras peligrosas. No funciona. HTML y JavaScript pueden decir lo mismo de muchas maneras, así que una lista de bloqueo siempre deja algo fuera.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart TD
    A[Filtro basado en patrones] --&amp;gt; B{Busca una sola forma}
    B --&amp;gt; C[Cambios de mayúsculas]
    B --&amp;gt; D[Otra etiqueta o evento]
    B --&amp;gt; E[Espacios y comillas]
    B --&amp;gt; F[Codificación]
    C --&amp;gt; G[Posible evasión]
    D --&amp;gt; G
    E --&amp;gt; G
    F --&amp;gt; G
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Lo que obtiene el atacante&lt;/h2&gt;
&lt;p&gt;El código se ejecuta como el sitio, así que puede hacer lo que el sitio puede hacer. Puede leer lo que muestra la página, modificarla, actuar como el usuario o robar una sesión si la cookie está expuesta. Mientras más privilegios tenga la víctima, peor es. Otras dos demos muestran cómo XSS se combina con otras fallas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XSS + CSRF&lt;/strong&gt; (&lt;code&gt;04-xss-csrf&lt;/code&gt;). Una sección de comentarios con XSS almacenado llama en silencio a un endpoint que cambia el correo de la víctima. Como el script corre dentro del sitio, el navegador envía la sesión de la víctima y el endpoint no tiene un token CSRF que lo detenga. Incluso con un token, un script que corre en la misma página podría leerlo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XSS + SSRF&lt;/strong&gt; (&lt;code&gt;05-xss-ssrf&lt;/code&gt;). Una función de &quot;vista previa de URL&quot; hace que el servidor consulte cualquier URL. Sin una lista de permitidos, puede llegar a un servicio interno que nunca debió ser público, y luego muestra la respuesta con &lt;code&gt;innerHTML&lt;/code&gt;. Dos fallas que se alimentan entre sí.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lo que realmente te protege&lt;/h2&gt;
&lt;p&gt;Ninguna cosa por sí sola basta, así que lo pienso en capas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Codifica la salida según el lugar al que va.&lt;/li&gt;
&lt;li&gt;Evita los destinos inseguros del DOM. Usa &lt;code&gt;textContent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Si tienes que permitir HTML, usa un sanitizador mantenido. No escribas el tuyo.&lt;/li&gt;
&lt;li&gt;Agrega una Content Security Policy.&lt;/li&gt;
&lt;li&gt;Marca las cookies de sesión como &lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt; y &lt;code&gt;SameSite&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Valida la entrada, pero nunca dependas solo de eso.&lt;/li&gt;
&lt;li&gt;Usa plantillas que escapen por defecto.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    A[Entrada no confiable] --&amp;gt; B[Validación]
    B --&amp;gt; C[Procesamiento]
    C --&amp;gt; D[Codificación según el contexto]
    D --&amp;gt; E[Salida segura]
    F[CSP y cookies reforzadas] -. defensa adicional .-&amp;gt; E
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para las demos encadenadas, arregla primero el XSS. Después agrega tokens CSRF y revisa &lt;code&gt;Origin&lt;/code&gt; en los endpoints que cambian estado. Para SSRF, define una lista de URLs que el servidor puede consultar, bloquea los rangos de IP privadas y nunca muestres contenido consultado con &lt;code&gt;innerHTML&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Lo que me llevo de esto&lt;/h2&gt;
&lt;p&gt;El objetivo no es reconocer todos los payloads posibles. Es asegurarte de que los datos nunca se traten como código. Codifica a la salida y agrega capas detrás.&lt;/p&gt;
&lt;p&gt;Puedes ejecutar las cinco demos desde el &lt;a href=&quot;https://github.com/orfloresti/devtalks-xss&quot;&gt;repo&lt;/a&gt;. Romper algo a propósito me enseñó más que leer sobre ello.&lt;/p&gt;
&lt;h2&gt;Referencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/orfloresti/devtalks-xss&quot;&gt;devtalks-xss: mis cinco demos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html&quot;&gt;OWASP XSS Prevention Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/DOM_based_XSS_Prevention_Cheat_Sheet.html&quot;&gt;OWASP DOM based XSS Prevention Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html&quot;&gt;OWASP XSS Filter Evasion Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><author>Orlando Flores Teomitzi</author></item></channel></rss>