Está en la página 1de 16

Capítulo 2

CC51T – Desarrollo de Aplicaciones web

PHP: Archivos - Seguridad

José Urzúa Reinoso http://jose.cl


Archivos por POST

• Permite cargar archivos de texto y binarios


CC51T – Desarrollo de Aplicaciones web

• PHP puede recibir cargas de archivos de


cualquier navegador compatible con RFC 1867
– “Form-based File Upload in HTML”
• Se debe asegurar que el formulario tenga el
atributo:
– enctype="multipart/form-data"

José Urzúa Reinoso http://jose.cl


Archivos

• Formulario para carga


CC51T – Desarrollo de Aplicaciones web

<!-- El tipo de codificación de datos, enctype, se DEBE especificar como a


continuación →

<form enctype="multipart/form-data" action="__URL__" method="POST">


<!-- MAX_FILE_SIZE debe preceder el campo de entrada de archivo -->
<input type="hidden" name="MAX_FILE_SIZE" value="30000" />

<!-- El nombre del elemento de entrada determina el nombre en el array


$_FILES -->
Enviar este archivo: <input name="userfile" type="file" />
<input type="submit" value="Send File" />

</form>

José Urzúa Reinoso http://jose.cl


Archivos

• $_FILES
CC51T – Desarrollo de Aplicaciones web

– $_FILES['userfile']['name']
• El nombre original del archivo en la máquina cliente.
– $_FILES['userfile']['type']
• El tipo mime del archivo, si el navegador proporciona esta
información. Un ejemplo podría ser "image/gif". Este tipo
mime no se verifica en el lado de PHP y por lo tanto no se
garantiza su valor.
– $_FILES['userfile']['size']
• El tamaño, en bytes, del archivo subido
– $_FILES['userfile']['tmp_name']
• El nombre temporal del archivo en el cual se almacena el
archivo cargado en el servidor

José Urzúa Reinoso http://jose.cl


Archivos

• $_FILES
CC51T – Desarrollo de Aplicaciones web

– $_FILES['userfile']['error']
• El código de error asociado a esta carga de archivo.
Agregado en PHP 4.2.0
• Si no se indica otro lugar, los archivos se
almacenan en el directorio temporal del servidor
• El archivo será borrado del directorio temporal al
final de la solicitud si no se ha movido o
renombrado.

José Urzúa Reinoso http://jose.cl


Archivos
CC51T – Desarrollo de Aplicaciones web

<?php

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "El archivo es válido y fue cargado exitosamente.\n";
} else {
echo "¡Posible ataque de carga de archivos!\n";
}

echo 'Aquí hay más información:';


print_r($_FILES);

print "</pre>";

?>

José Urzúa Reinoso http://jose.cl


Archivos

• Validaciones
CC51T – Desarrollo de Aplicaciones web

– Revisar $_FILES['userfile']['size'] para


aceptar/rechazar de acuerdo a tamaño de archivo
– Se puede revisar $_FILES['userfile']['type'] para
aceptar/rechazar archivos de algún tipo
• Este valor esta bajo control del cliente
– Revisar $_FILES['userfile']['error'] y decidir que hacer
de acuerdo a los códigos de error:
• http://www.php.net/manual/es/features.file-upload.errors.php

– Ejemplos: archivo.php archivos.php

José Urzúa Reinoso http://jose.cl


Archivos

• Dificultades:
CC51T – Desarrollo de Aplicaciones web

– MAX_FILE_SIZE no puede ser más grande que


upload_max_filesize de php.ini
– Revisar en php.ini:
• memory_limit, max_execution_time, max_input_time,
post_max_size, max_file_uploads
– No se garantiza que archivos con nombres exóticos
se manejen adecuadamente
• Cuidado con nombres de archivos con espacios en blanco

José Urzúa Reinoso http://jose.cl


Seguridad

• Sistema de archivos
CC51T – Desarrollo de Aplicaciones web

<?php
// remove a file from the user's home directory
$username = $_POST['user_submitted_name'];
$userfile = $_POST['user_submitted_filename'];
$homedir = "/home/$username";

unlink("$homedir/$userfile");

echo "The file has been deleted!";


?>

José Urzúa Reinoso http://jose.cl


Seguridad

• Inyección de SQL
CC51T – Desarrollo de Aplicaciones web

<?php

$offset = $_GET['offset']; // Cuidado, no hay validación en la entrada de datos!


$query = "SELECT id, name FROM products ORDER BY name LIMIT 20
OFFSET $offset;";
$result = pg_query($conn, $query);
?>

0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
select 'crack', usesysid, 't','t','crack'
from pg_shadow where usename='postgres';
--

José Urzúa Reinoso http://jose.cl


Seguridad

• Inyección de SQL
CC51T – Desarrollo de Aplicaciones web

<?php

$query = "SELECT id, name, inserted, size FROM products


WHERE size = '$size'";
$result = odbc_exec($conn, $query);

?>

'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0'
from usertable;
--

José Urzúa Reinoso http://jose.cl


Seguridad

• Consejos
CC51T – Desarrollo de Aplicaciones web

– Nunca se conecte como super usuario o como el


propietario de la base de datos
• utilice usuarios personalizados con privilegios muy limitados
– Use sentencias preparadas con variables asociadas

José Urzúa Reinoso http://jose.cl


Seguridad
CC51T – Desarrollo de Aplicaciones web

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES
(:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);

// insertar una fila


$name = 'one';
$value = 1;
$stmt->execute();

// insertar otra fila con diferentes valores


$name = 'two';
$value = 2;
$stmt->execute();
?>

José Urzúa Reinoso http://jose.cl


Seguridad
CC51T – Desarrollo de Aplicaciones web

Imagen obtenida desde: http://xkcd.com/327

José Urzúa Reinoso http://jose.cl


Seguridad

• Consejos
CC51T – Desarrollo de Aplicaciones web

– Revise si la entrada proporcionada tiene el tipo de


datos que se espera
• PHP provee varias funciones de validación de tipo de datos
– Si se espera una entrada numérica:
• verificar los datos con la función ctype_digit()
• o silenciosamente cambie su tipo utilizando settype()
• o use su representación numérica por medio de sprintf()

José Urzúa Reinoso http://jose.cl


Seguridad
CC51T – Desarrollo de Aplicaciones web

<?php

settype($offset, 'integer');
$query = "SELECT id, name FROM products ORDER BY name
LIMIT 20 OFFSET $offset;";

// Fíjese en %d en el formato de cadena, utilizar %s podría no


tener un resultado significativo
$query = sprintf("SELECT id, name FROM products ORDER BY
name LIMIT 20 OFFSET %d;",
$offset);

?>

José Urzúa Reinoso http://jose.cl

También podría gustarte