harold
March 30, 2024, 12:19am
1
Hi,
I’m trying to use MiniMagick to convert PDFs to PNGs in my Rails app. My code works fine locally, but I get the following error in production:
MiniMagick::Error (`convert /tmp/open-uri20240329-311-1uqgou /tmp/image20240329-311-5gh9v4.png` failed with status: 1 and error:
convert-im6.q16: attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/426.
convert-im6.q16: no images defined `/tmp/image20240329-311-5gh9v4.png' @ error/convert.c/ConvertImageCommand/3229
Is there any way around this? Or will I have to find another way to convert my PDFs? I have included my conversion code below as well as the code to install MiniMagick in my dockerfile.
PDF to PNG:
pdf_data = URI.open(submission.pdf_attachment.url)
image_path = Tempfile.new(['image', '.png']).path
MiniMagick::Tool::Convert.new do |convert|
convert << pdf_data.path
convert << image_path
end
image(image_path, width: [500, bounds.width].min)
File.delete(image_path) if File.exist?(image_path)
Dockerfile:
ARG BUILD_PACKAGES="git build-essential libpq-dev wget vim curl gzip xz-utils libsqlite3-dev libmagickwand-dev"
ARG DEPLOY_PACKAGES="postgresql-client file vim curl gzip libsqlite3-0 libvips42 imagemagick"
rubys
March 30, 2024, 12:32am
2
I’ve hit this issue myself, on my own hardware. This appears to be a good description of the problem and potential solutions: linux - ImageMagick security policy 'PDF' blocking conversion - Stack Overflow
What is your base image (FROM statement) in your Dockerfile?
harold
March 30, 2024, 12:36am
3
It’s working locally for me, it’s just when I push to production I get the error. Have you managed to get it working in production?
This is my dockerfile code:
ARG RUBY_VERSION=3.2.1
ARG VARIANT=jemalloc-slim
FROM quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-${VARIANT} as base
LABEL fly_launch_runtime="rails"
ARG BUNDLER_VERSION=2.3.24
ARG RAILS_ENV=production
ENV RAILS_ENV=${RAILS_ENV}
ENV RAILS_SERVE_STATIC_FILES true
ENV RAILS_LOG_TO_STDOUT true
ARG BUNDLE_WITHOUT=development:test
ARG BUNDLE_PATH=vendor/bundle
ENV BUNDLE_PATH ${BUNDLE_PATH}
ENV BUNDLE_WITHOUT ${BUNDLE_WITHOUT}
RUN mkdir /app
WORKDIR /app
RUN mkdir -p tmp/pids
#######################################################################
SHELL ["/bin/bash", "-c"]
RUN curl https://get.volta.sh | bash
ENV BASH_ENV ~/.bashrc
ENV VOLTA_HOME /root/.volta
ENV PATH $VOLTA_HOME/bin:/usr/local/bin:$PATH
RUN volta install node && volta install yarn
FROM base as build_deps
ARG BUILD_PACKAGES="git build-essential libpq-dev wget vim curl gzip xz-utils libsqlite3-dev libmagickwand-dev"
ENV BUILD_PACKAGES ${BUILD_PACKAGES}
RUN --mount=type=cache,id=dev-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=dev-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y ${BUILD_PACKAGES} \
&& rm -rf /var/lib/apt/lists /var/cache/apt/archives
#######################################################################
# install gems
FROM build_deps as gems
RUN gem update --system --no-document && \
gem install -N bundler -v ${BUNDLER_VERSION}
COPY Gemfile* ./
RUN bundle install && rm -rf vendor/bundle/ruby/*/cache
#######################################################################
# install deployment packages
FROM base
ARG DEPLOY_PACKAGES="postgresql-client file vim curl gzip libsqlite3-0 libvips42 imagemagick"
ENV DEPLOY_PACKAGES=${DEPLOY_PACKAGES}
RUN --mount=type=cache,id=prod-apt-cache,sharing=locked,target=/var/cache/apt \
--mount=type=cache,id=prod-apt-lib,sharing=locked,target=/var/lib/apt \
apt-get update -qq && \
apt-get install --no-install-recommends -y \
${DEPLOY_PACKAGES} \
&& rm -rf /var/lib/apt/lists /var/cache/apt/archives
# copy installed gems
COPY --from=gems /app /app
COPY --from=gems /usr/lib/fullstaq-ruby/versions /usr/lib/fullstaq-ruby/versions
COPY --from=gems /usr/local/bundle /usr/local/bundle
#######################################################################
# Deploy your application
COPY . .
# Adjust binstubs to run on Linux and set current working directory
RUN chmod +x /app/bin/* && \
sed -i 's/ruby.exe/ruby/' /app/bin/* && \
sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)' /app/bin/*
# The following enable assets to precompile on the build server. Adjust
# as necessary. If no combination works for you, see:
# https://fly.io/docs/rails/getting-started/existing/#access-to-environment-variables-at-build-time
ENV SECRET_KEY_BASE 1
# ENV AWS_ACCESS_KEY_ID=1
# ENV AWS_SECRET_ACCESS_KEY=1
# Run build task defined in lib/tasks/fly.rake
ARG BUILD_COMMAND="bin/rails fly:build"
RUN ${BUILD_COMMAND}
# Default server start instructions. Generally Overridden by fly.toml.
ENV PORT 8080
ARG SERVER_COMMAND="bin/rails fly:server"
ENV SERVER_COMMAND ${SERVER_COMMAND}
CMD ${SERVER_COMMAND}
rubys
March 30, 2024, 12:49am
4
Adding the following after the install of ${DEPLOY_PACKAGES}
will disable the security policy:
RUN sed -i '/PDF/d' /etc/ImageMagick-6/policy.xml
Whether that will expose your application to security issues will depend entirely on your usage; and is well beyond my area of expertise.
1 Like
harold
March 30, 2024, 1:12am
5
Thanks for the help, this has solved my issue. I’ll have a look into the potential security issues, but for now it’s working!
system
Closed
April 6, 2024, 1:12am
6
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.