4. Seguridad

4. Seguridad

Esta sección cubre todos los aspectos de seguridad del sistema DTEM, incluyendo hardening, gestión de certificados, control de accesos, compliance y mejores prácticas de seguridad.

4.1. Arquitectura de Seguridad

4.1.1. Principios de Seguridad

Zero Trust Architecture

  • Never Trust, Always Verify: Validación continua de identidad y accesos
  • Least Privilege: Acceso mínimo necesario para cada rol
  • Micro-segmentation: Aislamiento de servicios y redes
  • Encryption Everywhere: Cifrado en reposo y en tránsito

Defense in Depth

┌─────────────────────────────────────────────────────────────┐
│                    SECURITY LAYERS                          │
├─────────────────────────────────────────────────────────────┤
│ 1. Network Security (Firewalls, WAF, DDoS Protection)     │
│ 2. Application Security (Authentication, Authorization)     │
│ 3. Data Security (Encryption, Masking, Access Control)     │
│ 4. Infrastructure Security (OS Hardening, Patching)        │
│ 5. Physical Security (Data Center Access, Biometrics)      │
└─────────────────────────────────────────────────────────────┘

4.1.2. Controles de Seguridad

Control Type Implementation Status
Authentication JWT + MFA ✅ Implemented
Authorization RBAC + ABAC ✅ Implemented
Encryption AES-256 + TLS 1.3 ✅ Implemented
Audit Logging SIEM Integration ✅ Implemented
Vulnerability Scanning OWASP ZAP ✅ Implemented
Penetration Testing Annual Assessment 🔄 Scheduled

4.2. Gestión de Identidades y Accesos (IAM)

4.2.1. Modelo de Autenticación

Multi-Factor Authentication (MFA)

// MFA Configuration
const mfaConfig = {
  methods: ['TOTP', 'SMS', 'Email'],
  requiredForRoles: ['admin', 'super_admin'],
  gracePeriod: 30, // days
  backupCodes: 10,
  sessionTimeout: 8 * 60 * 60 // 8 hours
};

// TOTP Implementation
const speakeasy = require('speakeasy');
const qrcode = require('qrcode');

// Generate secret for user
const secret = speakeasy.generateSecret({
  name: `DTEM (${user.email})`,
  issuer: 'DTEM System',
  length: 32
});

// Generate QR code
const qrCodeUrl = await qrcode.toDataURL(secret.otpauth_url);

JWT Token Management

// JWT Configuration
const jwtConfig = {
  algorithm: 'RS256',
  expiresIn: '15m',
  issuer: 'dtem-api',
  audience: 'dtem-clients',
  keyId: 'dtem-signing-key-2023'
};

// Token Structure
const tokenPayload = {
  sub: user.id,
  email: user.email,
  roles: user.roles,
  permissions: user.permissions,
  session_id: sessionId,
  iat: Math.floor(Date.now() / 1000),
  exp: Math.floor(Date.now() / 1000) + (15 * 60),
  jti: crypto.randomUUID()
};

4.2.2. Role-Based Access Control (RBAC)

Role Hierarchy

roles:
  super_admin:
    description: "Full system access"
    permissions:
      - "*"
    inherits: []
    
  admin:
    description: "Administrative access"
    permissions:
      - "users.*"
      - "caf.*"
      - "dte.*"
      - "reports.*"
      - "system.*"
    inherits: []
    
  operator:
    description: "Day-to-day operations"
    permissions:
      - "dte.create"
      - "dte.read"
      - "dte.update"
      - "caf.read"
      - "reports.read"
    inherits: []
    
  viewer:
    description: "Read-only access"
    permissions:
      - "dte.read"
      - "caf.read"
      - "reports.read"
    inherits: []

Permission Matrix

Resource Super Admin Admin Operator Viewer
Users CRUD CRUD R R
CAF CRUD CRUD R R
DTE CRUD CRUD CRU R
Reports CRUD CRUD R R
System CRUD R - -
Audit Logs R R - -

4.2.3. Attribute-Based Access Control (ABAC)

Policy Definition

{
  "policy_id": "dte_access_policy",
  "description": "DTE access based on user attributes",
  "rules": [
    {
      "effect": "allow",
      "actions": ["dte.create", "dte.read"],
      "conditions": {
        "and": [
          {"user.department": ["accounting", "finance"]},
          {"user.status": "active"},
          {"resource.company_id": {"eq": "{{user.company_id}}"}}
        ]
      }
    },
    {
      "effect": "allow",
      "actions": ["dte.approve"],
      "conditions": {
        "and": [
          {"user.role": "manager"},
          {"user.department": {"eq": "{{resource.department}}"}},
          {"resource.amount": {"lt": 1000000}}
        ]
      }
    }
  ]
}

