Sécuriser son blog WordPress #2

Date: 4/01/2011 | Catégories: Blog,Open-source,Planet-libre,Reseau,Systeme | Tags: ,,,,,

Dans ce deuxième billet, nous allons aborder la pierre angulaire de la sécurisation de votre site/blog: la sécurisation du couple infernal Apache/PHP.

Bien qu'il existe d'autres serveurs Web (par exemple le très rapide NGinx ou le très simple Cherokee), Apache reste, à ce jour, le plus répandu. Un des reproche que l'on peut lui faire est sa lourdeur de configuration. Cette lourdeur et l'utilisation de fonctions pas forcement utiles à votre site peut rapidement entraîner des failles de sécurité. Nous allons donc détailler la sécurisation du serveur Web ainsi que celle du moteur de langage PHP qui est utilisé par WordPress.

Je vous rappelle que cet article est découpé en plusieurs billets (vous êtes en train de lire le #2):

Cette série de billets a été co-écrite avec Jérémie Marguerie étudiant à EPITA (merci à lui !).

Serveur Web Apache

Sécuriser l'installation par défaut d'Apache2

Apache est développé en tenant compte de la sécurité mais dévoile, dans le header HTTP, son identité (son nom et son numéro de version) à chaque client qui se connecte. Ne pas divulguer ces informations permet d’éviter aux scripts kiddies de connaitre directement les failles connues pour la version d’Apache utilisée et peut compliquer le travail des crackers.

Pour cacher ces informations aux clients HTTP, il suffit d'éditer le fichier /etc/apache2/conf.d/security et d'y ajouter/modifier les variables suivantes:

ServerTokens Prod
ServerSignature Off
TraceEnable On

Module de securité IDS pour Apache

Il existe dans Apache un module optionnel nommé ModSecurity2 qui permet de détecter et de protéger son serveur contre des attaques touchant vos applications Web (notamment les "SQL injections", "cross-site scripting", "path traversal attacks"...).

On commence par l'installation de mod-secure:

sudo aptitude install libapache2-mod-security2

Par défaut, aucune règle n'est appliquée. Il faut donc partir du fichier de configuration qui est donné en exemple:

sudo cp /usr/share/doc/mod-security-common/examples/modsecurity.conf-minimal /etc/apache2/conf.d/mod-security.conf

On édite ensuite le fichier /etc/apache2/conf.d/mod-security.conf:

# Basic configuration options
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

# Handling of file uploads
# TODO Choose a folder private to Apache.
SecUploadDir /tmp/
SecUploadKeepFiles Off

# Debug log
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 0

# Serial audit log
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogParts ABIFHZ
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log

# Maximum request body size we will
# accept for buffering
#SecRequestBodyLimit 131072
SecRequestBodyLimit 8192000

# Store up to 128 KB in memory
SecRequestBodyInMemoryLimit 131072

# Buffer response bodies of up to
# 512 KB in length
SecResponseBodyLimit 524288

# Verify that we've correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
SecRule REQBODY_PROCESSOR_ERROR "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Failed to parse request body.',severity:2"

# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \
failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}'"

# Did we see anything that might be a boundary?
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"

On relance ensuite Apache pour prendre en compte le plugin:

sudo /etc/init.d/apache2 restart

Ce module contient un ensemble d’expressions rationnelles dont l'objectif est de bloquer les requêtes jugées dangereuses. Il bloquera une partie des tentatives de piratage. C’est  tout de même une barrière de protection faillible mais qui peut empêcher l’exploitation de certaines failles. Dans tout les cas, cela n’empêche pas le développeur de coder correctement, en prenant en compte la sécurité au moment du développement des sites.

Module anti DOS

Nous allons installer le module Apache mod_evasive qui permet d’atténuer les attaques DOS faite en utilisant le protocole HTTP en bloquant les adresses IP des clients trop gourmand, c’est à dire ceux qui demandent trop rapidement des pages webs.

Contrairement à ce que l’on peut lire sur certains sites, ce module ne protège pas des DDOS, seulement des DOS (lire ici une explication des attaques DOS et DDOS). Autrement dit, il bloque les reqêtes venant d’une adresse IP (DOS).

Si un très grand nombre d’IPs font une seule requête : votre serveur sera saturé et le mod_evasive n’aura pas servi (DDOS). Bloquer les DDOS est très difficile car les requêtes sont difficilement reconnaissables des requêtes autorisées.

On commence par installer le module:

sudo aptitude install libapache2-mod-evasive

On édite le fichier /etc/apache2/conf.d/mod-evasive:

<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
</IfModule>

C'est la configuration par défaut qui va bloquer pendant 10 secondes (DOSBlockingPeriod) les requêtes HTTP venant de l'adresse IP source si une des assertions suivantes est vérifiée:

  • il y a plus de 2 requêtes (DOSPageCount) sur la même page dans un intervalle de 1 seconde (DOSPageInterval)
  • il y a plus de 50 requêtes (DOSSiteCount) sur l'ensemble du site dans un intervalle de 1 seconde (DOSSiteInterval)

On relance ensuite Apache pour prendre en compte le plugin:

sudo /etc/init.d/apache2 restart

Sécurisation du moteur PHP

PHP est un langage interprété, largement utilisé pour générer dynamiquement des pages HTML. C’est le langage utilisé par le moteur de CMS WordPress. La génération des pages de votre blog se faisant directement sur votre serveur, il est important de protéger l’environnement d’exécution des scripts PHP.

