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