<?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: SAUL JOSE ALVARADO URBANO</title>
    <description>The latest articles on DEV Community by SAUL JOSE ALVARADO URBANO (@saul_josealvaradourbano).</description>
    <link>https://dev.to/saul_josealvaradourbano</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4164159%2Fda645853-7dd5-4229-829c-8fac7e668dcf.png</url>
      <title>DEV Community: SAUL JOSE ALVARADO URBANO</title>
      <link>https://dev.to/saul_josealvaradourbano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saul_josealvaradourbano"/>
    <language>en</language>
    <item>
      <title>Respaldo y recuperación de PostgreSQL con despliegue automatizado en la nube</title>
      <dc:creator>SAUL JOSE ALVARADO URBANO</dc:creator>
      <pubDate>Sat, 10 Oct 2026 15:23:52 +0000</pubDate>
      <link>https://dev.to/saul_josealvaradourbano/respaldo-y-recuperacion-de-postgresql-con-despliegue-automatizado-en-la-nube-18pf</link>
      <guid>https://dev.to/saul_josealvaradourbano/respaldo-y-recuperacion-de-postgresql-con-despliegue-automatizado-en-la-nube-18pf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;UNIVERSIDAD PRIVADA DE TACNA&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;FACULTAD DE INGENIERÍA&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Artículo Técnico para el curso:&lt;/strong&gt; BASE DE DATOS II&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Estudiante:&lt;/strong&gt; Alvarado Urbano, Saul José (2023078332)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Estudiante:&lt;/strong&gt; Esteban Ramos, Ana Cecilia (2023078688)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Docente:&lt;/strong&gt; Ing. Patrick Josue Cuadros Quiroga&lt;br&gt;&lt;br&gt;
&lt;strong&gt;TACNA - PERÚ | 2026&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;La utilidad real de un respaldo se comprueba cuando la información puede recuperarse después de una falla. Por ello, una estrategia de protección de datos no debe limitarse a generar archivos: también debe considerar la frecuencia de las copias, su conservación, la restauración y la comprobación de que el contenido recuperado es utilizable.&lt;br&gt;
Este artículo presenta mi análisis individual del proyecto &lt;strong&gt;Database Backup Strategies&lt;/strong&gt;, desarrollado junto con &lt;strong&gt;Ana Esteban&lt;/strong&gt;. La solución evita Microsoft SQL Server y utiliza PostgreSQL, Django, GitHub y Render. Mi enfoque se centra principalmente en la recuperabilidad de la información y en la continuidad operativa del sistema.&lt;br&gt;
El proyecto combina una aplicación pública en Django, una base de datos PostgreSQL, respaldos lógicos mediante &lt;code&gt;pg_dump&lt;/code&gt;, recuperación mediante &lt;code&gt;pg_restore&lt;/code&gt;, un repositorio público de GitHub y un flujo de despliegue automático hacia Render.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Contexto y arquitectura de la solución
&lt;/h2&gt;

&lt;p&gt;La solución separa la ejecución de la aplicación, la persistencia de los datos, la generación de respaldos y el despliegue en la nube. Django atiende las solicitudes del usuario; PostgreSQL conserva la información; &lt;code&gt;pg_dump&lt;/code&gt; crea respaldos lógicos; y &lt;code&gt;pg_restore&lt;/code&gt; permite reconstruir la base de datos a partir de una copia compatible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Django:&lt;/strong&gt; framework de la aplicación web.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL:&lt;/strong&gt; motor de base de datos en producción.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pg_dump&lt;/code&gt;:&lt;/strong&gt; para crear archivos de respaldo lógico.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pg_restore&lt;/code&gt;:&lt;/strong&gt; para recuperar respaldos en formato personalizado.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; repositorio público y plataforma de colaboración.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render:&lt;/strong&gt; servicio de nube pública con Auto-Deploy.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Usuario
   │
   ▼
Aplicación Django
   │
   ▼
PostgreSQL
   │
   ├── pg_dump ────► Respaldo
   │
   └── pg_restore ──► Base de datos recuperada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Repositorio público y trabajo colaborativo
&lt;/h2&gt;