4.3. Gestión de Certificados Digitales

4.3.1. Ciclo de Vida de Certificados

Certificate Management Workflow

sequenceDiagram
    participant System
    participant PKI
    participant SII
    participant User
    
    System->>PKI: Generate CSR
    PKI-->>System: Issue Certificate
    System->>SII: Register Certificate
    SII-->>System: Confirmation
    System->>User: Certificate Active
    
    Note over System: Monitor Expiry
    System->>PKI: Renew Certificate (30 days before expiry)
    PKI-->>System: New Certificate
    System->>SII: Update Certificate
    System->>User: Certificate Updated

Automated Certificate Renewal

#!/bin/bash
# cert-renewal.sh

CERT_DIR="/app/certs"
EXPIRY_THRESHOLD=30 # days

check_certificate_expiry() {
    local cert_file=$1
    local expiry_date=$(openssl x509 -in "$cert_file" -noout -enddate | cut -d= -f2)
    local expiry_epoch=$(date -d "$expiry_date" +%s)
    local current_epoch=$(date +%s)
    local days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 ))
    
    echo $days_until_expiry
}

renew_certificate() {
    local cert_name=$1
    
    echo "Renewing certificate: $cert_name"
    
    # Generate new CSR
    openssl req -new -key "${CERT_DIR}/${cert_name}.key" \
        -out "${CERT_DIR}/${cert_name}.csr" \
        -subj "/C=CL/ST=Region/L=City/O=Empresa/CN=dtem.empresa.cl"
    
    # Submit to CA
    # ... CA integration logic
    
    # Install new certificate
    # ... installation logic
    
    # Restart services
    systemctl restart dtem-api
}

