Picture of Joan Galtés
Joan Galtés
Desenvolupador Full-Stack, estusiasta de la programació basada en el núvol i polivalent en desenvolupaments de back-end i front-end. Especialista en PHP, MVC, MySQL, HTML5, CSS3, usabilitat i disseny web responsive.
Publicat el 12 de març de 2018

Com establir correctament els permisos de fitxers i carpetes a un lloc web desenvolupat amb Drupal?

En aquest article aprendrem els trets bàsics de la protecció de fitxers i carpetes en sistemes UNIX i com aplicar-ho a un lloc web basat en Drupal.

Moltes vegades us haureu preguntat com s'ho fan els hackers per vulnerar les mesures de seguretat d'un lloc web i ficar-se a dins per dur a terme els seus malintencionats propòsits.

El cert és que de vegades s'ho posem massa fàcil. Bé per implementar un codi poc consistent, amb escletxes de seguretat per on poden explotar les seves habilitats, o bé per no tenir actualitzada a la darrera versió el codi de la nostra plataforma. Però moltes vegades, aquestes coses passen simplement per no establir un mínim nivell de protecció a nivell d'arxius i carpetes. Dit d'una altra manera: establir qui pot què i qui no pot fer-ho.

Val a dir que tot això està molt relacionat amb entorns Unix i derivats, com ara Linux, que és on s'executen la gran majoria del llocs webs a internet. No és l'objectiu d'aquest article explicar en detall com funcionen aquests sistemes operatius, però sí que farem una breu explicació de com funciona el seu sistema de permisos.

A Linux, el nivell de permisos d'un fitxer o carpeta està caracteritzat dos categories: grups d'usuaris i accions. Pel que fa al primer, cal destacar que existeixen 3 grups d’usuari: User (el propietari del fitxer o carpeta), Group que correspondria a un conjunt d’usuaris que tenen certs privilegis com a membres del lloc web, i finalment World, que són la resta d’usuaris aliens al sistema. D’altra banda, pel que fa a les accions, són ben senzilles: lectura, escriptura i execució.

En base a tot això, és evident que no sembla una bona idea que un usuari qualsevol, aliè al nostre lloc web, tingui permisos d'escriptura (capacitat de modificar el contingut de fitxers o carpetes) o d'execució en certs arxius crítics del sistema, com pot ser l'arxiu que conté les credencials de la nostra base de dades. En plataformes complexes com Drupal, amb milers i milers d'arxius i centenars de carpetes, la tasca de comprovar, un per un, si tot és correcte a nivell de permisos pot arribar a ser una tasca titànica. És cert que existeixen certes recomanacions, com establir un nivell de permisos "775" a totes les carpetes, i un nivell de permisos "664" a tots els fitxers, però, com dèiem abans, Drupal és un plataforma complexa i requereix un tractament més específic segons quin sigui l'arxiu o carpeta en qüestió.

És per això que semblaria força interessant disposar d'un script automatitzés tot això i establís el permisos adients a tots el fitxers i carpetes del nostre lloc web. I és això, ni menys ni menys, el que us deixem a sota d’aquestes línies: un petit script, escrit en bash, que es pot executar còmodament des de la nostra terminal per assegurar-nos un correcte nivell de protecció del nostre lloc web.

Esperem que aquest codi, específic per a Drupal 7, us sigui de molta utilitat. Si voleu informació detallada de com funciona aquest script podeu consultar-la a la pàgina de drupal.org: Securing file permissions and ownership.

#!/bin/bash
# Help menu
print_help() {
cat <<-HELP
This script is used to fix permissions of a Drupal installation
you need to provide the following arguments:
1) Path to your Drupal installation.
2) Username of the user that you want to give files/directories ownership.
3) HTTPD group name (defaults to www-data for Apache).
Usage: (sudo) bash ${0##*/} --drupal_path=PATH --drupal_user=USER --httpd_group=GROUP
Example: (sudo) bash ${0##*/} --drupal_path=/usr/local/apache2/htdocs --drupal_user=john --httpd_group=www-data
HELP
exit 0
}
if [ $(id -u) != 0 ]; then
printf "**************************************\n"
printf "* Error: You must run this with sudo or root*\n"
printf "**************************************\n"
print_help
exit 1
fi
drupal_path=${1%/}
drupal_user=${2}
httpd_group="${3:-www-data}"
# Parse Command Line Arguments
while [ "$#" -gt 0 ]; do
case "$1" in
--drupal_path=*)
drupal_path="${1#*=}"
;;
--drupal_user=*)
drupal_user="${1#*=}"
;;
--httpd_group=*)
httpd_group="${1#*=}"
;;
--help) print_help;;
*)
printf "***********************************************************\n"
printf "* Error: Invalid argument, run --help for valid arguments. *\n"
printf "***********************************************************\n"
exit 1
esac
shift
done
if [ -z "${drupal_path}" ] || [ ! -d "${drupal_path}/sites" ] || [ ! -f "${drupal_path}/core/modules/system/system.module" ] && [ ! -f "${drupal_path}/modules/system/system.module" ]; then
printf "*********************************************\n"
printf "* Error: Please provide a valid Drupal path. *\n"
printf "*********************************************\n"
print_help
exit 1
fi
if [ -z "${drupal_user}" ] || [[ $(id -un "${drupal_user}" 2> /dev/null) != "${drupal_user}" ]]; then
printf "*************************************\n"
printf "* Error: Please provide a valid user. *\n"
printf "*************************************\n"
print_help
exit 1
fi
cd $drupal_path
printf "Changing ownership of all contents of "${drupal_path}":\n user => "${drupal_user}" \t group => "${httpd_group}"\n"
chown -R ${drupal_user}:${httpd_group} .
printf "Changing permissions of all directories inside "${drupal_path}" to "rwxr-x---"...\n"
find . -type d -exec chmod u=rwx,g=rx,o= '{}' \;
printf "Changing permissions of all files inside "${drupal_path}" to "rw-r-----"...\n"
find . -type f -exec chmod u=rw,g=r,o= '{}' \;
printf "Changing permissions of "files" directories in "${drupal_path}/sites" to "rwxrwx---"...\n"
cd sites
find . -type d -name files -exec chmod ug=rwx,o= '{}' \;
printf "Changing permissions of all files inside all "files" directories in "${drupal_path}/sites" to "rw-rw----"...\n"
printf "Changing permissions of all directories inside all "files" directories in "${drupal_path}/sites" to "rwxrwx---"...\n"
for x in ./*/files; do
find ${x} -type d -exec chmod ug=rwx,o= '{}' \;
find ${x} -type f -exec chmod ug=rw,o= '{}' \;
done
echo "Done setting proper permissions on files and directories"

Deixa'ns els teus comentaris