&lt;p&gt;El proyecto se mantiene en un repositorio público de GitHub que contiene el código fuente, la configuración de PostgreSQL, el script de respaldo, el archivo &lt;code&gt;render.yaml&lt;/code&gt; y la documentación. El uso de Git permite conservar el historial de cambios y evidenciar el trabajo realizado por cada integrante.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repositorio público:&lt;/strong&gt; &lt;a href="https://github.com/anaesteban1/database-backup-strategies" rel="noopener noreferrer"&gt;https://github.com/anaesteban1/database-backup-strategies&lt;/a&gt;
Como parte de mi contribución, documenté el proceso de restauración de respaldos. Este cambio quedó registrado como commit en el repositorio y posteriormente activó un nuevo despliegue automático en Render, demostrando tanto la colaboración del equipo como el funcionamiento del flujo de integración.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  3. Estrategia de respaldo con PostgreSQL
&lt;/h2&gt;
&lt;h3&gt;
  
  
  3.1 Respaldo lógico mediante pg_dump
&lt;/h3&gt;

&lt;p&gt;PostgreSQL incorpora &lt;code&gt;pg_dump&lt;/code&gt; para exportar de forma lógica la información de una base de datos. En el proyecto se emplea el formato personalizado porque puede ser restaurado posteriormente con &lt;code&gt;pg_restore&lt;/code&gt; y facilita la administración del archivo de recuperación.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;pg_dump&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--dbname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;custom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;postgres_backup.dump&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para conservar diferentes puntos de recuperación se utiliza una marca de fecha y hora en el nombre de cada archivo, evitando que una ejecución posterior sobrescriba el respaldo anterior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-Date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yyyy-MM-dd_HH-mm-ss"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$backupFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postgres_backup_&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="s2"&gt;.dump"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 Automatización del proceso
&lt;/h3&gt;

&lt;p&gt;El repositorio contiene el script &lt;code&gt;scripts/backup_postgres.ps1&lt;/code&gt;. Este script valida la variable &lt;code&gt;DATABASE_URL&lt;/code&gt;, ejecuta &lt;code&gt;pg_dump&lt;/code&gt;, genera el archivo correspondiente y comprueba el resultado del comando. De esta manera, el mismo procedimiento puede repetirse sin escribir manualmente todos los parámetros en cada ocasión.&lt;br&gt;
En un entorno real, este script puede programarse mediante el Programador de tareas de Windows, un flujo de CI/CD o un servicio de automatización. El propósito es disminuir la dependencia de una ejecución manual y mantener una frecuencia de respaldo definida.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.3 Retención y puntos de recuperación
&lt;/h3&gt;

&lt;p&gt;Mantener únicamente la copia más reciente puede ser insuficiente, porque un error o una modificación no deseada también podría estar presente en ese archivo. Una política de retención conserva varios respaldos para poder elegir un punto de recuperación anterior que se considere válido.&lt;br&gt;
Una política sencilla podría conservar siete copias diarias, cuatro semanales y doce mensuales. La cantidad exacta dependerá del objetivo de recuperación, del espacio disponible y de la importancia de la información. Los nombres con fecha y hora utilizados en el proyecto permiten implementar posteriormente este tipo de rotación.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Restauración y validación de la recuperación
&lt;/h2&gt;

&lt;p&gt;Una estrategia de respaldo está incompleta si no existe un procedimiento de restauración. Los archivos creados por &lt;code&gt;pg_dump&lt;/code&gt; en formato personalizado pueden recuperarse mediante &lt;code&gt;pg_restore&lt;/code&gt; sobre una base de datos PostgreSQL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;pg_restore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--dbname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;postgres_backup.dump&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La restauración debe probarse de forma periódica en un entorno controlado. Esta prueba permite comprobar que el archivo se puede leer, que los objetos de la base de datos se reconstruyen y que la información recuperada es correcta. Por ello, validar la recuperación es tan importante como generar el respaldo.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Despliegue automatizado con GitHub y Render
&lt;/h2&gt;

&lt;p&gt;El despliegue de la aplicación funciona de manera independiente del respaldo de la base de datos. El repositorio público se encuentra conectado a Render y la rama &lt;code&gt;main&lt;/code&gt; utiliza Auto-Deploy. Cada vez que se publica un nuevo commit, Render detecta el cambio, reconstruye la aplicación y publica automáticamente una nueva versión.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Documenta proceso de restauracion de respaldos"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mi commit de documentación del proceso de restauración produjo un nuevo despliegue automático. Esta evidencia confirma que los cambios realizados por distintos colaboradores pasan por el mismo flujo de entrega sin necesidad de ejecutar un despliegue manual desde Render.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Colaborador
   │
   ▼ (git push origin main)