# Check all certificates
for cert in "${CERT_DIR}"/*.crt; do
    days_left=$(check_certificate_expiry "$cert")
    
    if [ "$days_left" -lt "$EXPIRY_THRESHOLD" ]; then
        cert_name=$(basename "$cert" .crt)
        renew_certificate "$cert_name"
    fi
done

4.3.2. SII Certificate Integration

Certificate Upload and Validation

// SII Certificate Service
class SIICertificateService {
    async uploadCertificate(certificateData, privateKey) {
        // Validate certificate format
        const cert = new X509Certificate(certificateData);
        
        // Verify certificate is valid for SII
        if (!this.validateSIICertificate(cert)) {
            throw new Error('Invalid SII certificate');
        }
        
        // Extract certificate information
        const certInfo = {
            subject: cert.subject,
            issuer: cert.issuer,
            serialNumber: cert.serialNumber,
            validFrom: cert.validFrom,
            validTo: cert.validTo,
            fingerprint: cert.fingerprint
        };
        
        // Store certificate securely
        await this.storeCertificate(certInfo, privateKey);
        
        // Register with SII
        await this.registerWithSII(certInfo);
        
        return certInfo;
    }
    
    validateSIICertificate(cert) {
        // Check issuer is SII
        if (!cert.issuer.includes('Servicio de Impuestos Internos')) {
            return false;
        }
        
        // Check certificate purpose
        const keyUsage = cert.keyUsage;
        if (!keyUsage.digitalSignature || !keyUsage.nonRepudiation) {
            return false;
        }
        
        // Check certificate is not expired
        const now = new Date();
        if (now < cert.validFrom || now > cert.validTo) {
            return false;
        }
        
        return true;
    }
}

4.4. Hardening de Sistema

4.4.1. Security Hardening Checklist

Operating System Hardening

#!/bin/bash
# os-hardening.sh

# Update system packages
apt update && apt upgrade -y

# Remove unnecessary packages
apt remove -y telnet ftp rsh rlogin
apt autoremove -y

# Configure firewall
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

# Secure SSH
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#Port 22/Port 2222/' /etc/ssh/sshd_config
systemctl restart ssh

# Configure fail2ban
apt install -y fail2ban
cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3

[sshd]
enabled = true
port = 2222
logpath = /var/log/auth.log

[nginx-http-auth]
enabled = true
logpath = /var/log/nginx/error.log
EOF

systemctl enable fail2ban
systemctl start fail2ban

# Configure automatic security updates
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

Application Security Hardening

// Security Middleware Configuration
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');

// Security headers
app.use(helmet({
    contentSecurityPolicy: {
        directives: {
            defaultSrc: ["'self'"],
            styleSrc: ["'self'", "'unsafe-inline'"],
            scriptSrc: ["'self'"],
            imgSrc: ["'self'", "data:", "https:"],
            connectSrc: ["'self'", "https://api.dtem.empresa.cl"],
            fontSrc: ["'self'"],
            objectSrc: ["'none'"],
            mediaSrc: ["'self'"],
            frameSrc: ["'none'"]
        }
    },
    hsts: {
        maxAge: 31536000,
        includeSubDomains: true,
        preload: true
    }
}));

// Rate limiting
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // limit each IP to 100 requests per windowMs
    message: 'Too many requests from this IP',
    standardHeaders: true,
    legacyHeaders: false
});

app.use('/api/', limiter);

// Input validation and sanitization
const { body, validationResult } = require('express-validator');

const validateDTE = [
    body('documentType').isIn(['33', '34', '39', '41', '52', '56', '61']),
    body('rut').matches(/^\d{1,2}\.\d{3}\.\d{3}-[0-9kK]$/),
    body('totalAmount').isFloat({ min: 0 }),
    body('email').isEmail().normalizeEmail(),
    
    (req, res, next) => {
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() });
        }
        next();
    }
];

4.4.2. Network Security

Network Segmentation

# Network Policy for Kubernetes
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: dtem-network-policy
  namespace: dtem-prod
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 3000
  - from:
    - podSelector:
        matchLabels:
          app: api-gateway
    ports:
    - protocol: TCP
      port: 3000
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - podSelector:
        matchLabels:
          app: redis
    ports:
    - protocol: TCP
      port: 6379
  - to: []
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 443

Web Application Firewall (WAF)

# Nginx WAF Configuration
server {
    listen 443 ssl http2;
    server_name api.dtem.empresa.cl;
    
    # SSL Configuration
    ssl_certificate /etc/ssl/certs/dtem.crt;
    ssl_certificate_key /etc/ssl/private/dtem.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;
    
    # Security Headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    
    # WAF Rules
    location / {
        # SQL Injection Protection
        if ($args ~* "union.*select.*(") {
            return 403;
        }
        
        # XSS Protection
        if ($args ~* "<script") {
            return 403;
        }
        
        # Path Traversal Protection
        if ($uri ~* "\.\./") {
            return 403;
        }
        
        proxy_pass http://api-gateway-service:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

4.5. Compliance y Auditoría

4.5.1. Regulatory Compliance

Chilean Tax Regulations

  • Resolución Exenta N° 60: Requisitos técnicos para DTE
  • Resolución Exenta N° 3.497: Certificados digitales
  • Norma Técnica N° 73: Formatos y estándares XML
  • Circular N° 57: Validación de firmas digitales

Data Protection Compliance

// Data Protection Implementation
class DataProtectionService {
    // GDPR/Chilean Law Implementation
    async anonymizePersonalData(data) {
        const sensitiveFields = ['email', 'phone', 'address', 'rut'];
        
        return data.map(record => {
            const anonymized = { ...record };
            
            sensitiveFields.forEach(field => {
                if (anonymized[field]) {
                    anonymized[field] = this.hashField(anonymized[field]);
                }
            });
            
            return anonymized;
        });
    }
    
    hashField(value) {
        return crypto.createHash('sha256')
            .update(value + process.env.HASH_SALT)
            .digest('hex');
    }
    
    async logDataAccess(userId, action, resource) {
        const auditLog = {
            timestamp: new Date().toISOString(),
            userId,
            action,
            resource,
            ipAddress: this.getClientIP(),
            userAgent: this.getUserAgent()
        };
        
        await this.auditService.log(auditLog);
    }
}

4.5.2. Security Auditing

Audit Trail Implementation

-- Audit Log Table Structure
CREATE TABLE audit_logs (
    id BIGSERIAL PRIMARY KEY,
    timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    user_id UUID REFERENCES users(id),
    action VARCHAR(100) NOT NULL,
    resource_type VARCHAR(50) NOT NULL,
    resource_id VARCHAR(100),
    old_values JSONB,
    new_values JSONB,
    ip_address INET,
    user_agent TEXT,
    session_id UUID,
    success BOOLEAN NOT NULL,
    error_message TEXT
);

-- Indexes for performance
CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp);
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
CREATE INDEX idx_audit_logs_action ON audit_logs(action);
CREATE INDEX idx_audit_logs_resource ON audit_logs(resource_type, resource_id);

Automated Security Scanning

# Security Scan Pipeline
security_scan:
  stage: security
  image: owasp/zap2docker-stable
  script:
    - mkdir -p /zap/wrk/
    - /zap/zap-baseline.py 
        -t https://api.dtem.empresa.cl 
        -J gl-sast-report.json
        -r zap-report.html
        -x zap-report.xml
  artifacts:
    reports:
      sast: gl-sast-report.json
    paths:
      - zap-report.html
      - zap-report.xml
  only:
    - main
    - develop

dependency_check:
  stage: security
  image: owasp/dependency-check
  script:
    - dependency-check.sh 
        --project "DTEM" 
        --scan . 
        --format JSON 
        --format HTML 
        --out reports/
  artifacts:
    reports:
      dependency_scanning: reports/dependency-check-report.json
    paths:
      - reports/dependency-check-report.html

4.6. Incident Response

4.6.1. Security Incident Response Plan

Incident Classification

Severity Response Time Escalation Examples
Critical 15 minutes Immediate Data breach, system compromise
High 1 hour 4 hours Service disruption, unauthorized access
Medium 4 hours 24 hours Suspicious activity, policy violations
Low 24 hours 72 hours Failed login attempts, minor misconfigurations

Response Workflow

flowchart TD
    A[Security Incident Detected] --> B{Triage & Classification}
    B -->|Critical| C[Immediate Response]
    B -->|High| D[Urgent Response]
    B -->|Medium| E[Standard Response]
    B -->|Low| F[Low Priority Response]
    
    C --> G[Containment]
    D --> G
    E --> G
    F --> G
    
    G --> H[Eradication]
    H --> I[Recovery]
    I --> J[Post-Incident Review]
    J --> K[Documentation & Lessons Learned]

4.6.2. Security Monitoring

Real-time Threat Detection

# Falco Rules for Security Monitoring
- rule: Unauthorized Database Access
  desc: Detect unauthorized database access attempts
  condition: >
    spawned_process and
    proc.name in (psql, mysql, sqlite3) and
    not user.name in (postgres, mysql, root)
  output: >
    Unauthorized database access detected
    (user=%user.name command=%proc.cmdline container=%container.name)
  priority: HIGH
  tags: [database, security]

- rule: Suspicious Network Connection
  desc: Detect suspicious outbound network connections
  condition: >
    outbound_connect and
    not fd.sip in (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and
    not fd.sip in (api.dtem.empresa.cl, sii.cl)
  output: >
    Suspicious network connection detected
    (user=%user.name connection=%fd.name ip=%fd.cip)
  priority: MEDIUM
  tags: [network, security]

Security Metrics Dashboard

{
  "security_dashboard": {
    "panels": [
      {
        "title": "Failed Login Attempts",
        "type": "stat",
        "targets": [
          {
            "expr": "rate(failed_login_total[5m])",
            "legendFormat": "Failed Logins/sec"
          }
        ]
      },
      {
        "title": "Security Events by Severity",
        "type": "piechart",
        "targets": [
          {
            "expr": "sum by (severity) (security_events_total)",
            "legendFormat": "{{severity}}"
          }
        ]
      },
      {
        "title": "Vulnerability Scan Results",
        "type": "table",
        "targets": [
          {
            "expr": "vulnerability_scanner_results",
            "format": "table"
          }
        ]
      }
    ]
  }
}

4.7. Security Best Practices

4.7.1. Development Security

Secure Coding Guidelines

// Secure Coding Examples

// 1. Parameterized Queries (Prevent SQL Injection)
const getUserById = async (userId) => {
    const query = 'SELECT * FROM users WHERE id = $1';
    const result = await pool.query(query, [userId]);
    return result.rows[0];
};

// 2. Input Validation
const validateEmail = (email) => {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
};

// 3. Secure Password Handling
const bcrypt = require('bcrypt');
const saltRounds = 12;

const hashPassword = async (password) => {
    return await bcrypt.hash(password, saltRounds);
};

// 4. Secure File Upload
const multer = require('multer');
const path = require('path');

const upload = multer({
    dest: 'uploads/',
    fileFilter: (req, file, cb) => {
        const allowedTypes = ['.xml', '.pdf', '.json'];
        const ext = path.extname(file.originalname).toLowerCase();
        
        if (allowedTypes.includes(ext)) {
            cb(null, true);
        } else {
            cb(new Error('Invalid file type'));
        }
    },
    limits: {
        fileSize: 10 * 1024 * 1024 // 10MB
    }
});

4.7.2. Security Testing

Automated Security Tests

// Security Test Suite
describe('Security Tests', () => {
    test('Should prevent SQL injection', async () => {
        const maliciousInput = "'; DROP TABLE users; --";
        
        const response = await request(app)
            .post('/api/users')
            .send({ email: maliciousInput })
            .expect(400);
            
        expect(response.body.errors).toBeDefined();
    });
    
    test('Should enforce rate limiting', async () => {
        const requests = Array(101).fill().map(() => 
            request(app).get('/api/health')
        );
        
        const responses = await Promise.all(requests);
        const rateLimitedResponses = responses.filter(r => r.status === 429);
        
        expect(rateLimitedResponses.length).toBeGreaterThan(0);
    });
    
    test('Should validate JWT tokens', async () => {
        const response = await request(app)
            .get('/api/protected')
            .set('Authorization', 'Bearer invalid-token')
            .expect(401);
            
        expect(response.body.message).toBe('Invalid token');
    });
});

Próxima sección: 5. Base de Datos