AMR TECH™ AUDIT REPORT FOLIO 037

Auditoría Tienda Streaming · 2026-09-26

FOLIO: AUD-20260926-037 Secuencia: Auditoría #1 del día 2026-09-26
📅 2026-09-26 13:30:00 COT 👤 Auditor: Anderson Mares (AMR TECH) ● VIGENTE
Sistema Completo StreamingApps · Tienda & Cuentas

Auditoría
Tienda Streaming

Análisis completo de productos-dropi.php (1,151 líneas) y cuentas-streaming.php (583 líneas). Evaluación de seguridad, rendimiento, arquitectura de checkout y SEO.

productos-dropi.php · 1,151 líneas cuentas-streaming.php · 583 líneas
Score Global
6.5  / 10
REQUIERE MEJORAS
Hallazgos Críticos
4
ACCIÓN URGENTE
Hallazgos Medios
5
PLAN DE ACCIÓN
Fortalezas
4
MANTENER
Recomendaciones
6
ROADMAP

Resumen Ejecutivo

La tienda de streaming es principalmente un escaparate de productos con checkout vía WhatsApp (sin pasarela de pago integrada). Se detecta un buen uso de htmlspecialchars() para escape de salida y PDO con prepared statements cuando la base de datos está disponible. Sin embargo, el flujo de compra completo depende de un redirect a WhatsApp, sin carrito, sin rastreo de órdenes y sin confirmación de pago automatizada.

Desglose por dimensión
Seguridad
6/10
Comercio
4/10
Resiliencia
5/10
Rendimiento
6.5/10
SEO / UX
5.5/10
Calidad Código
7.5/10

Hallazgos Críticos 4 CRÍTICOS

C1
CRÍTICO Sin Pasarela de Pago — Checkout Vía WhatsApp
Risk: Revenue tracking imposible
IMPACTO ALTO

El checkout es un redirect a wa.me. No existe Order ID, no hay confirmación de pago, no hay reducción de inventario al comprar. Esto hace imposible el seguimiento de ingresos, permite duplicación de órdenes y no ofrece protección contra fraude.

# Arquitectura actual (sin pasarela)
Usuario hace clic → Genera link wa.me → Abre WhatsApp
→ Negociación manual → Sin registro de venta
→ Sin inventario actualizado → Sin comprobante
C2
CRÍTICO Dropi API — Punto Único de Falla, Sin Cache
productos-dropi.php · líneas 209–217
DISPONIBILIDAD

Los productos se obtienen de la API externa de Dropi sin fallback de cache local. Si la API está caída, el catálogo completo aparece vacío para el usuario. No hay lógica de reintento, no hay cache local y no hay mensaje de error amigable.

# Lines 209–217 (simplificado)
$response = @file_get_contents($dropi_url);
// No retry, no TTL cache, no fallback
if (!$response) { $products = []; }
C3
CRÍTICO Sin CSRF en Formularios de Búsqueda y Filtros
$_GET directo sin validación completa
SEGURIDAD

Los parámetros GET son tomados directamente: $selectedCategory = trim($_GET['cat']) y $search = trim($_GET['q']). Aunque GET es menos riesgoso que POST, los parámetros son reflejados en links href sin sanitización completa en todos los contextos, abriendo posibles vectores de XSS reflejado.

# Pattern de riesgo
$search = trim($_GET['q']);
// $search utilizado en href sin urlencode en todos los links
C4
CRÍTICO Mapeo de Precios con 5 Fallbacks sin Test Unitario
productos-dropi.php · líneas 232–293
PRECISIÓN FINANCIERA

El mapeo de campos sell_price y provider_price hace suposiciones con 5 nombres de campo alternativos. No hay test unitario que garantice la precisión del precio. Un cambio en la API de Dropi podría mostrar precios incorrectos silenciosamente.

# Cadena de fallbacks (líneas 232–293)
$price = $p['sell_price'] ?? $p['price_sell'] ?? $p['precio_venta']
       ?? $p['price'] ?? $p['valor'] ?? 0;
// Sin unit test → riesgo de precio 0 en producción

Hallazgos Medios 5 MEDIOS

M1
MEDIO
Sin Paginación en Catálogo

Query SELECT * FROM dropshipping_products WHERE is_active = 1 sin LIMIT. Con catálogos grandes, carga todos los registros en memoria en cada request. Riesgo de OOM y timeouts con >500 productos.

M2
MEDIO
Cuentas Streaming sin Autenticación

cuentas-streaming.php muestra cuentas disponibles públicamente sin login gate. Cualquier visitante puede ver el inventario de cuentas, precios internos y disponibilidad. Requiere autenticación mínima.

M3
MEDIO
Favoritos Solo en localStorage

Los productos favoritos se almacenan únicamente en localStorage. Se pierden al limpiar el navegador, cambiar de dispositivo o usar modo incógnito. No hay sincronización server-side, lo que afecta la experiencia de usuario recurrente.

