---
title: "Proteger Astro de ataques a la cadena de suministro: Parte 2 - Medidas de seguridad a largo plazo"
description: "Implemente medidas de seguridad integrales para su proyecto Astro. Aprenda a asegurar su pipeline de CI/CD, automatizar el escaneo de dependencias y prevenir futuros ataques a la cadena de suministro de npm."
source: "https://www.launchfa.st/es/blog/protect-astro-supply-chain-attacks-part-2"
author: "Rishi Raj Jain"
created_at: 2025-12-01T12:00:00.000Z
---

> **Site index for agents**
> Fetch https://www.launchfa.st/llms.txt to discover every page on this site.
> Every page is also available as Markdown by appending `.md` to its URL.

<img width="1600" height="900" alt="Proteger Astro de ataques a la cadena de suministro Parte 2" decoding="async" loading="eager" class="mt-4 border rounded-sm bg-cover bg-center bg-no-repeat transform will-change-auto" src="https://ik.imagekit.io/vjeqenuhn/launchfast-website/protect-astro-supply-chain-attacks-2.png" />

> **Esta es la Parte 2 de una serie de 2 artículos** sobre cómo proteger sitios Astro de ataques a la cadena de suministro de npm. La [Parte 1](/blog/protect-astro-supply-chain-attacks-part-1) cubrió la comprensión de la amenaza y la respuesta inmediata. Este artículo se centra en medidas de seguridad a largo plazo, monitorización y buenas prácticas.

En la [Parte 1](/blog/protect-astro-supply-chain-attacks-part-1), cubrimos la respuesta inmediata al ataque Shai-Hulud 2.0. Ahora es el momento de implementar medidas de seguridad integrales que protejan su proyecto Astro de futuros ataques a la cadena de suministro. No son parches temporales: son prácticas esenciales que deberían formar parte de su flujo de trabajo de desarrollo.

## Requisitos previos

Necesitará lo siguiente:

- Haber completado la [Parte 1](/blog/protect-astro-supply-chain-attacks-part-1) de esta serie

## 1. Implementar bloqueo y verificación de paquetes

La primera línea de defensa contra ataques a la cadena de suministro es asegurarse de que siempre instala exactamente las versiones de los paquetes que ha probado y verificado.

### 1.1 Usar números de versión exactos

Nunca use rangos de versión en su `package.json` para dependencias de producción:

```json
// ❌ Malo: permite actualizaciones automáticas
{
  "dependencies": {
    "astro": "^4.16.1",    // Puede instalar 4.16.x o 4.x.x
    "sharp": "~0.33.1"     // Puede instalar 0.33.x
  }
}

// ✅ Bueno: solo versiones exactas
{
  "dependencies": {
    "astro": "4.16.1",
    "sharp": "0.33.1"
  }
}
```

### 1.2 Configurar npm/pnpm para seguridad

Cree un archivo `.npmrc` en la raíz de su proyecto con configuraciones de seguridad estrictas:

```bash
# File: .npmrc

# Always use exact versions when saving packages
save-exact=true

# Ensure package-lock.json is always created and used
package-lock=true

# Run audit on every install
audit=true

# Set minimum audit level (low, moderate, high, critical)
audit-level=moderate

# Fail install if vulnerabilities are found
audit-report=true
```

Para usuarios de pnpm (recomendado), configure funciones de seguridad adicionales:

```bash
# File: .npmrc (for pnpm)

# Require exact versions
save-exact=true

# Strict peer dependencies
strict-peer-dependencies=true

# Verify package integrity using checksums
package-import-method=copy

# Run security audit on install
audit=true

# Only allow packages from verified registries
registry=https://registry.npmjs.org/

# Verify SSL certificates
strict-ssl=true
```

### 1.3 Confirmar siempre los archivos de bloqueo

Su archivo de bloqueo (`package-lock.json` o `pnpm-lock.yaml`) es fundamental para builds reproducibles:

```bash
# Ensure lock file is tracked in git
git add pnpm-lock.yaml
git commit -m "chore: commit lock file for security"
```

Actualice su `.gitignore` para asegurarse de que los archivos de bloqueo nunca se ignoren:

```bash
# File: .gitignore

# Make sure these are NOT in .gitignore:
# pnpm-lock.yaml
# package-lock.json
# yarn.lock

# But DO ignore
node_modules/
```

## 2. Usar herramientas de escaneo de dependencias

Las herramientas de escaneo automatizado pueden detectar vulnerabilidades antes de que lleguen a producción. Configuremos un flujo de trabajo de escaneo integral.

### 2.1 Escaneo de seguridad con Snyk y GitHub Actions

