Composer プラグインの Drupal Paranoia で Drupal をより安全なディレクトリ構造へ変更する
Drupal Composerグループのリポジトリの中にDrupal Paranoiaという Composer のプラグインを見つけたので試した。前提として、適用する Drupal プロジェクトがdrupal-composer/drupal-projectで作成されていることが必要
なぜこのプラグインを使うか
DocumentRoot 以下の不必要な PHP ファイルから脆弱性を生まないようにするため。実際 2016 年にCoderというモジュールで脆弱性SA-CONTRIB-2016-039が発生した。
この脆弱性では Code モジュールが有効である必要ではなく、ファイルシステム上にありウェブからアクセスできる場所にあれば攻撃が可能だった。
The module does not need to be enabled for this to be exploited. Its presence on the file system and being reachable from the web are sufficient.
何をするプラグインなのか
DocumentRoot 以下 PHP ファイルをウェブ側からアクセスできない場所に移動し、必要最小限の PHP ファイル(スタブ)に置き換えれば目的は達成されるが、composer update
の度に都度行うのは手間なので、これを運用に乗せるため自動的に実行する。
確認
Drupal Paranoia 適用前
❯ tree -L 1
.
├── LICENSE
├── README.md
├── composer.json
├── composer.lock
├── drush
├── load.environment.php
├── phpunit.xml.dist
├── scripts
├── vendor
└── web
4 directories, 6 files
❯ tree web -L 1
web
├── autoload.php
├── core
├── index.php
├── modules
├── profiles
├── robots.txt
├── sites
├── themes
├── update.php
└── web.config
5 directories, 5 files
Drupal Paranoia 適用後
.
├── LICENSE
├── README.md
├── app├── composer.json
├── composer.lock
├── drush
├── load.environment.php
├── phpunit.xml.dist
├── scripts
├── vendor
└── web
5 directories, 6 files
❯ tree web -L 1
web
├── core
├── index.php
└── sites
2 directories, 1 file
❯ tree app -L 1
app
├── autoload.php
├── core
├── index.php
├── modules
├── profiles
├── robots.txt
├── sites
├── themes
├── update.php
└── web.config
5 directories, 5 files
残された PHP ファイルは 4 ファイルのみ
❯ find ./web -name "*.php"
./web/core/install.php
./web/core/modules/statistics/statistics.php
./web/core/rebuild.php
./web/index.php
中身もほぼカラ
❯ cat ./web/index.php
<?php
chdir('../app/');
require './index.php';
❯ cat ./web/core/install.php
<?php
chdir('../../app/core/');
require './install.php';
PHP 以外のファイルはシンボリックリンクに置き換え
❯ tree web/core/themes/classy/css
web/core/themes/classy/css
└── components
├── action-links.css -> ../../../../../../app/core/themes/classy/css/components/action-links.css
├── book-navigation.css -> ../../../../../../app/core/themes/classy/css/components/book-navigation.css
├── breadcrumb.css -> ../../../../../../app/core/themes/classy/css/components/breadcrumb.css
├── button.css -> ../../../../../../app/core/themes/classy/css/components/button.css
├── collapse-processed.css -> ../../../../../../app/core/themes/classy/css/components/collapse-processed.css
├── container-inline.css -> ../../../../../../app/core/themes/classy/css/components/container-inline.css
├── details.css -> ../../../../../../app/core/themes/classy/css/components/details.css
(略)
動作確認
snize/demo_drupal-paranoia: Secure your site with Drupal Paranoia
drush site:install demo_umami --db-url="sqlite://sites/default/files/.ht.sqlite" -y
cd web && php -S localhost:8888
まとめ
今回の場合はweb(DocumentRoot)
以下が必要最小限のファイルに置き換えられ、構造的に外部のアクセスから守られること確認した。本番運用しても問題ないように見える。
DrupalCon Nashville2018以降 Drupal 周辺の Composer プロジェクトが活発になっている気がするので今後もウォッチしていきたい。