Use exiftool to strip image EXIF data (preserving orientation)

This commit is contained in:
joshua stein 2021-01-20 23:50:57 -06:00
parent 4ce2702886
commit 6cbcfc98d3
2 changed files with 77 additions and 40 deletions

View File

@ -36,6 +36,15 @@ the following:
* ``ffmpegthumbnailer`` executable in ``$PATH`` * ``ffmpegthumbnailer`` executable in ``$PATH``
EXIF Stripping
--------------
When ``STRIP_IMAGE_EXIF`` is enabled, all images uploaded will be
processed through exiftool to strip all EXIF data except the orientation
tag.
Requires the ``exiftool`` script in ``$PATH``.
INSTALL INSTALL
------- -------
:: ::

108
fhost.py
View File

@ -68,6 +68,11 @@ app.config["FHOST_UPLOAD_BLACKLIST"] = "tornodes.txt"
app.config["NSFW_DETECT"] = False app.config["NSFW_DETECT"] = False
app.config["NSFW_THRESHOLD"] = 0.608 app.config["NSFW_THRESHOLD"] = 0.608
app.config["STRIP_IMAGE_EXIF"] = True
if app.config["STRIP_IMAGE_EXIF"]:
import subprocess
if app.config["NSFW_DETECT"]: if app.config["NSFW_DETECT"]:
from nsfw_detect import NSFWDetector from nsfw_detect import NSFWDetector
nsfw = NSFWDetector() nsfw = NSFWDetector()
@ -185,12 +190,7 @@ def in_upload_bl(addr):
return False return False
def store_file(f, addr): def check_existing(digest, data, addr):
if in_upload_bl(addr):
return "Your host is blocked from uploading files.\n", 451
data = f.stream.read()
digest = sha256(data).hexdigest()
existing = File.query.filter_by(sha256=digest).first() existing = File.query.filter_by(sha256=digest).first()
if existing: if existing:
@ -212,50 +212,78 @@ def store_file(f, addr):
db.session.commit() db.session.commit()
return existing.geturl() return existing.geturl()
return None
def store_file(f, addr):
if in_upload_bl(addr):
return "Your host is blocked from uploading files.\n", 451
data = f.stream.read()
digest = sha256(data).hexdigest()
exists = check_existing(digest, data, addr)
if exists != None:
return exists
guessmime = mimedetect.from_buffer(data)
if not f.content_type or not "/" in f.content_type or f.content_type == "application/octet-stream":
mime = guessmime
else: else:
guessmime = mimedetect.from_buffer(data) mime = f.content_type
if not f.content_type or not "/" in f.content_type or f.content_type == "application/octet-stream": if mime in app.config["FHOST_MIME_BLACKLIST"] or guessmime in app.config["FHOST_MIME_BLACKLIST"]:
mime = guessmime abort(415)
if mime.startswith("text/") and not "charset" in mime:
mime += "; charset=utf-8"
ext = os.path.splitext(f.filename)[1]
if not ext:
gmime = mime.split(";")[0]
if not gmime in app.config["FHOST_EXT_OVERRIDE"]:
ext = guess_extension(gmime)
else: else:
mime = f.content_type ext = app.config["FHOST_EXT_OVERRIDE"][gmime]
else:
ext = ext[:8]
if mime in app.config["FHOST_MIME_BLACKLIST"] or guessmime in app.config["FHOST_MIME_BLACKLIST"]: if not ext:
abort(415) ext = ".bin"
if mime.startswith("text/") and not "charset" in mime: if app.config["STRIP_IMAGE_EXIF"] and mime.startswith("image/"):
mime += "; charset=utf-8" p = subprocess.Popen(["exiftool",
"-stay_open", "true",
"-all=",
"-tagsfromfile", "@",
"-Orientation",
"-" ], stdout = subprocess.PIPE, stdin = subprocess.PIPE)
p.stdin.write(data)
p.stdin.close()
data = p.stdout.read()
digest = sha256(data).hexdigest()
exists = check_existing(digest, data, addr)
if exists != None:
return exists
ext = os.path.splitext(f.filename)[1] spath = getpath(digest)
if not ext: with open(spath, "wb") as of:
gmime = mime.split(";")[0] of.write(data)
if not gmime in app.config["FHOST_EXT_OVERRIDE"]: if app.config["NSFW_DETECT"]:
ext = guess_extension(gmime) nsfw_score = nsfw.detect(spath)
else: else:
ext = app.config["FHOST_EXT_OVERRIDE"][gmime] nsfw_score = None
else:
ext = ext[:8]
if not ext: sf = File(digest, ext, mime, addr, nsfw_score)
ext = ".bin" db.session.add(sf)
db.session.commit()
spath = getpath(digest) return sf.geturl()
with open(spath, "wb") as of:
of.write(data)
if app.config["NSFW_DETECT"]:
nsfw_score = nsfw.detect(spath)
else:
nsfw_score = None
sf = File(digest, ext, mime, addr, nsfw_score)
db.session.add(sf)
db.session.commit()
return sf.geturl()
def store_url(url, addr): def store_url(url, addr):
# handler to convert gopher links to HTTP(S) proxy # handler to convert gopher links to HTTP(S) proxy