Seguridad

Seguridad en Módulos Perfex: CSRF, XSS y SQL Injection

J. Negro 15 Dic 2025 18 min lectura
Volver al Blog

Introducción a la Seguridad Web

La seguridad en el desarrollo de módulos para Perfex CRM es crítica. Un módulo vulnerable puede comprometer todo el sistema, exponiendo datos sensibles de clientes y la empresa. En este artículo cubriremos las tres vulnerabilidades más comunes según OWASP.

🔒 Las 3 Amenazas Principales

  • CSRF - Cross-Site Request Forgery
  • XSS - Cross-Site Scripting
  • SQL Injection - Inyección SQL

1. CSRF - Cross-Site Request Forgery

CSRF ocurre cuando un atacante engaña a un usuario autenticado para que ejecute acciones no deseadas. Perfex CRM incluye protección CSRF por defecto, pero debes usarla correctamente.

Cómo Funciona un Ataque CSRF

Un atacante crea una página maliciosa que envía un formulario a tu aplicación. Si el usuario tiene sesión activa, la acción se ejecuta sin su conocimiento.

❌ Vulnerable

// JavaScript sin token CSRF
$.post('/admin/modulo/delete', {
    id: 123
});

✅ Protegido

// Incluye token CSRF
$.post(admin_url + 'modulo/delete', {
    ...csrfData,
    id: 123
});

Implementación Correcta

// En JavaScript, el objeto csrfData está disponible globalmente
$.ajax({
    url: admin_url + 'mi_modulo/guardar',
    type: 'POST',
    data: {
        [csrfData.token_name]: csrfData.hash,  // Token CSRF
        nombre: $('#nombre').val(),
        descripcion: $('#descripcion').val()
    },
    success: function(response) {
        // Manejar respuesta
    }
});

// Forma abreviada usando spread operator
$.post(admin_url + 'mi_modulo/guardar', {
    ...csrfData,
    nombre: 'valor'
});

💡 En Formularios HTML

Perfex añade automáticamente el token CSRF a los formularios creados con form_open(). Nunca uses <form> directamente.

2. XSS - Cross-Site Scripting

XSS permite a un atacante inyectar scripts maliciosos que se ejecutan en el navegador de otros usuarios. Puede robar sesiones, redirigir a sitios maliciosos o modificar el contenido de la página.

Tipos de XSS

❌ Vulnerable

<!-- Sin escapar -->
<p><?php echo $usuario->nombre; ?></p>

// Si nombre = "<script>alert('XSS')</script>"
// El script se ejecutará

✅ Protegido

<!-- Escapado correctamente -->
<p><?php echo html_escape($usuario->nombre); ?></p>

// El script se mostrará como texto
// &lt;script&gt;alert('XSS')&lt;/script&gt;

Funciones de Escape en Perfex

// Para HTML
echo html_escape($input);

// Para atributos HTML
<input value="<?php echo html_escape($valor); ?>">

// Para URLs
<a href="<?php echo htmlspecialchars($url, ENT_QUOTES, 'UTF-8'); ?>">

// Para JavaScript (en JSON)
<script>
    var data = <?php echo json_encode($data); ?>;
</script>

⚠️ Regla de Oro

Nunca confíes en datos del usuario. Escapa TODO lo que venga del exterior antes de mostrarlo: parámetros GET/POST, datos de BD, cookies, headers HTTP.

3. SQL Injection

SQL Injection ocurre cuando datos del usuario se insertan directamente en queries SQL sin sanitizar. El atacante puede leer, modificar o eliminar toda la base de datos.

❌ Vulnerable

// Concatenación directa
$id = $_GET['id'];
$query = "SELECT * FROM users
          WHERE id = " . $id;
$this->db->query($query);

// Si id = "1 OR 1=1"
// Devuelve TODOS los usuarios

✅ Protegido

// Query Builder de CodeIgniter
$id = $this->input->get('id');
$this->db
    ->where('id', $id)
    ->get(db_prefix() . 'users');

// CodeIgniter escapa automáticamente
// Query: WHERE id = '1 OR 1=1'

Mejores Prácticas

// 1. SIEMPRE usa Query Builder
$this->db
    ->select('id, nombre, email')
    ->from(db_prefix() . 'clientes')
    ->where('activo', 1)
    ->where('id', $id)
    ->get();

// 2. Si necesitas query raw, usa bindings
$this->db->query(
    "SELECT * FROM " . db_prefix() . "clientes WHERE email = ?",
    [$email]
);

// 3. Para LIKE, usa escape_like_str()
$busqueda = $this->db->escape_like_str($input);
$this->db->like('nombre', $busqueda);

// 4. Valida tipos de datos
$id = (int) $this->input->get('id');  // Fuerza integer

Resumen: Checklist de Seguridad

✅ Lista de Verificación

CSRF:
□ Incluir csrfData en todas las peticiones AJAX
□ Usar form_open() en lugar de <form>

XSS:
□ Usar html_escape() en todas las salidas
□ Usar json_encode() para datos JavaScript
□ Validar y sanitizar inputs

SQL Injection:
□ Usar Query Builder siempre
□ Usar bindings para queries raw
□ Validar tipos de datos
□ Usar db_prefix() en nombres de tablas

JN

J. Negro

Desarrollador especializado en Perfex CRM con más de 5 años de experiencia creando módulos empresariales. Fundador de SalesCloud.