[Resuelto] ¿por qué es necesaria $_server["php_self"] en el action de un form?

Iniciado por big_ed, 13 Agosto 2019, 20:35 PM

0 Miembros y 1 Visitante están viendo este tema.

@XSStringManolo

Cita de: big_ed en 14 Agosto 2019, 02:50 AM
No estoy usando input de tipo mail o telf porque no son compatibles con Internet explorer 9.
Yo ignoro a internet explor 8 para abajo, pero del 9 para arriba siempre debe ser compatible.
tampoco uso placeholder ni required

Exp1 y exp2 si las uso, fijate bien , estan en el preg_match

Entonces solo me limitare a hacer la seguridad basica porque no soy un hacker experto, y si alguien quiere una super seguridad, pues que pague mas para subcontratar y llamar a un experto que refuerce, porque lo que es yo, no es mi rama
No tenía ni idea de que no eran compatibles O.o

Disculpa, no los vi, me cuesta leer códigos sin antes darles formato con alguna herramienta.

Yo menos, no se ni defenderme adecuadamente de ataques que sí se realizar... Por algo no publico mis servers y solo acceden usuarios registrados a través de proxies y tengo 50.000 copias de seguridad en todos sitios, le tengo pendrives puestos para archivos importantes y los voy alternando por si hasta me jodiesen el pendrive que está puesto.