Il est donc conseillé d’utiliser suphp. Il est relativement facile à installer et permet d’exécuter vos scripts PHP sous un utilisateur autre que www-data et donc protéger votre système.

Cela permet aussi de servir plusieurs sites internet sur un même serveur. Si un pirate atteint un site, il ne pourra pas toucher aux autres.

Ce module fournit aussi la possibilité de disposer d’un fichier PHP.ini par site web, et offre donc plus de flexibilité que l’installation standard de PHP.

La sécurité a néanmoins un coup: la performance. Attendez vous à des pertes de performances sur vos applications. Dans le cas d’une application codée correctement et d’un serveur non surchargé, cette perte devrait cependant être minime.

Il est également possible de désactiver certaines fonctions sensible de PHP (system, exec...) en éditant le fichier php.ini (voir exemple dans l'étape n°3 de ce billet).

Pour installer  suPhp sur votre serveur je vous conseille la lecture de cet article. (si vous voulez/devez faire cohabiter deux versions de PHP, par exemple la 4 et la 5, vous pouvez également consulter ce billet).

Conclusion (temporaire)

On dispose donc maintenant d'un système et d'un serveur Web sécurisé. Il ne reste plus qu'à attendre la suite de cette série de billets pour s'attaquer à la sécurisation du moteur de blogging WordPress.

  • Pingback: Tweets that mention Sécuriser son blog Wordpress #2 -- Topsy.com()

  • Pour PHP, pourquoi pas php5-suhosin?
    http://www.hardened-php.net/suhosin/

    David

    • Depuis la version 5.2.4 de PHP, le package Ubuntu est pré-configuré avec le patch Suhosin…

  • jahman

    Salut,

    Le mode trace n’est pas plutot à désactiver?

    http://forum.spiritofhack.net/viewtopic.php?id=1936

  • Jahman

    quelques options du php.ini à régler/désactiver si possible

    Resource Limits: ce groupe d’option permet d’eviter d’avoir des processus utilisant trop de processeur ou de memoire
    magic_quotes [gpc|runtime] = On : permet de proteger les caracteres (remplace ’ par \’ par exemple).
    safe_mode = On : mesures diverses de protection
    disable_function = : permet de supprimer des fonctions dangereuses de PHP (type mail ou pour l’exeution de commandes system, shell exec, passthru, popen, proc open)
    display_errors = Off : permet de ne plus afficher les messages d’erreur
    log_errors = On : journalise les erreurs
    file_upload = Off : desactive l’upload de fichiers (source importante de compromission)
    register_globals = Off : desactive la porte globale des variables
    enable_dl = Off : desactive le chargement de bibliotheques partagees
    allow_url_fopen = Off : desactive l’ouverture de fichiers distants
    allow_url_include = Off : deasctive l’inclusion de fichiers distants

  • On pourrait également parler de suExec et de Suhosin.

    Attention sur les attaques DDoS car même avec une protection c’est souvent une saturation au niveau réseau qui provoque l’indispo d’un serveur. Et ça, c’est l’hébergeur qui peut agir en amont sur les routeurs pour filtrer les requêtes

    • C’est tout à fait vrai, par exemple lors de la deuxième attaque massive sur Wikileaks après la diffusion des messages diplomatiques, c’est un flux de plus de 10 Gbps qui arrivait sur les serveurs… Il faut une sacrée infrastructure réseau pour arriver à ces débits !

  • Avec sous mod-security installé nikto me detecte toujours les mêmes failles.
    Pourtant j’ai ajouté de nouvelles règles essayé pas mal de trucs, et il me révèle toujours les mêmes.

  • Pingback: Sécuriser son blog WordPress #3()

  • DJ

    Une question,

    Je viens d’installer le module anti dos et le fichier /etc/apache2/conf.d/mod-evasive ne s’y trouve pas ?

    C’est pas plutot sur Apache2.conf qu’il faut renseigner les infos ?

    DOSHashTableSize 3097
    DOSPageCount 2
    DOSSiteCount 50
    DOSPageInterval 1
    DOSSiteInterval 1
    DOSBlockingPeriod 10

    Merci et bon tuto

    • Salut DJ, cela dépend de comment tu as installé Apache. Avec une installation standard depuis les dépôts Ubuntu tu dois avoir une directive de type include à la fin de ton fichier apache2.conf qui va intégrer automatiquement out les fichiers se trouvant dans le sous répertoire /etc/apache2/conf.d/.

      Si ce répertoire n’existe pas alors deux solutions:
      1) la première est de le créer et de rajouter la directive include dans le apache2.conf puis de mettre les paramètres pour le module anti dos dans un fichier de ce nouveau répertoire.
      2) mettre directement les directives dans le fichier apache2.conf.

      A toi de voir…

      • DJ

        Merci pour les infos.

        Effectivement j’ai installé par les dépôts mais pour le module il s’est bien installé mais aucun fichier visible donc je l’ai crée moi même et j’ai pu redémarrer mon service apache2 sans soucis

        Merci encore 🙂

  • %

    La mise en place d’un WAF peut limiter l’édition des pages à partir de l’administration ou la rédaction d’articles composés d’éléments HTML.

    Une très bonne protection reste la désactivation de l’administration des plugins, mais aussi la rédaction d’articles par un compte non privilégié. Ceci permettra de stopper les attaques contre les plugins (ex : http://blog.felix-aime.fr/developpement-web/dune-csrf-a-un-rce-bienvenue-chez-wordpress-fear/)

  • Pingback: Sécuriser son blog Wordpress #1()