Using git attributes to exclude files from your release

Exclude files from your exports

Using git attributes to exclude files from your release

Deploying your development codebase to production seems like it has been solved many different ways, and often those ways are terrible from a security perspective.

Clone the whole repository on the production webservers

Quite possibly the worst idea ever, as not only is every single file on the production web servers, also every single revision of every single file is on the web server. Even worse, if the root .git directory is accessible over HTTP, the whole website can be cloned over HTTP as well.

Yes you can remove the .git directory, but this will not solve all your problems.

Use git archive to create a snapshot of the repository

One step better is to create just a snapshot of the repository using git archive. You can create a snapshot easily using git archive:

Zip format

git archive master -o

Compressed tar format

git archive master | bzip2 -9 > latest.tar.bz2

this will still contain files you do not want on the web server, e.g.

  • .gitignore
  • .gitattributes
  • potentially other redundant files that are not needed on production

Using git attributes combined with git archive

We have recently switched to using git attributes on all releases to ensure only the needed files for production are sent there during a release.

Sample git attributes file for Drupal 7

Here is a sample git attributes file that we use for Drupal 7:

# used to remove files from deployment using `git archive`
# git files
.gitattributes export-ignore
.gitignore export-ignore
# drush files
build.make export-ignore
patches.txt export-ignore
# zen 5.x files
sites/all/themes/*/sass export-ignore
sites/all/themes/*/sass-extensions export-ignore
sites/all/themes/*/images-source export-ignore
sites/all/themes/*/fonts export-ignore
sites/all/themes/*/config.rb export-ignore
sites/all/themes/*/STARTERKIT export-ignore
# drupal directories
scripts export-ignore
profiles/minimal export-ignore
profiles/standard export-ignore
profiles/testing export-ignore
# general text files
*README.txt export-ignore
* export-ignore
* export-ignore
*README export-ignore
*LICENSE.txt export-ignore
*license.txt export-ignore
*LICENSE.html export-ignore
COPYRIGHT.txt export-ignore
CHANGELOG.txt export-ignore
*changelog.txt export-ignore
*changelog.html export-ignore
*CHANGES.html export-ignore
*INSTALL.html export-ignore
*TODO.txt export-ignore
*API.txt export-ignore
*api.html export-ignore
*KNOWN_ISSUES.txt export-ignore
UPGRADE.txt export-ignore
web.config export-ignore
MAINTAINERS.txt export-ignore
INSTALL*.txt export-ignore
# patches
*.patch export-ignore
# tests
*.test export-ignore
# contrib (these could be security holes)
sites/all/libraries/plupload/examples export-ignore
sites/all/libraries/plupload/docs export-ignore
sites/all/libraries/jquery.jcarousel/examples export-ignore
sites/all/libraries/jquery.jcarousel/index.html export-ignore
sites/all/libraries/jquery.jcarousel/style.css export-ignore
sites/all/libraries/jquery.jcarousel/skins export-ignore
sites/all/libraries/jquery.jcarousel/lib/jquery.jcarousel.js export-ignore
sites/all/libraries/jquery.jcarousel/lib/jquery-1.4.2.min.js export-ignore
sites/all/libraries/colorbox/ export-ignore
sites/all/libraries/colorbox/*/*.html export-ignore
sites/all/libraries/colorbox/content export-ignore
sites/all/libraries/colorbox/jquery.colorbox.js export-ignore
sites/all/modules/contrib/ckeditor/images/buttons/index.html export-ignore
sites/all/modules/contrib/openlayers/tests/js/qunit/index.html export-ignore

The sample git attributes file is rather long and exhaustive, and it covers a wide range of core and contributed modules for Drupal 7. The plupload module is especially dangerous, as the library actually comes with several PHP scripts that if your web server allowed it to execute, it would allow anyone (anonymous included) to upload unlimited files to the web server.

You could take the export to the next level and remove several core PHP files from the release like:

  • cron.php
  • install.php
  • update.php etc


If you have any suggestions for improvements, let me know in the comments.