GitHub
   │
   ▼
Auto-Deploy de Render
   │
   ▼
Aplicación publicada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Publicación en nube pública
&lt;/h2&gt;

&lt;p&gt;La aplicación Django se encuentra publicada en Render y utiliza PostgreSQL como base de datos. El sitio permite registrar información de prueba, lo que facilita demostrar el tipo de datos que deben protegerse mediante una estrategia de respaldo y recuperación.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aplicación pública:&lt;/strong&gt; &lt;a href="https://database-backup-strategies.onrender.com" rel="noopener noreferrer"&gt;https://database-backup-strategies.onrender.com&lt;/a&gt;
La interfaz indica que la aplicación está activa, que el despliegue automático desde GitHub se encuentra habilitado y que el motor utilizado es PostgreSQL. De esta forma se cumple el requisito de publicar la aplicación en un proveedor público sin utilizar Microsoft SQL Server.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Buenas prácticas operativas
&lt;/h2&gt;

&lt;p&gt;En un entorno de producción, los respaldos importantes deberían almacenarse también fuera del servidor principal. Mantener la base de datos y todas sus copias en una misma infraestructura crea un único punto de falla. También es recomendable cifrar los respaldos cuando contengan información sensible y supervisar las ejecuciones programadas.&lt;br&gt;
Las credenciales de producción tampoco deben almacenarse en el repositorio público. El proyecto utiliza variables de entorno como &lt;code&gt;DATABASE_URL&lt;/code&gt;, &lt;code&gt;SECRET_KEY&lt;/code&gt; y &lt;code&gt;DEBUG&lt;/code&gt; para separar los datos sensibles del código fuente y evitar su exposición en GitHub.&lt;br&gt;
Además, una estrategia madura debe establecer objetivos de recuperación y realizar pruebas periódicas de restauración. No basta con confirmar que un archivo existe; es necesario comprobar que puede utilizarse para recuperar la información dentro del tiempo esperado.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Demostración en video
&lt;/h2&gt;

&lt;p&gt;Se publicará un video de acceso público de no más de cinco minutos. En él se mostrará el repositorio, la estrategia de respaldo y restauración de PostgreSQL, el commit que activa el Auto-Deploy, el historial de despliegues de Render y la aplicación funcionando públicamente.&lt;/p&gt;




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

&lt;p&gt;El proyecto demuestra que una estrategia efectiva de respaldo debe enfocarse en la posibilidad real de recuperar la información. PostgreSQL proporciona &lt;code&gt;pg_dump&lt;/code&gt; para generar respaldos lógicos y &lt;code&gt;pg_restore&lt;/code&gt; para restaurarlos, mientras que la identificación por fecha y hora facilita mantener distintos puntos de recuperación.&lt;br&gt;
También se comprobó que el respaldo de datos y la entrega del software son procesos diferentes. GitHub y Render automatizan la publicación de los cambios de la aplicación, mientras el script de respaldo y el procedimiento de restauración protegen la información almacenada en PostgreSQL.&lt;br&gt;
La combinación de repositorio público, respaldo y restauración, despliegue automatizado y alojamiento en la nube permite cumplir los requisitos del trabajo y proporciona una base que puede ampliarse con políticas de retención, almacenamiento externo y pruebas periódicas de recuperación.&lt;/p&gt;




