Estoy escribiendo un script PHP que toma información de un formulario HTML5, incluidas las cargas, y los envía por correo electrónico a un administrador utilizando el cliente de correo de Magento. Creo que he cubierto los conceptos básicos bastante bien, pero estoy seguro de que me estoy perdiendo algunas vulnerabilidades potenciales ya que no soy un experto en seguridad.
A partir de este momento, los datos irán directamente al correo electrónico con la excepción de los archivos temporales de las subidas de HTML5. No se está enviando a una base de datos, así que estoy validando la extensión del archivo, el tamaño del archivo, el número de archivo, la longitud de la cadena para otras entradas y el uso de la función htmlspecialchars()
de PHP para evitar la inyección de HTML.
¿Alguien puede señalar algunas cosas que podría estar pasando por alto aquí?
<?php
$maxfilesize = 1000;
$maxStringLength = 50;
if(isset($_POST['submit'])){
$drivers_license = $_FILES['drivers-license'];
$cfi_cert = $_FILES['cfi-cert'];
$cfi_multiple = false;
if(count($_FILES['cfi-cert']['name']) > 1){
if(count($_FILES['cfi-cert']['name']) > 2){
die('Invalid input')
}
$cfi_multiple = true;
$cfi_cert1['name'] = $_FILES['cfi-cert']['name'][0];
$cfi_cert1['type'] = $_FILES['cfi-cert']['type'][0];
$cfi_cert1['tmp_name'] = $_FILES['cfi-cert']['tmp_name'][0];
$cfi_cert1['error'] = $_FILES['cfi-cert']['error'][0];
$cfi_cert1['size'] = $_FILES['cfi-cert']['size'][0];
$cfi_cert2['name'] = $_FILES['cfi-cert']['name'][1];
$cfi_cert2['type'] = $_FILES['cfi-cert']['type'][1];
$cfi_cert2['tmp_name'] = $_FILES['cfi-cert']['tmp_name'][1];
$cfi_cert2['error'] = $_FILES['cfi-cert']['error'][1];
$cfi_cert2['size'] = $_FILES['cfi-cert']['size'][1];
}
//Remove special characters from text inputs
$ftn = htmlspecialchars($_POST['ftn']);
$phone = htmlspecialchars($_POST['phone']);
$email = htmlspecialchars($_POST['email']);
if(strlen($email) > $maxStringLength || strlen($phone) > $maxStringLength || strlen($ftn) > $maxStringLength){
die('Invalid input');
}
//Build attachments array, calling image validation function for each
$attachments = array();
imageValidationErrorCheck($drivers_license, $maxfilesize);
$attachments[] = $drivers_license;
if($cfi_multiple){
imageValidationErrorCheck($cfi_cert1, $maxfilesize);
$attachments[] = $cfi_cert1;
imageValidationErrorCheck($cfi_cert2, $maxfilesize);
$attachments[] = $cfi_cert2;
} else {
imageValidationErrorCheck($cfi_cert, $maxfilesize);
$attachments[] = $cfi_cert;
}
//Use Magento's email client
$mageFilename = '../app/Mage.php';
require_once($mageFilename);
Mage::app();
$mailTemplate = Mage::getModel('core/email_template');
$mailTemplate->setSenderName('Test Sender');
$mailTemplate->setSenderEmail('[email protected]');
$mailTemplate->setTemplateSubject('Processing');
$output .= "Email Address:<br>";
$output .= $email . "<br><br>";
$output .= "Phone Number:<br>";
$output .= $phone . "<br><br>";
$output .= "FTN:<br>";
$output .= $ftn . "<br><br>";
$mailTemplate->setTemplateText($output);
foreach($attachments as $attachment){
$mailTemplate->getMail()->createAttachment(
file_get_contents($attachment['tmp_name']),
Zend_Mime::TYPE_OCTETSTREAM,
Zend_Mime::DISPOSITION_ATTACHMENT,
Zend_Mime::ENCODING_BASE64,
$attachment['name']
);
}
$mailTemplate->send('[email protected]');
}
//Validate images
function imageValidationErrorCheck($file, $maxSizeKb){
$error = '';
$baseName = basename($file['name']);
$type = substr($baseName, strrpos($baseName, '.') + 1);
$sizeInKb = $file['size'] / 1024;
//Limit size to max file size
if($sizeInKb > $maxSizeKb){
die('Invalid input');
}
//Check file extension
$allowedExtensions = array("jpg", "jpeg", "gif", "bmp", "png", "tiff", "pdf", "doc", "docx");
if(!in_array(strtolower($type), $allowedExtensions)){
die('Invalid input');
}
}
?>