# Security

The authors & contributors of the `Wand` module, ImageMagick library, and all the third party image delegates make a genuine effort to release stable code. However there is a trade off between convenience & secure environment, and everyone makes honest mistakes. Ensure you’re using the latest library versions, and the system is up to date with security patches. If you are using `Wand` to process images from the public, then you must be more vigilant.

- Never use `Wand` directly within a HTTP service, or on any server with public access. A simple queue based background worker can be used. For example: Celery, Redis, or Amazon’s SQS, but there are many others.

- Update the `policy.xml` on the system, and reduce the resource limits to something reasonable to your system.

      <policy domain="resource" name="memory" value="256MiB"/>
      <policy domain="resource" name="map" value="512MiB"/>
      <policy domain="resource" name="width" value="8KP"/>
      <policy domain="resource" name="height" value="8KP"/>
      <policy domain="resource" name="area" value="16KP"/>
      <policy domain="resource" name="disk" value="1GiB"/>
      <policy domain="resource" name="file" value="768"/>
      <policy domain="resource" name="thread" value="1"/>
      <policy domain="resource" name="throttle" value="0"/>
      <policy domain="resource" name="time" value="120"/>
      <policy domain="resource" name="list-length" value="128"/>

- Update the `policy.xml` on the system to restrict any formats that are unused, or have a history of abuse.

      <policy domain="coder" rights="none" pattern="MVG" />
      <policy domain="coder" rights="none" pattern="EPS" />
      <policy domain="coder" rights="none" pattern="PS" />
      <policy domain="coder" rights="none" pattern="PS2" />
      <policy domain="coder" rights="none" pattern="PS3" />
      <policy domain="coder" rights="none" pattern="PDF" />
      <policy domain="coder" rights="none" pattern="XPS" />
      <policy domain="filter" rights="none" pattern="*" />
      <policy domain="delegate" rights="none" pattern="HTTPS" />
      <policy domain="delegate" rights="none" pattern="SHOW" />
      <policy domain="delegate" rights="none" pattern="WIN" />
      <policy domain="path" rights="none" pattern="@*"/>

- Check the “magick bytes” of all untrusted files before processing. Never assume that the file extension suffix, or mimetype is good enough. For example:

      def assert_png(filename):
          """Ensure the file at a give path has the PNG magick-number
          header.  Throw an `AssertionError` if it does not match.
          """
          PNG_HEADER = [
              0x89, 0x50, 0x4E, 0x47,
              0x0D, 0x0A, 0x1A, 0x0A
          ]
          with open(filename, 'rb') as fd:
              file_header = list(fd.read(8))
          assert file_header == PNG_HEADER

      try:
          assert_png(user_file)
          with Image(filename='png:'+user_file) as img:
              # ... do work ...
      except AssertionError:
          # ... handle exception ...

- Ensure that any Python code is invoked with a low-privileged system user.

- Ensure filenames are sanitized.

- Ensure filenames are prefixed with coder protocol.

      with Image(filename='png:input.png') as img:
          # ... do work ...

- Ensure error handling is in place. Expect `PolicyError` exceptions if a file-format was banned, and `ResourceLimitError` if the system is unable to allocate additional memory/disk resources. Both can be configured by the `policy.xml` listed above.