&lt;h2&gt;
  
  
  Enlaces del proyecto
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repositorio GitHub:&lt;/strong&gt; &lt;a href="https://github.com/anaesteban1/database-backup-strategies" rel="noopener noreferrer"&gt;https://github.com/anaesteban1/database-backup-strategies&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aplicación pública en la nube:&lt;/strong&gt; &lt;a href="https://database-backup-strategies.onrender.com" rel="noopener noreferrer"&gt;https://database-backup-strategies.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demostración en video:&lt;/strong&gt; &lt;em&gt;(Pendiente - agregar la URL pública antes de publicar el artículo)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Django Software Foundation. (s. f.). &lt;em&gt;Documentación de Django&lt;/em&gt;. &lt;a href="https://docs.djangoproject.com/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PostgreSQL Global Development Group. (s. f.). &lt;em&gt;pg_dump. Documentación de PostgreSQL&lt;/em&gt;. &lt;a href="https://www.postgresql.org/docs/current/app-pgdump.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/current/app-pgdump.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PostgreSQL Global Development Group. (s. f.). &lt;em&gt;pg_restore. Documentación de PostgreSQL&lt;/em&gt;. &lt;a href="https://www.postgresql.org/docs/current/app-pgrestore.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/current/app-pgrestore.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PostgreSQL Global Development Group. (s. f.). &lt;em&gt;Copias de seguridad y restauración. Documentación de PostgreSQL&lt;/em&gt;. &lt;a href="https://www.postgresql.org/docs/current/backup.html" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/current/backup.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Render. (s. f.). &lt;em&gt;Desplegar una aplicación Django&lt;/em&gt;. &lt;a href="https://render.com/docs/deploy-django" rel="noopener noreferrer"&gt;https://render.com/docs/deploy-django&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>automation</category>
      <category>cloud</category>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Implementación de DevSecOps con Bearer SAST y GitHub Actions: De la Detección a la Remediación</title>
      <dc:creator>SAUL JOSE ALVARADO URBANO</dc:creator>
      <pubDate>Mon, 05 Oct 2026 15:25:50 +0000</pubDate>
      <link>https://dev.to/saul_josealvaradourbano/implementacion-de-devsecops-con-bearer-sast-y-github-actions-de-la-deteccion-a-la-remediacion-16k</link>
      <guid>https://dev.to/saul_josealvaradourbano/implementacion-de-devsecops-con-bearer-sast-y-github-actions-de-la-deteccion-a-la-remediacion-16k</guid>
      <description>&lt;p&gt;&lt;strong&gt;Autor:&lt;/strong&gt; Saúl Jose Alvarado Urbano &lt;br&gt;
&lt;strong&gt;Autor:&lt;/strong&gt; Ana Cecilia Esteban Ramos&lt;br&gt;
&lt;strong&gt;Repositorio:&lt;/strong&gt; &lt;a href="https://github.com/saulalvarado1/Bearer_Articulo" rel="noopener noreferrer"&gt;github.com/saulalvarado1/Bearer_Articulo&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;API en Vivo:&lt;/strong&gt; &lt;a href="https://bearer-articulo.onrender.com" rel="noopener noreferrer"&gt;bearer-articulo.onrender.com&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Resumen (Abstract)
&lt;/h2&gt;

&lt;p&gt;En el desarrollo de software moderno, la seguridad ya no puede ser una fase tardía o una auditoría aislada antes del lanzamiento a producción. El paradigma &lt;strong&gt;Shift-Left&lt;/strong&gt; propone integrar la seguridad desde las primeras etapas del ciclo de vida del desarrollo de software (SSDLC). &lt;/p&gt;

&lt;p&gt;En este artículo técnico presentamos la implementación práctica de un flujo &lt;strong&gt;DevSecOps&lt;/strong&gt; completo para una API REST construida con &lt;strong&gt;Node.js&lt;/strong&gt; y &lt;strong&gt;Express&lt;/strong&gt;. Configuramos un pipeline de Integración Continua (CI) en &lt;strong&gt;GitHub Actions&lt;/strong&gt; utilizando &lt;strong&gt;Bearer CLI&lt;/strong&gt;, una herramienta avanzada de Análisis Estático de Seguridad de Aplicaciones (SAST) especializada en la detección de fallas OWASP Top 10 y riesgos de privacidad/fuga de datos (PII). Demostramos cómo el pipeline bloquea automáticamente código vulnerable ante una fuga de credenciales en logs (&lt;strong&gt;CWE-134 / Insecure Logging&lt;/strong&gt;), y cómo se aplica la remediación para alcanzar un despliegue seguro.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Arquitectura y Stack Tecnológico
&lt;/h2&gt;

&lt;p&gt;El flujo implementado conecta las herramientas de desarrollo, análisis estático y automatización:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ Desarrollador ] 
       │  (git push)
       ▼
[ GitHub Repository ] 
       │  (Trigger Workflow)
       ▼
[ GitHub Actions Runner ]
       │
       ├─► 1. Checkout de Código
       ├─► 2. Escaneo SAST con Bearer CLI
       │      ├── ¿Hay vulnerabilidades HIGH / CRITICAL?
       │      ├── [SÍ] ──► ❌ PIPELINE FALLA (Bloqueo de despliegue)
       │      └── [NO] ──► ✅ PIPELINE EXITOSO
       ▼