Snyk es una [plataforma de seguridad para desarrolladores](https://snyk.io/) líder, especializada en escanear sus dependencias en busca de vulnerabilidades.

Cree un flujo de trabajo de GitHub Actions para el escaneo con Snyk:

```yaml
# File: .github/workflows/snyk-security-scan.yml

name: Snyk Security Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]
  schedule:
    - cron: '0 2 * * *'
  workflow_dispatch:

jobs:
  snyk-scan:
    runs-on: ubuntu-latest

    permissions:
      contents: read

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'

      - name: Install pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Install dependencies (safely)
        run: pnpm install --frozen-lockfile --ignore-scripts

      - name: Run npm audit
        run: pnpm audit --audit-level=moderate
        continue-on-error: true
        id: npm-audit

      - name: Run Snyk security scan
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high --all-projects
        continue-on-error: true
        id: snyk-scan

      - name: Generate Security Report
        if: always()
        run: |
          echo "# Snyk Security Scan Report" > security-report.md
          echo "Generated: $(date)" >> security-report.md
          echo "" >> security-report.md
          echo "## Scan Results" >> security-report.md
          echo "- npm audit: ${{ steps.npm-audit.outcome }}" >> security-report.md
          echo "- Snyk scan: ${{ steps.snyk-scan.outcome }}" >> security-report.md

      - name: Upload Security Report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: snyk-security-report-${{ github.run_number }}
          path: security-report.md
          retention-days: 90
```

Snyk ofrece monitorización continua de sus dependencias, rastreando nuevas vulnerabilidades incluso después de que su código se haya fusionado. Proporciona sugerencias de corrección que identifican exactamente qué actualizaciones resolverán problemas conocidos. Con una sólida integración en IDE y CI/CD, Snyk le ayuda a detectar problemas de seguridad antes de que sus dependencias lleguen a producción. Además, Snyk ofrece un generoso plan gratuito para repositorios públicos y de código abierto, lo que lo hace accesible para la comunidad de desarrolladores en general.

### 2.2 Escáner de vulnerabilidades Trivy con GitHub Actions

Trivy es un [escáner de vulnerabilidades de código abierto](https://github.com/aquasecurity/trivy) que ofrece un escaneo más amplio, incluyendo seguridad de infraestructura y contenedores.

Configure Trivy con GitHub Actions:

```yaml
# File: .github/workflows/trivy-scan.yml

name: Trivy Scan

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]
  schedule:
    - cron: '0 4 * * *'
  workflow_dispatch:

jobs:
  trivy-scan:
    runs-on: ubuntu-latest

    permissions:
      contents: read
      security-events: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Install dependencies (safely)
        run: pnpm install --frozen-lockfile --ignore-scripts

      - name: Trivy vulnerability scan (code & dependencies)
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          scan-ref: '.'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'HIGH,CRITICAL'

      - name: Upload Trivy results to GitHub Security
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'
```

Trivy es un escáner de seguridad de código abierto que ofrece una cobertura amplia de vulnerabilidades en todo su proyecto: no solo en `node_modules`, sino también en contenedores, paquetes del sistema operativo, archivos de configuración e infraestructura como código. Sus resultados pueden exportarse en formato SARIF, lo que permite una integración fluida con las funciones de seguridad de GitHub. Trivy es gratuito, sencillo de automatizar y está bien adaptado tanto para flujos de trabajo locales como de CI/CD.

### 2.3 Configurar escaneo de seguridad local

No espere a que CI/CD detecte los problemas. Escanee localmente antes de hacer push:

```bash
# Install Snyk CLI globally
npm install -g snyk

# Authenticate with Snyk
snyk auth

# Scan your project
snyk test

# Monitor your project (sends snapshot to Snyk for continuous monitoring)
snyk monitor
```

Añada un hook de git pre-push:

```bash
# Install husky if you haven't already
pnpm add -D husky

# Initialize husky
npx husky init

# Create pre-push hook
cat > .husky/pre-push << 'EOF'
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo "🔍 Running security scan before push..."
pnpm audit --audit-level=moderate
EOF

chmod +x .husky/pre-push
```

## 3. Asegurar su pipeline de CI/CD

El ataque Shai-Hulud 2.0 apuntó específicamente a entornos de CI/CD donde los secretos están fácilmente disponibles. Así es como puede reforzar su pipeline.

### 3.1 Usar permisos mínimos

Configure sus GitHub Actions con el principio de mínimo privilegio:

```yaml
# File: .github/workflows/deploy.yml

name: Deploy to Production

on:
  push:
    branches: [main]

# Set minimal default permissions
permissions:
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    # Override only for specific needs
    permissions:
      contents: read
      deployments: write
      id-token: write  # For OIDC authentication
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'
          
      - name: Install pnpm
        uses: pnpm/action-setup@v2
        with:
          version: 8
          
      # Critical: Disable install scripts in CI
      - name: Install dependencies
        run: pnpm install --frozen-lockfile --ignore-scripts
        
      - name: Build
        env:
          # Use environment-specific secrets
          DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
          API_KEY: ${{ secrets.PROD_API_KEY }}
        run: pnpm run build
        
      - name: Deploy
        run: pnpm run deploy
```

### 3.2 Desactivar scripts de instalación

Los scripts de instalación son el vector de ataque principal. Desactívelos siempre en CI/CD:

```yaml
# Always use --ignore-scripts in CI
- name: Install dependencies
  run: pnpm install --frozen-lockfile --ignore-scripts
```

Para paquetes que legítimamente necesitan scripts de instalación (como `sharp` o `esbuild`), reconstrúyalos explícitamente:

```typescript
// File: scripts/secure-install.ts

import { execSync } from 'child_process'

console.log('🔒 Running secure installation...\n')

try {
  // Install without running any scripts
  console.log('📦 Installing packages without scripts...')
  execSync('pnpm install --frozen-lockfile --ignore-scripts', {
    stdio: 'inherit',
  })
  
  console.log('\n✅ Dependencies installed safely')
  
  // Explicitly rebuild trusted packages that need native bindings
  const TRUSTED_PACKAGES = [
    'sharp',      // Image processing
    'esbuild',    // Bundler
    '@parcel/watcher',  // File watcher
    // Add other trusted packages here
  ]
  
  console.log('\n📦 Rebuilding trusted native packages...')
  for (const pkg of TRUSTED_PACKAGES) {
    try {
      console.log(`  - Rebuilding ${pkg}...`)
      execSync(`pnpm rebuild ${pkg}`, { stdio: 'inherit' })
      console.log(`  ✅ ${pkg} rebuilt successfully`)
    } catch (error) {
      console.error(`  ❌ Failed to rebuild ${pkg}`)
      // Don't fail the whole process - package might not be installed
    }
  }
  
  console.log('\n✅ Secure installation complete!')
} catch (error) {
  console.error('\n❌ Installation failed:', error.message)
  process.exit(1)
}
```

Actualice su `package.json`:

```json
{
  "scripts": {
    "install:safe": "tsx scripts/secure-install.ts",
    "build": "astro build",
    "dev": "astro dev"
  }
}
```

### 3.3 Usar aislamiento de entornos

Use secretos y credenciales diferentes para cada entorno (dev, staging, producción) para contener posibles brechas y evitar que las filtraciones se propaguen entre entornos.

```yaml
# File: .github/workflows/deploy-staging.yml

name: Deploy to Staging

on:
  push:
    branches: [develop]

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment: staging  # GitHub environment
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Build and Deploy
        env:
          # Staging-specific secrets
          DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
          API_KEY: ${{ secrets.STAGING_API_KEY }}
        run: |
          pnpm install --frozen-lockfile --ignore-scripts
          pnpm run build
          pnpm run deploy:staging
```
---
```yaml
# File: .github/workflows/deploy-production.yml

name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment: production  # Different environment
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Build and Deploy
        env:
          # Production-specific secrets
          DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}
          API_KEY: ${{ secrets.PROD_API_KEY }}
        run: |
          pnpm install --frozen-lockfile --ignore-scripts
          pnpm run build
          pnpm run deploy:production
```

### 3.4 Usar OIDC en lugar de tokens de larga duración

Para despliegues en la nube, use OpenID Connect (OIDC) en lugar de almacenar credenciales de larga duración:

```yaml
# File: .github/workflows/deploy-aws.yml

name: Deploy to AWS

on:
  push:
    branches: [main]

permissions:
  id-token: write  # Required for OIDC
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      # Use OIDC to get temporary credentials
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
          aws-region: us-east-1
          
      # Now you have temporary AWS credentials
      - name: Deploy to S3
        run: |
          pnpm run build
          aws s3 sync dist/ s3://my-bucket/
```

Al adoptar OIDC, elimina la necesidad de almacenar credenciales de nube de larga duración en GitHub, reduciendo significativamente el riesgo si su entorno de CI alguna vez se ve comprometido. En su lugar, GitHub Actions puede solicitar credenciales temporales que expiran automáticamente para cada ejecución del flujo de trabajo. Cada evento de autenticación se registra y es auditable en AWS CloudTrail, garantizando trazabilidad completa y transparencia de seguridad.

## 4. Configurar la automatización de npm audit

Convierta las auditorías de seguridad en una parte habitual de su flujo de trabajo de desarrollo.

### 4.1 Configurar hooks pre-commit

Configurar hooks pre-commit añade un punto de control automatizado en su flujo de trabajo para evitar que confirme código inseguro. Cada vez que intente hacer un commit, Husky activará la auditoría de seguridad (usando `pnpm audit --audit-level=moderate`). Si se detectan vulnerabilidades por encima del umbral, el commit se bloquea hasta que se resuelvan los problemas o se omitan intencionalmente. Esto ayuda a garantizar que solo se confirme código seguro en el repositorio, manteniendo la integridad de su proyecto desde el principio.

```bash
# File: .husky/pre-commit

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo "🔍 Running pre-commit security checks...\n"

# Run audit
echo "📦 Checking for vulnerabilities..."
pnpm audit --audit-level=moderate

if [ $? -ne 0 ]; then
  echo "\n❌ Security vulnerabilities found!"
  echo "Run 'pnpm audit fix' to resolve issues."
  echo "Or use --no-verify to skip (not recommended)."
  exit 1
fi

echo "✅ Security checks passed!\n"
```

Además, actualice los scripts en `package.json` para ejecutar las auditorías a través del gestor de paquetes correspondiente.

```json
{
  "scripts": {
    "audit": "pnpm audit --audit-level=moderate",
    "audit:fix": "pnpm audit fix",
    "audit:production": "pnpm audit --production --audit-level=high",
    "precommit": "pnpm run audit",
    "prepush": "pnpm run audit:production"
  }
}
```

### 4.2 Crear informes de seguridad automatizados

Esta sección muestra cómo crear informes de seguridad automatizados para su proyecto.

```typescript
// File: scripts/generate-security-report.ts

import { execSync } from 'child_process'
import { writeFileSync } from 'fs'

const generateSecurityReport = () => {
  console.log('📊 Generating security report...\n')
  
  const report = {
    timestamp: new Date().toISOString(),
    auditResults: null as any,
    outdatedPackages: null as any,
    recommendations: [] as string[],
  }
  
  try {
    // Run npm audit
    const auditOutput = execSync('pnpm audit --json', {
      encoding: 'utf-8',
    })
    report.auditResults = JSON.parse(auditOutput)
  } catch (error: any) {
    // Audit exits with non-zero if vulnerabilities found
    if (error.stdout) {
      report.auditResults = JSON.parse(error.stdout)
    }
  }
  
  // Generate recommendations
  const vulnerabilities = report.auditResults?.metadata?.vulnerabilities
  if (vulnerabilities) {
    const { critical, high, moderate } = vulnerabilities
    
    if (critical > 0) {
      report.recommendations.push(
        `🚨 CRITICAL: ${critical} critical vulnerabilities require immediate attention`
      )
    }
    if (high > 0) {
      report.recommendations.push(
        `⚠️  HIGH: ${high} high-severity vulnerabilities should be addressed soon`
      )
    }
    if (moderate > 0) {
      report.recommendations.push(
        `ℹ️  MODERATE: ${moderate} moderate vulnerabilities should be reviewed`
      )
    }
  }
  
  // Write report
  const reportPath = `security-report-${Date.now()}.json`
  writeFileSync(reportPath, JSON.stringify(report, null, 2))
  
  console.log(`✅ Security report generated: ${reportPath}\n`)
  
  // Print summary
  console.log('📊 Summary:')
  report.recommendations.forEach(rec => console.log(rec))
  
  return report
}

generateSecurityReport()
```

- Ejecute un comando `pnpm audit` para escanear sus dependencias en busca de vulnerabilidades y capturar los resultados en JSON.
- Recopile la marca de tiempo del descubrimiento, los resultados de la auditoría y las recomendaciones de remediación.
- Resuma las vulnerabilidades por gravedad (critical, high, moderate) y proporcione recomendaciones accionables si hay problemas.
- Escriba el informe de seguridad resultante en un archivo que pueda revisar o compartir con su equipo.

Al integrar este script en su flujo de trabajo, garantiza una visibilidad clara y regular del estado de seguridad de su proyecto. Esto facilita el seguimiento y la corrección efectiva de vulnerabilidades, y respalda una política de monitorización continua de la seguridad.

## Conclusión

Los pasos que hemos cubierto aquí establecen una defensa fiable: use siempre versiones exactas y archivos de bloqueo, automatice las comprobaciones de seguridad en su pipeline de CI/CD, desactive los scripts de instalación durante los builds de producción, use OIDC en lugar de credenciales estáticas y convierta las revisiones de seguridad en una parte estándar de su proceso con git.

Si tiene preguntas o comentarios, no dude en contactarme en [Twitter](https://twitter.com/direct_messages/create/rishi_raj_jain_).