Si es para un sitio serio tuyo o si tienes contrato con alguien ten cuidado que si algún usuario del sitio es estafado debido a que se filtran sus credenciales en tu sitio, si te denuncia lo vas a tener que pagar.  :-(



big_ed

Cita de: string Manolo en 14 Agosto 2019, 03:31 AM
No tenía ni idea de que no eran compatibles O.o

Disculpa, no los vi, me cuesta leer códigos sin antes darles formato con alguna herramienta.

Yo menos, no se ni defenderme adecuadamente de ataques que sí se realizar... Por algo no publico mis servers y solo acceden usuarios registrados a través de proxies y tengo 50.000 copias de seguridad en todos sitios, le tengo pendrives puestos para archivos importantes y los voy alternando por si hasta me jodiesen el pendrive que está puesto.

Si es para un sitio serio tuyo o si tienes contrato con alguien ten cuidado que si algún usuario del sitio es estafado debido a que se filtran sus credenciales en tu sitio, si te denuncia lo vas a tener que pagar.  :-(




entiendo , no es tu rama
yo en cambio si tengo la necesidad de saber la compatibilidad de una tecnologia en todos los navegadores y sus versiones... cuando hago una web la pruebo en al menos los 5 navegadores mas importantes, en pc de escritorio, tablets, moviles, laptops, etc

si, el editor de codigo de muchos foros solo es blanco y negro...yo queria agregarle color al codigo para que se entendiera mejor pero no me lo permitio

que es eso de las credenciales?
yo por si acaso especifico que mi nivel alto es en diseño desde cero y programacion de animaciones...dejo claro que de seguridad informatica y SEO hago lo basico, para que una web funcione bien y sea etica su elaboracion...pero si quieren algo mas robusto y que se posicione en el primer lugar de google entonces que me paguen mas para contratar a un experto en esa rama o que ellos lo incorporen y que meta mano en mi codigo
No se puede saber de todo, quien mucho abarca poco aprieta , o algo asi era  ;D
Mejor especializarse en algo puntual

#!drvy

#12
Hola,

En general lo tienes bien aunque supongo que esos datos los estas guardando en una base de datos. En tal caso, te recomiendo usar sentencias preparadas si es que no las estas utilizando ya.
https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php - MySQLi
https://www.php.net/manual/es/pdo.prepared-statements.php - PDO

De todos modos, te dejo el como lo haría yo por si pillas alguna idea o algo.

Código (php) [Seleccionar]
<?php

function validate($input$type$required false)
{
    if (
$required && empty($input)) {
        throw new \
Exception('No ha rellenado unos de los campos obligatorios');
    }

    
// Nos aseguramos de que el input no va a ser mayor de 1024 caracteres.
    
if (mb_strlen($input'utf-8') > 1024) {
        throw new \
Exception('Uno de los campos contiene demasiados caracteres.');
    }

    switch (
$type) {
        case 
'user':
            
$valid preg_match('/^[[:alpha:]\s]{2,50}$/iu'$input);
            
$error 'El campo Nombre permite un máximo de 50 caracteres de solo letras mayusculas o minusculas';
            break;

        case 
'email':
            
$valid filter_var($inputFILTER_VALIDATE_EMAIL);
            
$error 'El campo Correo no es válido.';
            break;

        case 
'phone':
            
$valid preg_match('/^[0-9]{1,11}$/'$input);
            
$error 'El campo Teléfono permite un máximo de 11 caracteres numericos';
            break;

        case 
'text':
            
$valid = (mb_strlen($input) <= 900);
            
$error 'El campo Texto no puede contener más de 900 caracteres';
            break;
    }

    if (!
$valid) {
        throw new \
Exception($error);
    }

    return 
htmlspecialchars(trim($input), ENT_QUOTES);
}

if (isset(
$_POST['submit'])) {
    try {
        
$user validate($_POST['text'], 'user'true);
        
$email validate($_POST['mail'], 'email'true);
        
$phone validate($_POST['telf'], 'phone');
        
$post validate($_POST['post'], 'text');

        
// Guardar datos en base de datos con sentencias preparadas
        
echo 'Válido';

    } catch (\
Exception $error) {
        echo 
$error->getMessage();
    }
}




Las principales diferencias son:

- Meto toda la validación en una función.

- Uso FILTER_VALIDATE_EMAIL para validar correo en vez de regex. En tu regex por ejemplo, el correo juan@undominiomuylargo.productions no validaria porque además de sobrepasar los 30 caracteres que le pones de límite en general, sobrepasa los 9 caracteres que le pones de limite al TLD (aquí tienes la lista de TLDS actuales), según estándar se permite hasta 63 caracteres de longitud para un TLD..

- Validó la longitud min/max de los campos en el propio regex ahorrando un IF.

- Garantizo que los caracteres son tratados como UTF-8 sobre todo en el campo de Nombre donde si te fijas usó un Character class de regex para decirle que coja todo carácter alpha (letras) y trato la expresión como unicode. Por defecto, si no tratas los strings como multibyte, los caracteres fuera del ASCII genérico son tratados como dos bytes. Por ejemplo strlen devuelve 2 para la letra Ñ (mb_strlen devuelve 1). Así permites que haya nombres como Iñaki o Jóse.


Si te soy sincero, yo no utilizariá htmlspecialchars para "sanitizar" el input. Dado que las sentencias preparadas ya se encargan de que no haya una inyección SQL por culpa de caracteres raros, guardariá los datos sin "sanitizar" (aparte de los requerimientos como por ejemplo solo números para el teléfono) y la hora de imprimir (mostrar) dicho campo, utilizariá htmlentities.


CitarPero ¿cuáles son exactamente los caracteres que debo evitar?
POrque yo podría impedirlos con expresiones regulares, pero quisiera saber cuáles son.


Lo peor que puedes hacer es una lista negra de caracteres. Es mejor hacer una lista blanca y permitir solo los caracteres que tu quieras a hacer una negra y que tengas que estar cada 2x3 metiendo caracteres nuevos porque resulta que ó no es lo mismo que ò pero el sistema los trata igual. Es un poco como el intento de censurar palabras malsonantes en este foro, la palabra ***** esta censurada (te pone las * cuando lo publicas) pero la palabra m.ierda o mierda o mierda no  :laugh:


Citaryo en cambio si tengo la necesidad de saber la compatibilidad de una tecnologia en todos los navegadores y sus versiones... cuando hago una web la pruebo en al menos los 5 navegadores mas importantes, en pc de escritorio, tablets, moviles, laptops, etc

No se, ya nadie da soporte para IE9.. es un poco absurdo hoy en dia. Nosotros por ejemplo solo damos soporte para las 2 últimas versiones de cada navegador (IE10, IE11). Es una versión que tiene ya 8 años y no es tan vital como IE8. Es decir, si tienes IE 9, no hay ninguna razón para que no tengas IE 10 o IE 11. IE 8 en cambio es un poco más vital en ese sentido porque fue la última versión de IE con soporte para XP. Pero vamos, estamos hablando de navegadores que llevan AÑOS sin actualizarse y con estándares obsoletos cuanto menos.

Saludos

big_ed

Cita de: #!drvy en 14 Agosto 2019, 10:04 AM
Hola,

En general lo tienes bien aunque supongo que esos datos los estas guardando en una base de datos. En tal caso, te recomiendo usar sentencias preparadas si es que no las estas utilizando ya.
https://www.php.net/manual/es/mysqli.quickstart.prepared-statements.php - MySQLi
https://www.php.net/manual/es/pdo.prepared-statements.php - PDO

De todos modos, te dejo el como lo haría yo por si pillas alguna idea o algo.

Código (php) [Seleccionar]
<?php

function validate($input$type$required false)
{
    if (
$required && empty($input)) {
        throw new \
Exception('No ha rellenado unos de los campos obligatorios');
    }

    
// Nos aseguramos de que el input no va a ser mayor de 1024 caracteres.
    
if (mb_strlen($input'utf-8') > 1024) {
        throw new \
Exception('Uno de los campos contiene demasiados caracteres.');
    }

    switch (
$type) {
        case 
'user':
            
$valid preg_match('/^[[:alpha:]\s]{2,50}$/iu'$input);
            
$error 'El campo Nombre permite un máximo de 50 caracteres de solo letras mayusculas o minusculas';
            break;

        case 
'email':
            
$valid filter_var($inputFILTER_VALIDATE_EMAIL);
            
$error 'El campo Correo no es válido.';
            break;

        case 
'phone':
            
$valid preg_match('/^[0-9]{1,11}$/'$input);
            
$error 'El campo Teléfono permite un máximo de 11 caracteres numericos';
            break;

        case 
'text':
            
$valid = (mb_strlen($input) <= 900);
            
$error 'El campo Texto no puede contener más de 900 caracteres';
            break;
    }

    if (!
$valid) {
        throw new \
Exception($error);
    }

    return 
htmlspecialchars(trim($input), ENT_QUOTES);
}

if (isset(
$_POST['submit'])) {
    try {
        
$user validate($_POST['text'], 'user'true);
        
$email validate($_POST['mail'], 'email'true);
        
$phone validate($_POST['telf'], 'phone');
        
$post validate($_POST['post'], 'text');

        
// Guardar datos en base de datos con sentencias preparadas
        
echo 'Válido';

    } catch (\
Exception $error) {
        echo 
$error->getMessage();
    }
}




Las principales diferencias son:

- Meto toda la validación en una función.

- Uso FILTER_VALIDATE_EMAIL para validar correo en vez de regex. En tu regex por ejemplo, el correo juan@undominiomuylargo.productions no validaria porque además de sobrepasar los 30 caracteres que le pones de límite en general, sobrepasa los 9 caracteres que le pones de limite al TLD (aquí tienes la lista de TLDS actuales), según estándar se permite hasta 63 caracteres de longitud para un TLD..

- Validó la longitud min/max de los campos en el propio regex ahorrando un IF.

- Garantizo que los caracteres son tratados como UTF-8 sobre todo en el campo de Nombre donde si te fijas usó un Character class de regex para decirle que coja todo carácter alpha (letras) y trato la expresión como unicode. Por defecto, si no tratas los strings como multibyte, los caracteres fuera del ASCII genérico son tratados como dos bytes. Por ejemplo strlen devuelve 2 para la letra Ñ (mb_strlen devuelve 1). Así permites que haya nombres como Iñaki o Jóse.


Si te soy sincero, yo no utilizariá htmlspecialchars para "sanitizar" el input. Dado que las sentencias preparadas ya se encargan de que no haya una inyección SQL por culpa de caracteres raros, guardariá los datos sin "sanitizar" (aparte de los requerimientos como por ejemplo solo números para el teléfono) y la hora de imprimir (mostrar) dicho campo, utilizariá htmlentities.



Lo peor que puedes hacer es una lista negra de caracteres. Es mejor hacer una lista blanca y permitir solo los caracteres que tu quieras a hacer una negra y que tengas que estar cada 2x3 metiendo caracteres nuevos porque resulta que ó no es lo mismo que ò pero el sistema los trata igual. Es un poco como el intento de censurar palabras malsonantes en este foro, la palabra ***** esta censurada (te pone las * cuando lo publicas) pero la palabra m.ierda o mierda o mierda no  :laugh:


No se, ya nadie da soporte para IE9.. es un poco absurdo hoy en dia. Nosotros por ejemplo solo damos soporte para las 2 últimas versiones de cada navegador (IE10, IE11). Es una versión que tiene ya 8 años y no es tan vital como IE8. Es decir, si tienes IE 9, no hay ninguna razón para que no tengas IE 10 o IE 11. IE 8 en cambio es un poco más vital en ese sentido porque fue la última versión de IE con soporte para XP. Pero vamos, estamos hablando de navegadores que llevan AÑOS sin actualizarse y con estándares obsoletos cuanto menos.

Saludos

. Tú cuando haces un formulario de contacto guardas los datos en una base???
Porque yo los voy a enviar a un correo directamente, con la funcion MAIL.

. Entonces con mi expresion regular sería solo cuestion de aumentarles los caracteres permitidos al correo..
Y tienes razon, creo que puedo meter mas condiciones en el regexp, como por ejemplo la de limite de longitud (y todas las que pueda) y asi  ahorrame codigo

. SI no voy a enviar los datos a una base , y por ende no voy a poder usar las sentencias preparadas ¿entonces esta bien que siga con HTMLSPECIALCHARS?...Aunque francamente no entiendo por que debo repetir la limpieza de datos, ya que mis expresiones regulares de por si ya evitan que se ingresen caracteres extraños ¿acaso las expresiones regulares no son 100% seguras? Digo, para que usar htmlspecialchars y addslashes , si mi expresion ya restringe todo eso...siento que es redundante

. Bueno pero al menos dime los caracteres que debo evitar, no para hacer una lista negra, sino para yo saberlo

. Es verdad que ya casi nadie da soporte a IE9,10 desde que aparecio Edge, aunque igual debe haber gente que aun lo tenga , y bueno no me quiero arriesgar, tampoco es que IE9 Y 10 sean muy antiguos.....en cambio i8 ese si ya fue...yo tengo ese trauma de que por ejemplo alguna vez algun viejito me pida ver mi pagina, ingrese y se vea toda desconfigurada

. En conclusion y para finalizar, para hacer un formulario seguro ¿debo cuidar que no ingresen sentencias en la url y en los campos de inputs?
Yo quiero que me digas en terminos simples cual debe ser mi objetivo para hacer el formulario seguro, que lo digas directamente, para yo asi ingeniarmelas ...porque si solo sigo unos pasos que me dicen pero si saber para que sirven exactamente entonces nunca voy a ser bueno en esto de la seguridad, porque solo estaria repitiendo lo que otros hacen sin saber su verdadera finalidad...
Quiero que me digas por ejemplo "mira, solo debes evitar que en los inputs pongan este signo '>>>'".. ..entonces yo ya sabria cual es mi meta y simplemente invertiria tiempo en mi ingenio

Gracias