[ Despliegue en la Nube (Render / Cloud SaaS) ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Componentes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Node.js &amp;amp; Express (API modular y ligera).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Herramienta SAST:&lt;/strong&gt; &lt;a href="https://www.bearer.com/" rel="noopener noreferrer"&gt;Bearer CLI&lt;/a&gt; (Motor de análisis de flujo de datos sensibles y patrones de vulnerabilidad).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orquestador CI/CD:&lt;/strong&gt; GitHub Actions (Automatización de pruebas y compuertas de calidad).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entorno Cloud:&lt;/strong&gt; Render (Plataforma como Servicio - PaaS para despliegue continuo).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2.Configuración del Pipeline de Seguridad (CI)
&lt;/h2&gt;

&lt;p&gt;Para automatizar la verificación de seguridad en cada cambio de código, definimos el flujo en el archivo &lt;code&gt;.github/workflows/bearer-scan.yml&lt;/code&gt;:&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="s"&gt;yaml&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;Bearer SAST Scan &amp;amp; Security Pipeline&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&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;main"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&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;main"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;security_scan&lt;/span&gt;&lt;span class="pi"&gt;:&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;Bearer SAST Security Analysis&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&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;Checkout Repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&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;Run Bearer CLI Scanner&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bearer/bearer-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;# Falla el pipeline si encuentra vulnerabilidades de severidad alta o crítica&lt;/span&gt;
          &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high,critical"&lt;/span&gt;
          &lt;span class="c1"&gt;# Escanea todo el repositorio&lt;/span&gt;
          &lt;span class="na"&gt;diff&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ¿Por qué Bearer?
&lt;/h3&gt;

&lt;p&gt;A diferencia de los linters tradicionales o analizadores puramente sintácticos, Bearer rastrea el &lt;strong&gt;flujo de datos (dataflow)&lt;/strong&gt; desde las fuentes de entrada (&lt;em&gt;sources&lt;/em&gt;) hasta los puntos de salida (&lt;em&gt;sinks&lt;/em&gt;). Esto le permite identificar con precisión si información personal identificable (PII), secretos o credenciales están siendo expuestos o mal manejados.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Caso Práctico: Introducción Intencional de una Vulnerabilidad
&lt;/h2&gt;

&lt;p&gt;En el endpoint de autenticación (&lt;code&gt;/api/login&lt;/code&gt;), se simuló un error común pero crítico en el desarrollo de software: el registro no sanitizado de credenciales de usuario para fines de depuración (&lt;em&gt;debugging&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Código vulnerable original (&lt;code&gt;server.js&lt;/code&gt;):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email y contraseña requeridos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ALERTA SAST: Imprimir contraseñas y PII en logs estándar (CWE-134 / CWE-532)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[AUTH-LOG] Intento de login para usuario: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; con credencial: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Autenticación exitosa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jwt-simulated-token-bearer-demo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Credenciales inválidas&lt;/span&gt;&lt;span class="dl"&gt;'&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;
  
  
  4. Detección y Bloqueo en GitHub Actions (Compuerta de Calidad)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy8aa6ykifqowv9gogtbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy8aa6ykifqowv9gogtbg.png" alt="Detección de vulnerabilidad Bearer SAST" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al realizar el &lt;code&gt;push&lt;/code&gt; hacia el repositorio remoto, el runner de GitHub Actions ejecutó el escaneo de Bearer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resultado del Análisis:
&lt;/h3&gt;

&lt;p&gt;Bearer detectó la vulnerabilidad de severidad &lt;strong&gt;HIGH&lt;/strong&gt; y finalizó el proceso con código de salida &lt;code&gt;1&lt;/code&gt;, deteniendo inmediatamente la integración:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HIGH: Unsanitized user input in format string [CWE-134]
https://docs.bearer.com/reference/rules/javascript_lang_format_string_using_user_input

File: server.js:54
54  console.log(`[AUTH-LOG] Intento de login para usuario: ${email} con credencial: ${password}`);

87 checks, 1 findings
CRITICAL: 0
HIGH: 1 (CWE-134)
Error: Process completed with exit code 1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Impacto de Seguridad:&lt;/strong&gt; Registrar credenciales en texto claro (&lt;code&gt;password&lt;/code&gt;) y datos no sanitizados en los flujos de salida del servidor viola normas de cumplimiento como GDPR, HIPAA y PCI-DSS, además de exponer los datos en sistemas centralizados de agregación de logs (CloudWatch, Datadog, ELK).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Fase de Remediación (Fix)
&lt;/h2&gt;

&lt;p&gt;Para resolver el problema sin comprometer la trazabilidad de eventos del sistema, aplicamos el principio de &lt;strong&gt;Mínimo Privilegio en Logs&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Eliminar completamente&lt;/strong&gt; el registro de contraseñas u otros datos sensibles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evitar concatenaciones de cadenas no sanitizadas&lt;/strong&gt; con datos directos provenientes del cliente.&lt;/li&gt;
&lt;li&gt;Registrar únicamente el evento de autenticación genérico.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Código corregido (&lt;code&gt;server.js&lt;/code&gt;):
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email y contraseña requeridos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// PRÁCTICA SEGURA: Registro de eventos sin exponer datos sensibles ni formatos dinámicos&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[AUTH-LOG] Intento de login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Autenticación exitosa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jwt-simulated-token-bearer-demo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Credenciales inválidas&lt;/span&gt;&lt;span class="dl"&gt;'&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;
  
  
  6. Verificación de Seguridad y Aprobación del Pipeline
&lt;/h2&gt;

&lt;p&gt;El equipo subió la remediación mediante el commit:&lt;br&gt;
&lt;code&gt;fix: remove sensitive login data from logs&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resultado del nuevo escaneo:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Checks ejecutados:&lt;/strong&gt; 87&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hallazgos Críticos:&lt;/strong&gt; 0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hallazgos Altos:&lt;/strong&gt; 0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estado del Pipeline:&lt;/strong&gt; &lt;strong&gt;SUCCESS (Verde ✅)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrws3hwcwuvm8r24x6s7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxrws3hwcwuvm8r24x6s7.png" alt="Pipeline exitoso en GitHub Actions" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Al no encontrarse infracciones de severidad alta o crítica, el pipeline aprueba los artefactos y autoriza el paso al despliegue continuo en la nube pública.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Lecciones Aprendidas y Buenas Prácticas DevSecOps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;La seguridad como código (Security as Code):&lt;/strong&gt; Definir políticas de escaneo en archivos versionables (&lt;code&gt;.yml&lt;/code&gt;) garantiza consistencia y auditoría en cada contribución.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retroalimentación temprana:&lt;/strong&gt; Detectar vulnerabilidades en el momento del &lt;code&gt;pull request&lt;/code&gt; reduce drásticamente el costo temporal y financiero de mitigar incidentes en producción.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Equilibrio entre seguridad y velocidad:&lt;/strong&gt; Configurar filtros de severidad (&lt;code&gt;high,critical&lt;/code&gt;) previene falsos positivos que puedan frenar innecesariamente el ritmo de entrega del equipo de ingeniería.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protección de PII:&lt;/strong&gt; Las herramientas modernas de SAST deben comprender el contexto de privacidad y no limitarse únicamente a inyecciones SQL o XSS tradicionales.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Recursos y Enlaces
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Código fuente completo:&lt;/strong&gt; &lt;a href="https://github.com/saulalvarado1/Bearer_Articulo" rel="noopener noreferrer"&gt;GitHub - saulalvarado1/Bearer_Articulo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aplicación en Vivo (Producción):&lt;/strong&gt; &lt;a href="https://bearer-articulo.onrender.com" rel="noopener noreferrer"&gt;https://bearer-articulo.onrender.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentación oficial de Bearer:&lt;/strong&gt; &lt;a href="https://docs.bearer.com/" rel="noopener noreferrer"&gt;https://docs.bearer.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CWE-134 (Use of Externally-Controlled Format String):&lt;/strong&gt; &lt;a href="https://cwe.mitre.org/data/definitions/134.html" rel="noopener noreferrer"&gt;https://cwe.mitre.org/data/definitions/134.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CWE-532 (Insertion of Sensitive Information into Log File):&lt;/strong&gt; &lt;a href="https://cwe.mitre.org/data/definitions/532.html" rel="noopener noreferrer"&gt;https://cwe.mitre.org/data/definitions/532.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cicd</category>
      <category>devops</category>
      <category>github</category>
      <category>security</category>
    </item>
  </channel>
</rss>
