Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Gobierno de Aragón
Especificaciones técnicas para el
alojamiento de aplicaciones
Referencia: AST-ESPEC-
EspecificacionesTecnicasLAMP2016.doc
Autor: Aragonesa de Servicios Telemáticos
Fecha de creación: 08/08/2016
Última actualización: 09/11/2016
Versión: v1.0
Contenido
1. INTRODUCCIÓN ................................................................................................................................. 5
3. ESTRUCTURA DE UN PROYECTO................................................................................................... 8
3.1. DIRECTORIOS GENERALES COMUNES A TODOS LOS TIPOS DE PROYECTO .................. 8
3.1.1. Directorio docs/.......................................................................................................................... 8
3.1.2. Directorio src/ ............................................................................................................................ 8
3.1.2.1. Directorio php/ ....................................................................................................................... 9
3.1.2.2. Directorio conf/ ...................................................................................................................... 9
3.1.3. Directorio setup/ ........................................................................................................................ 9
3.1.3.1. Manual de instalación............................................................................................................ 9
3.1.3.2. Scripts de BBDD ................................................................................................................. 10
3.1.4. Ficheros estáticos y temporales .............................................................................................. 11
1. Introducción
El presente documento define las especificaciones técnicas a seguir por toda aplicación que se
despliegue en la arquitectura LAMP del Gobierno de Aragón.
Parte I: Arquitectura. Breve descripción de todos los componentes que forman parte
de la arquitectura del sistema, balanceo, servidor de aplicaciones, capa de datos,..
Parte II: Estructura de un proyecto. Estructura organizativa que deben cumplir los
desarrollos LAMP.
Parte III: Especificaciones del entorno. Configuración del entorno de servidores del
Gobierno de Aragón.
El documento va complementado con varios anexos con información más específica a modo de
complemento.
Existen 3 entornos disponibles en los que se instalarán las aplicaciones de forma secuencial:
La arquitectura tecnológica del Gobierno de Aragón está organizada en base a una estructura de
3 capas (frontales web, capa media y capa de base de datos).
La siguiente tabla muestra la relación de los productos instalados divididos por capa en el entorno
de producción:
Componente
Descripción Máquina Sistema operativo Descripción detallada
(arquitectura)
Capa frontal Apache 2.2 fov-apache-01, fov- Red Hat Enterprise Linux 6.4 Apache Web Server con
apache-02 (x86_64) ProxyPass
Capa media Apache 2.4.6 mov-lamp2016-01 Red Hat Enterprise Linux Apache web server con PHP
Server release 7.2 (Maipo) 5.4.16 como módulo
Capa back MariaDB 5.5.47 bov-lamp2016-01 Red Hat Enterprise Linux Servidor MariaDB, puerto
Server release 7.2 (Maipo) 3306
3. Estructura de un proyecto
Todo proyecto que se entregue para ser desplegado en los servidores del Gobierno de Aragón
debe tener una estructura determinada y cumplir con una serie de especificaciones que se detalla
a continuación.
Directorio Contenido
setup/ Este directorio contiene ficheros relacionados con la instalación del sistema, por ejemplo, manual de
instalación, ficheros de creación de la base de datos, etc.
Contiene los fuentes de la aplicación web. Los ficheros ubicados en esta carpeta serán
copiados a la carpeta document root del virtual host de apache en los distintos entornos.
Salvo parámetros que el proveedor desconoce y no pueden ser facilitados, como pueden ser
accesos o contraseñas a distintas URLs de la DGA, todos los demás parámetros deben ser
informados correctamente en cada fichero según el entorno para el que estén definidos.
Estos ficheros se deberán entregar por triplicado, uno por cada uno de los entornos de ejecución
de las aplicaciones (integración, preproducción, producción), de forma que el proveedor entregue
la aplicación una única vez por versión. Desde despliegue, a medida que la aplicación vaya
pasando por los distintos entornos, se ajustarán los parámetros de acuerdo con este y se copiarán
el/los fichero/s dentro de su ruta en src/php (ruta especificada en el manual de instalación).
NOTA: una misma entrega parametrizable se utilizará para el paso de la aplicación por los tres
entornos. En ningún caso se aceptarán para una misma versión entregas diferentes o con alguna
corrección para preproducción o producción.
Cualquier cambio en ficheros que no tenga que ver con la parametrización deberá generar una
nueva versión y, por consiguiente, una nueva entrega.
NOTA: en todas las entregas se deberá incluir un manual con las instrucciones de ejecución de los
scripts, así como las posibles acciones en caso de errores (continuar la ejecución o no, ejecutar
scripts de borrado o regresión, etc...).
Creación de tablas
Creación de índices
Creación de vistas
Creación de triggers
Otros
NOTA: no se deben incluir scripts para la creación de usuarios. Para tal fin existen formularios de
solicitud de usuarios/bases de datos.
NOTA: siempre que sea necesario actualizar estos ficheros, deberá indicarse en el Manual de
Instalación de la versión correspondiente.
Entorno Máquinas
Integración fiv-apache-01.aragon.local
Preproducción fev-apache-01.aragon.local, fev-apache-02.aragon.local
Producción fov-apache-01.aragon.local, fov-apache-02.aragon.local
Entorno Máquina
Integración miv-lamp2016-01.aragon.local
Preproducción mev-lamp2016-01.aragon.local
Producción mov-lamp2016-01.aragon.local
Los subdominios DNS están definidos de forma que las URLs de las aplicaciones sean las
siguientes, dependiendo si se debe habilitar o no el acceso por protocolo seguro:
Entorno APACHE
Integración http://desaplicaciones.aragon.es/[app] https://desaplicaciones.aragon.es/[app]
Preproducción http://preaplicaciones.aragon.es/[app] https://preaplicaciones.aragon.es/[app]
Producción http://aplicaciones.aragon.es/[app] https://aplicaciones.aragon.es/[app]
En caso de necesitar una URL diferente debe contactar con Aragonesa de Servicios Telemáticos.
NOTA: el valor del puerto nunca debe ir ‘hardcodeado’ en la aplicación, debe incluirse como
parámetro dentro de un fichero de configuración.
Entorno Máquina
Integración biv-lamp2016-01.aragon.local
Preproducción bev-lamp2016-01.aragon.local
Producción bov-lamp2016-01.aragon.local
VARIABLE VALOR
open_files_limit 2500
max_connections 500
innodb_buffer_pool_size 8388608
key_buffer_size 8384512
max_connections 500
tmp_table_size 33554432
have_innodb YES
innodb_data_file_path ibdata1:10M:autoextend
user=mysql
old_passwords=1
lower_case_table_names=1
character-set-server=utf8
collation-server=utf8_general_ci
skip-character-set-client-handshake
port=3306
log_slow_queries = slow-queries.log
open_files_limit=2500
max_connections=500
tmp_table_size=33554432
5. Especificaciones de desarrollo
Previamente al desarrollo de una nueva aplicación deberá asegurarse de que se está en posesión
de la última versión disponible del documento de especificaciones.
NOTA: si su aplicación requiere de una extensión que no está instalada en el servidor, debe
ponerse en contacto con AST antes de solicitar el despliegue de la misma. Tenga en cuenta que
es posible que no se autorice dicha extensión, lo que implicaría trabajo adicional en el desarrollo.
Se recomienda el uso de las extensiones instaladas exclusivamente.
Directorio html, corresponde al “document root” del virtual host asociado al sitio. A
este directorio se copiará el contenido de src/php del entregable.
5.6. Interoperabilidad
Para la realización de webservices, deberán cumplirse las especificaciones marcadas en el
documento “AST-ESPEC-InteroperabilidadTecnicaWS.pdf”.
5.7. Logs
Para cada aplicación, el servidor generará por defecto estos ficheros de log en la ruta app/logs/:
access.log, error.log, ssl_access.log, ssl_errorlog y php.log. Si la aplicación necesita generar logs
adicionales, deberá utilizar un sistema de log que escriba en esta ruta. La rotación de logs es
diaria, de esta forma se tendrá un histórico del log almacenado por día, lo que facilita su consulta
y envío al proveedor en caso de ser solicitados.
NOTA: si la aplicación necesita generar logs específicos, al margen de los generados por defecto,
debe indicarlo en el manual de instalación.
NOTA: La utilización de estas plataformas deberá solicitarse previamente a AST a través del gestor
de la aplicación e indicarse claramente en el Manual de Instalación de la aplicación.
La aplicación utilizará por lo general un usuario para conectarse a la base de datos. Este tendrá
asignados una serie de privilegios en función de las necesidades de la aplicación. Será
nombrado con el código de aplicación seguido de “USER” (APP_USER).
Deberá indicarse en el manual de instalación el/los usuarios a crear y los privilegios asociados a
los mismos. El grupo de despliegue se encargará de gestionar la creación de dichos usuarios.
6. Obligaciones y recomendaciones
6.1. Codificación
Se deben tener en cuenta los fundamentos indicados por PHP para su codificación cumpliéndose
obligatoriamente al menos los indicados en el apartado “Verificaciones SonarQube” incluidas en
este documento.
El Framework Interop Group (antes conocido como el ‘PHP Standards Group’) ha propuesto y
aprobado una serie de recomendaciones de estilo conocidas como PSR-0, PSR-1, PSR-2 y PSR-
4.
Se recomienda escribir código PHP que se adhiera a uno o más de estos estándares. Puede ser
cualquier combinación de PSR, o uno de los estándares de codificación hechos por PEAR o Zend.
Para verificar que el código construido cumple estas recomendaciones puede utilizarse
PHP_CodeSniffer y para obtener un análisis en tiempo real pueden usarse plugins para editores
de texto como Sublime Text.
Para modificar la sintaxis de código automáticamente y que quede conforme a estos estándares
puede utilizarse:
Se prefiere la utilización del inglés para los nombres de símbolos e infraestructura del código.
6.1.2. Estilo
6.1.2.1. Indentación
La terminación de la línea sigue la convención del archivo UNIX. Las líneas deben finalizar con un
salto de línea única (LF).
No se deben utilizar atajos-uso abreviado de tags. SI los ficheros solo contienen código PHP la
etiqueta de cierre puede ser omitida. El código siempre debe comenzar delimitado por las
etiquetas PHP como en el ejemplo siguiente;
<?php
?>
$a = 'Example String';
Cadena que incluye diferentes apóstrofes: debe de marcarse con comillas dobles.
Un array con un índice debe de comenzar situando el mismo a 0. No está permitido utilizar
números negativos. Cuando el array se declara utilizando el constructor, se debe dejar un espacio
tras cada delimitador para mejorar la legibilidad:
También está permitido declarar arrays inicializados mediante el constructor. En este caso, cada
línea sucesiva debe alinearse con la superior de la siguiente manera:
$sampleArray = array(
1, 2, 3, "ispCP",
$a, $b, $c,
56.44, $d, 500
);
Las funciones deben invocarse sin espacios entre el nombre de la función, el paréntesis de
apertura y el primer parámetro. Después deben situarse comas entre cada parámetro y no
existir espacios entre el último parámetro, el último paréntesis y el punto y coma final.
<?php
$var = foo($bar, $baz, $quux);
?>
Esto incluye a las instrucciones de tipo if, for, while, switch. Las instrucciones de control deben
tener un espacio entre la palabra reservada del control y el paréntesis. De esta manera se
distinguen de las llamadas a funciones. Un ejemplo de una instrucción if es la siguiente:
<?php
if ((condition1) || (condition2)) {
action1;
} elseif ((condition3) && (condition4)) {
action2;
} else {
defaultaction;
}
?>
6.1.3. Nomenclatura
6.1.3.1. Clases
Los nombres de clases sólo pueden contener caracteres alfanuméricos. Se desaconseja el uso
de números dentro de la nomenclatura de clases.
Si se utiliza más de una palabra para el nombre de una clase, es necesario poner en mayúscula la
primera letra de cada palabra. El resto de las letras no pueden indicarse en mayúsculas.
En general, las clases abstractas siguen las mismas consideraciones que las clases, pero con una
regla adicional: deben terminar con la palabra "Abstract". Este sufijo no puede ir precedido de
guión bajo.
6.1.3.3. Interfaces
Las interfaces siguen la misma convención que las clases con la única regla adicional que deben
finalizar con la palabra "Interface". Este sufijo no puede ir precedido de guión bajo.
Para todos los ficheros, sólo los caracteres alfanuméricos, guiones bajos y el guión normal están
permitidos. Los espacios están estrictamente prohibidos. Todos los ficheros que contienen
código PHP terminan con la extensión ".php", con la excepción de la vista de los scripts.
Los nombres de las funciones sólo pueden contener caracteres alfanuméricos. Los guiones
bajos no están permitidos y el uso de los números es desaconsejable. Las funciones siempre
comienzan en minúsculas. Si una función tiene más de una palabra, cada palabra a excepción de
la primera debe de comenzar en mayúsculas. Es recomendable dar un nombre a la función que
describa su funcionalidad y su comportamiento
// Ejemplos de funciones
filtradoEntrada()
getElementoPorId()
En la programación orientada a objetos, los métodos que acceden a los objetos deben ser
siempre prefijados por "get" o "set". Cuando se usan patrones de diseño, tales como singleton
o factory, el nombre del método debería contener el nombre del patrón para facilitar la lectura del
código.
Las funciones de ámbito global están permitidas, pero se desaconseja su uso. Se recomienda que
estas funciones se encapsulen en clases estáticas.
6.1.3.6. Variables
Los nombres de las variables solo pueden contener caracteres alfanuméricos. Los guiones
bajos no están permitidos y el uso de los números es desaconsejable.
Para las variables que son declaradas con el modificador "private" o "protected", el primer carácter
debe de ser un simple guion bajo. Las variables declaradas como públicas nunca comenzarán con
guion bajo. Las variables siempre comenzarán con una letra en minúscula y seguir la convención
de mayúsculas "camelCaps".
Se recomienda que los nombres de las variables sean tan descriptivos como sea posible, para
facilitar el entendimiento del código. Los nombres de variables como "$i" y "$j" están
desaconsejados para otro contexto que no sean bucles sencillos. Si un bucle contiene más de 20
líneas de código, los nombres de las variables índices, deben tener nombres más descriptivos
6.1.3.7. Constantes
Los nombres de las constantes sólo pueden contener caracteres alfanuméricos. Si el nombre de
la constante está compuesto por varias palabras, éstas deben de ir separadas por guion bajo (_).
Se permite el uso de números pero se desaconseja su uso. Todos los caracteres de las
constantes deben ser escritos siempre en mayúsculas.
Las constantes deben ser definidas como miembros de una clase con la palabra clave "const". La
definición de constantes de ámbito global está permitida con "define" pero se desaconseja.
6.1.4. Ficheros
Para revisar los nombres de ficheros se utilizan las funciones realpath() y basename(). La
primera convierte direcciones relativas en absolutas y la segunda toma una ruta y devuelve
la parte correspondiente al nombre del fichero.
NOTA: por securización del entorno -tal y como se refleja en el Anexo “Securización del entorno”-
está desactivada la funcionalidad de acceso a ficheros remotos (allow_url_fopen = off) y definida la
directiva open_basedir.
Debe evitar utilizar el nombre enviado por el navegador (podría ser, por ejemplo,
/etc/passwd). Es conveniente generar un nombre único para el fichero subido.
6.1.4.3. Bibliotecas
Debe almacenar los ficheros de biblioteca fuera de la raíz de la web para evitar que puedan
ser accedidos por su URL e indicar a PHP la ubicación de esos ficheros indicando la ruta
completa en los include() y require() o mediante la directiva include_path en php.ini
include_path = “.:/usr/local/php:/usr/local/lib/myapp”
Existen gran cantidad de librerías, frameworks y componentes de PHP que pueden ser utilizados
en los proyectos: dependencias de proyecto.
Actualmente hay dos sistemas principales de gestión de paquetes para PHP: Composer y PEAR.
El uso recomendado es el siguiente:
Solo hay que añadir las dependencias de su proyecto a un archivo llamado composer.json,
ejecutar algunos comandos y Composer descargará automáticamente las dependencias para su
proyecto y configurará el cargador automático en cuestión de segundos.
Ya existen muchas librerías PHP compatibles con Composer y están listas para su uso. Hay una
lista de estos “paquetes” en el sitio Packagist, que es el repositorio oficial de librerías compatibles
con Composer.
A tener en cuenta:
2.- Revisar las dependencias por actualizaciones de seguridad mediante Security Advisories
Checker
6.1.5.2. PEAR
Se han automatizado verificaciones para garantizar la calidad software del proyecto que va a
entregar utilizando la herramienta SonarQube. Debe realizar verificaciones para subsanar los
problemas que se detecten. Existen para SonarQube plugins como pmd, checkstyles, findbugs…
Para usar estas primeras verificaciones puede descargar el perfil del proyecto SonarQube en la
intranet de AST: http://ast.aragon.es.
6.1.6.1. Crítica
Esta función hace que la aplicación sea más vulnerable a los ataques DoS (denegación del
servicio).
if (is_bad_ip($requester)) {
sleep(5); // Noncompliant
}
No hardcodear credenciales
Deben ser almacenadas fuera del código encriptadas en un fichero de configuración o en BBDD.
$uname = getEncryptedUser();
$password = getEncryptedPass();
connect($uname, $password);
A partir de PHP 5.4.0 utilizar llamadas con parámetros por referencia causará un error fatal.
myfun($name);
switch ($myVariable) {
case 0: // Empty case used to specify the same behavior for a
group of cases.
case 1:
do_something();
break;
case 2: // Use of continue statement
continue;
case 3: // Case includes a jump statement (exit, return, break
&etc)
exit(0);
case 4:
echo 'Second case, which falls through';
// no break <- comment is used when fall-through is intentional in a non-
empty case body
default: // For the last case, use of break statement is optional
doSomethingElse();
}
Para evitar resultados inesperados y warnings del tipo “Missing argument 2 in call to
nombreFuncion()”.
En algunas ocasiones se utiliza la función die() en condicionales para realizar un control sobre los
errores. Esto puede suponer graves problemas para la aplicación: en el caso que se produzca el
error no se reportará información del mismo provocando un sensación poco agradable en el
usuario. Es más recomendable utilizar funciones como trigger_error() y en conjunto con
set_error_handler() para manejar los errores de tu aplicación.
class Foo {
public function bar($param) {
if ($param === 42) {
throw new Exception('Value 42 is not expected.');
}
}
}
6.1.6.2. Mayor
En su lugar crear un tipo propio que gestione la excepción o utilizar subtipos que existan en la
librería estándar de PHP.
$name = $this->params()->fromPost('name');
Las sentencias if con condiciones que siempre son false generan bloques de código no
funcionales y las que siempre son true son redundantes. Por ello se debe evitar el uso de
sentencias if sin condiciones.
if (true) { // Noncompliant
doSomething();
}
...
if (false) { // Noncompliant
doSomethingElse();
}
doSomething();
Los bloques de código vacíos deben ser eliminados. Un bloque que contenga comentarios no se
considera vacío.
for ($i = 0; $i < 42; $i++){} // Empty on purpose or missing piece of code ?
Un número excesivo de parámetros indica que pueden resolverse mediante el uso de objetos. No
es recomendable realizar llamadas que involucren a más de 7 parámetros.
No sobrecargar funciones
En vez de añadir líneas se debe extraer a una función. El máximo de líneas permitido es 10.
La condición de parada se establece en una variable local antes de que comience el bucle y no
debe modificarse en el cuerpo.
$i = 20;
}
}
"if ... else if" debe terminar con una sentencia "else"
La última acción debe finalizar siempre con sentencia “else” y no con “else if”.
if (condition1) {
do_something();
} else if (condition2) {
do_something_else();
} else {
throw new InvalidArgumentException('message');
}
switch ($param) {
case 0:
do_something();
break;
case 1:
do_something_else();
break;
default:
error();
break;
}
REPLACE WITH
$HTTP_SERVER_VARS $_SERVER
$HTTP_GET_VARS $_GET
$HTTP_POST_VARS $_POST
$HTTP_POST_FILES $_FILES
$HTTP_SESSION_VARS $_SESSION
$HTTP_ENV_VARS $_ENV
$HTTP_COOKIE_VARS $_COOKIE
Para asegurar que los datos usados en la construcción no han sido manipulados.
6.1.6.3. Menor
No utilizar tabuladores
6.1.6.4. Info
Comprobar que los métodos hacen lo que tienen que hacer y no desarrollan una excesiva
funcionalidad que provoca que su mantenimiento sea complejo. No es recomendable crear
métodos con más de 100 líneas de código.
El siguiente código seguro que funciona, pero el problema es que la función count() que es
ejecutada dentro de la iteración del bucle torna penaliza severamente la velocidad del proceso el
proceso.
<?php
for ($i = 0; $i < count($miArray); $i++)
{
// Código
}
?>
Si calculamos la función fuera del bucle, mejoramos la velocidad en torno a un 600% con
respecto a la función inicial.
Si es posible, hay que declarar los métodos como estáticos si van a ser tratados de esta
manera. Está probado que se reduce su tiempo de ejecución hasta cuatro veces con respecto a
los métodos que no están declarados como estáticos.
Cuando necesite calcular el tiempo actual dentro de la ejecución del algún script dentro de una
aplicación es mucho más eficiente utilizar $_SERVER [ ’REQUEST_TIME’ ] que la función time().
Cuando tenemos una estructura con un bucle destinado a la lectura de un array o una colección
está demostrado que es mucho más rápido utilizar foreach(), preferentemente a estructuras del
tipo while o for.
// Un ejemplo basado en array Hash con 100 elementos, 24 byte para claves y 10k datos
por cada entrada
foreach($aHash as $val) // Tiempo de ejecución + 100 %
while(list(,$val) = each($aHash) // Tiempo de ejecución + 579 %
<?php
if (strpos($authors, 'Chris') !== FALSE) {
echo 'Chris is an author.';
} else {
echo 'Chris is not an author.';
}
?>
Realizar un preincremento como ++$i es más rápido que el postincremento $i++ en las variables,
así que use el preincremento cada vez que sea posible. El preincremento es casi un 10% más
rápido: debe cambiar las instrucciones para que hagan el pre-incremento, sobre todo en los
bucles críticos.
Errores en el código pueden consumir los recursos dedicados, por ello debe revisar la salida que
las páginas producen con el fin de asegurarse de que PHP no está registrando errores.
Existen funciones que aumentan la capacidad de depuración, permitiendo comprobar los scripts
sin necesidad de mostrar datos en HTML. Algunas son SitePoint, Xdebug y Scream.
NOTA: tal y como se refleja en el Anexo “Securización del entorno”, la directiva register_globals
tiene el valor off.
6.2. Documentación
Los bloques de documentación deben ser compatibles con phpDocumentor.
6.2.1. Ficheros
Cada fichero que contenga código PHP debe tener un bloque cabecera al comienzo del fichero
que contenga estos tags de phpDocumentor como mínimo:
/**
* Short description for file
*
* Long description for file (if any)...
*
* LICENSE: Some license information
*
* @copyright 2005 Zend Technologies
* @license http://www.zend.com/license/3_0.txt PHP License 3.0
* @version CVS: $Id:$
* @link http://dev.zend.com/package/PackageName
* @since File available since Release 1.2.0
*/
6.2.2. Clases
Cada clase debe tener un bloque que contenga estos tags de phpDocumentor como mínimo:
/**
* Short description for class
*
* Long description for class (if any)...
*
* @copyright 2005 Zend Technologies
* @license http://www.zend.com/license/3_0.txt PHP License 3.0
* @version Release: @package_version@
* @link http://dev.zend.com/package/PackageName
* @since Class available since Release 1.2.0
* @deprecated Class deprecated in Release 2.0.0
*/
6.2.3. Funciones
Cada función o método, debe tener un bloque de documentación que contenga al menos:
No es necesario el uso del tag @access ya que el nivel de acceso es conocido por las palabras
clave "public", "private", o "protected" usadas para declarar la función.
Si una función o método puede lanzar una excepción debe usarse el tag @throws:
6.3.1. Extensiones
mysqli
pdo
mysql ha sido deprecada en versión PHP 5.5.0 y eliminada en PHP 7.0. Se recomienda la
actualización a cualquiera de esas extensiones incluso aunque no se utilice PHP 7.0 sino versiones
anteriores.
PDO (PHP Data Objects) se incluye desde la versión 5.1.0 de PHP proporcionando un interfaz
común para conectar con diferentes BBDD. Además permite incluir –de forma segura- entradas
externas (p.e. IDs) en las sentencias SQL sin tener que preocuparse de ataques a la BBDD.
No utilizar mysql_real_escape_string
6.4. Caché
Para la mejora del rendimiento se recomienda el uso de diferentes utilidades de caché que
mejoren la carga de las páginas del sitio.
XCache
Importante cuando hay que cachear objetos individuales para almacenarlos en memoria y obtener
un acceso rápido a ellos. Las soluciones más populares son: APCu, memcached, XCache y
WinCache.
Las más utilizadas son APCu y memcached. APCu es mejor para el cache de objetos, su pega es
que se asocia al servidor en que está instalado. Memcached se instala como servicio separado y
puede accederse a través de la red, es más indicado para instalaciones de varios servidores.
6.5. Seguridad
Debe tomar las precauciones necesarias para mejorar la seguridad de los proyectos.
La comunidad del The Open Web Application Security Project (OWASP) ha compilado una lista
completa de problemas de seguridad conocidos y los métodos a seguir para protegerse contra
ellos. Esta guía es lectura obligada para cualquier desarrollador.
Siempre debe sanear y verificar los datos de entrada de la aplicación PHP antes de usarlos en el
código. Las funciones filter_var() y filter_input() proporcionan limpieza de los datos y verifican la
validez del formato del texto (por ejemplo, las direcciones de correo electrónico).
Los datos de entrada exteriores pueden contener cualquier cosa: datos provenientes de
formularios en $_GET y $_POST, algunos valores provenientes del $_SERVER, el cuerpo de la
solicitud HTTP vía la función fopen('php://input', 'r'). Han de ser filtrados de diferente manera
dependiendo de su propósito.
Datos sin filtrar a la salida de HTML: se corre el riesgo de ejecutar código sin verificar de
HTML o JavaScript en el sitio: Cross-Site Scripting (XSS). Para prevenir estos ataques hay
que sanear todas las etiquetas de HTML en los datos de entrada al remover etiquetas o
convirtiéndolas en entidades de HTML. Se puede utilizar strip_tags(), htmlentities() o
htmlspecialchars().
Aceptar la entrada de datos para determinar qué archivo necesita cargar del sistema
de archivos: debe quitar los caracteres “/”, “../”, bytes nulos y otros de la ruta de archivo
para que no permita cargar archivos escondidos, no públicos, o sensitivos.
Las cookies sólo son accesibles a través del protocolo HTTP: está activada la opción
session.cookie_httponly.
Utilizar la opción secure en las cookies de sesión ya que está activada la opción
session.cookie_secure.
if (!isset($_SESSION['timeout_idle'])) {
$_SESSION['timeout_idle'] = time() +
ini_get('session.gc_maxlifetime');
} else {
if ($_SESSION['timeout_idle'] < time()) {
//destroy session
} else {
$_SESSION['timeout_idle'] = time() +
ini_get('session.gc_maxlifetime');
}
}
Establecer un tiempo máximo de validez de sesión: este timeout puede ser establecido
mediante un código similar al anterior, utilizando el parámetro session.cookie_lifetime, etc.
6.5.5. Validación
La validación asegura que lo que contiene la entrada de datos es lo que se espera. Por
ejemplo, se debe validar una dirección de correo electrónico, un número telefónico, o la
edad de un usuario al procesar una solicitud de registro.
Si no hay otra alternativa más que almacenar los archivos de configuración en la raíz de
documentos de su aplicación, se debe adjuntar la extensión .php al nombre de los
archivos. De esta manera, aún si alguien accede a ellos directamente, la información no
será impresa en forma de texto a la pantalla.
La información en los archivos de configuración debe ser protegida ya sea por medio
de codificación o con los permisos de grupo/usuario pertinentes en el sistema de archivos.
Se recomienda aplicar los siguientes valores en el fichero php.ini en función del entorno:
Desarrollo
display_errors = On
display_startup_errors = On
error_reporting = -1 (1)
log_errors = On
(1) El valor -1 mostrará cualquier error independientemente que en versiones posteriores de PHP se añadan nuevas constantes.
Producción
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
Registered PHP Streams => https, ftps, compress.zlib, compress.bzip2, php, file,
glob, data, http, ftp, phar, zip
Registered Stream Socket Transports => tcp, udp, unix, udg, ssl, sslv3, sslv2, tls
Registered Stream Filters => zlib.*, bzip2.*, convert.iconv.*, string.rot13,
string.toupper, string.tolower, string.strip_tags, convert.*, consumed, dechunk
Configuration
bz2
calendar
Core
ctype
curl
date
ereg
exif
fileinfo
filter
ftp
gettext
gmp
hash
iconv
json
libxml
mhash
openssl
pcntl
pcre
Phar
readline
Reflection
Reflection: enabled
Version: $Id: 6c4d8062369898a397e4b128348042f5c01b4427 $
session
shmop
SimpleXML
sockets
SPL
standard
tokenizer
xml
zip
Zip: enabled
Extension Version: $Id: 0c033d4e4613d577409950ed7bf8da4b68286d15 $
Zip version: 1.11.0
Compiled against libzip version: 0.10.1
zlib
Environment
PHP Variables
_SERVER["argc"] => 1
phpinfo,symlink,system,shell_exec,exec,proc_get_status,proc_nice,proc_terminate,defin
e_syslog_variables,syslog,openlog,closelog,escapeshellcmd,passthru,ocinumcols,ini_alt
er,leak,listen,chgrp,apache_note,apache_setenv,debugger_on,debugger_off,ftp_exec,dl,d
ll,ftp,myshellexec,proc_open,socket_bind,proc_close,popen,show_source,curl_exec,curl_
multi_exec,parse_ini_file
Esta directiva limita los archivos que pueden ser abiertos por PHP al árbol de directorios
especificado. Se han habilitado las siguientes opciones:
open_basedir = /var/www/sites/
upload_tmp_dir = /tmp
Deshabilitar register_globals
register_globals = Off
Deshabilitar allow_url_fopen
allow_url_fopen = Off
Versión de PHP
expose_php = Off
TraceEnable Off
Activar session.autostart
session.auto_start = 1
Activar session.cookie_httponly
Para que las cookies sólo estén accesibles a través del protocolo http. Esto implica que
JavaScript no tiene acceso a las cookies de sesión
session.cookie_httponly = 1
Activar session.cookie_secure
session.cookie_secure = 1
_session.name = GAPHPSESSID
El presente documento define un convenio para nominar objetos de base de datos para:
Convenio de Nombres
Reglas.
Todo objeto debe ir precedido del prefijo apl_, donde apl debe sustituirse por el
código de la aplicación a la que pertenece el objeto. Esta regla evita los conflictos
entre nombres de objetos de aplicaciones distintas.
Todo objeto debe incorporar en el nombre el tipo del objeto (p.e. i para índices, pk
para primary keys, etc.). Como excepción a esta regla están las tablas, por ser el
objeto principal de la base de datos. Esta regla evita dedicar tiempo en pensar
nombres distintos para objetos de distinto tipo dentro de la misma aplicación.
Todo objeto debe terminar con una cadena de caracteres que debe definirse
libremente para distinguir los objetos del mismo tipo y aplicación.
Todo objeto que depende jerárquicamente de otro debe ir precedido del nombre
del objeto del depende (p.e. índices sobre tablas. Esta regla da una visión de la
jerarquía de objetos a nivel de nombres y proporciona un método rápido de nombrar
objetos que no son utilizados en sentencias DML.
Convenio de estilos.
La letra cursiva se utiliza para definir cadenas que deben ser sustituidas por
literales definidos previamente.
La letra negrita se utiliza para definir cadenas fijas que deben escribirse
literalmente.
Longitud de nombres.
La longitud total de un nombre de objeto no puede exceder el límite MariaDB Este límite
debe reducirse para el caso de las tablas, ya que el nombre de estas sirve de base para la
definición de otros nombres de objetos dependientes.
Convenio de Nombres
Vistas: OEP_V_ADMITIDOS
Índices: OEP_SOLICITANTES_IX_DNI
OEP_SOLICITANTES_IX_APELLIDOS