M4
MEDIO
Imágenes sin Lazy Loading ni srcset

Las imágenes de productos provienen de CDN externo sin loading="lazy" en todos los <img> y sin srcset para responsive. Esto impacta el LCP (Largest Contentful Paint) en móvil con catálogos grandes.

M5
MEDIO
Sin SEO Meta Description ni Structured Data (JSON-LD)

No se generan <meta name="description"> dinámicas por producto ni <script type="application/ld+json"> con schema Product. Esto excluye los productos del rich snippet de Google Shopping y reduce el CTR orgánico significativamente. Para un e-commerce, la ausencia de structured data es un costo directo de adquisición.

Fortalezas 4 POSITIVOS

Escape de Salida Consistente

htmlspecialchars() aplicado a toda la salida de usuario (línea 11 y a lo largo del archivo). Protección efectiva contra XSS persistente y reflejado en el 95% de contextos de output.

PDO + Prepared Statements

Cuando la base de datos está disponible, se usa PDO con prepared statements correctamente. Protección efectiva contra inyección SQL en las consultas de catálogo y filtros de búsqueda.

Integración WhatsApp Bien Implementada

Los links wa.me incluyen mensaje pre-formateado con nombre del producto, precio y categoría. Reduce fricción en el proceso de consulta y mejora la tasa de conversación inicial con el vendedor.

Diseño Responsive con Tailwind

Layout mobile-first con Tailwind CSS correctamente configurado. Las tarjetas de producto se adaptan bien a distintos breakpoints. La experiencia móvil es funcional y estéticamente coherente.

Recomendaciones 6 ACCIONES

🔴
URGENTE · Prioridad 1
Integrar Pasarela de Pago (MercadoPago / Wompi)

Integrar MercadoPago o Wompi para Colombia. Agrega tracking de órdenes, confirmación de pago automática y certeza de ingresos. Implementar tabla orders con estado, monto, y referencia de transacción. Reducir dependencia total de WhatsApp para cierre.

🔴
URGENTE · Prioridad 2
Cache Server-Side de API Dropi (Redis / Archivo, TTL 30 min)

Agregar cache con TTL 30 minutos para los datos de Dropi. Si Redis no está disponible, usar cache en archivo (/tmp/dropi_cache.json). Implementar graceful degradation: mostrar últimos productos conocidos con banner "actualizando catálogo…" en lugar de página vacía.

🟡
MEDIA · Prioridad 3
Paginación en Catálogo (LIMIT + OFFSET)

Agregar LIMIT 24 OFFSET ? a la query principal del catálogo. Implementar UI de paginación o infinite scroll. Objetivo: máximo 24 productos por página para controlar memoria y tiempos de respuesta.

🟡
MEDIA · Prioridad 4
Lazy Loading + srcset en Imágenes de Productos

Agregar loading="lazy" a todos los <img> de productos y decoding="async". Si el CDN de Dropi soporta parámetros de redimensionado, generar srcset para 400w, 800w y 1200w. Mejora estimada en LCP: 40–60% en móvil.

🟡
MEDIA · Prioridad 5
JSON-LD Structured Data para Productos (Google Shopping)

Agregar <script type="application/ld+json"> con schema Product incluyendo name, description, price, image y offers. Habilita rich snippets en Google, mejora CTR orgánico y es requisito para Google Shopping gratuito.

🟢
BAJA · Prioridad 6
Favoritos Server-Side (Cookie o DB Liviana)

Migrar favoritos de localStorage a cookie firmada o tabla DB user_favorites con identificador de sesión. Permite que los favoritos persistan entre dispositivos y sesiones, mejorando la retención de usuarios recurrentes.

Plan de Acción Priorizado

SEMANAS 1–2 · URGENTE Remediación Crítica
Implementar cache de API Dropi con fallback a archivo (evitar catálogo vacío)
Agregar urlencode() consistente en todos los parámetros reflejados en href
Escribir tests unitarios de mapeo de precios con campos alternativos de Dropi
SEMANAS 3–4 · MEDIO Rendimiento & SEO
Agregar LIMIT + OFFSET a query de catálogo + UI de paginación
Implementar loading="lazy" + decoding="async" en todas las imágenes
Agregar JSON-LD Product schema en páginas de detalle
SEMANAS 5–8 · ESTRATÉGICO Monetización & Comercio
Integrar MercadoPago o Wompi con tabla orders y notificaciones IPN
Gate de autenticación en cuentas-streaming.php
Migrar favoritos a cookie firmada / tabla DB

Archivos Analizados

productos-dropi.php
1,151 líneas — Catálogo principal con integración Dropi API, filtros por categoría, búsqueda, favoritos y checkout WhatsApp.
PHP 8.x PDO Tailwind CSS Dropi API
cuentas-streaming.php
583 líneas — Catálogo de cuentas de streaming (Netflix, Disney+, etc.), precios por plan y disponibilidad en tiempo real.
PHP 8.x MySQL Sin Auth