2

我正在使用 python 在谷歌应用程序引擎上构建一个 webapp,我有以下代码允许用户上传图像,但是如果有人上传不是图像的东西,代码就会崩溃,因为我试图从数据,它当然不接受任何不是图像文件的东西。基本上我想知道是否有一种简单的方法可以防止上传不是图像文件的文件。

class RecordPage(BlogHandler):
    def get(self, keyid, title):
        record = individual_record_cache(keyid)
        upload_url = blobstore.create_upload_url('/upload/%s' % (keyid))
        photos = []
        for blobRef in record.blobRefs:
            photos.append(images.get_serving_url(blobRef, size=None, crop=False, secure_url=None))

        global visits
        user = users.get_current_user()
        logout = users.create_logout_url(self.request.uri)       
        self.render("recordpermalink.html", user=user, logout=logout, record=record, visits=visits, photos=photos, upload_url=upload_url, keyid=keyid)

class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
    def post(self, record_id):
        upload_files = self.get_uploads('file')
        blob_info = upload_files[0]
        blobRef = blob_info.key()
        record = Record.get_by_id(int(record_id))
        record.blobRefs.append(blobRef)
        record.put()
        individual_record_cache(record_id, True)
        record_cache(True)
        profile_record_cache(True)
        self.redirect('/record/%s/%s' % (record_id, record.title))
4

4 回答 4

3
  1. 如果您安装了上传处理程序,则无法阻止上传 blob,因为您的处理程序仅在 blob 已在 blobstore 中后调用。但是,您可以检查 blob 并将其删除。

  2. 上传 blob 后,您可以使用以下命令检查它是否为图像ImageService

    Image image = ImagesServiceFactory.makeImageFromBlob(blobKey);
    try {
        image.getFormat();
    } catch (IllegalArgumentException e) {
        // wrong image data - blob uploaded was not an image -> delete it
    }
    
于 2012-09-23T06:56:15.797 回答
2

您应该使用两种形式的检查(但是都在上传完成之后)。首先,MIME 类型:确保它以“image/*”开头。其次,尝试使用图像处理程序读取图像:

from PIL import Image
class UploadHandler(BaseUploadHandler):
    def post(self):
    try:
        upload = self.get_uploads()[0]
        # also check mime type here
        i = Image.open(upload.open()) # open it with PIL
        w, h = i.size # make sure you can read its size
    except:
        # error stuff here, probably means it's not an image
于 2012-09-23T06:17:37.110 回答
2

在上传之前,没有办法知道什么是图像,或者至少上传了前几个字节。

如果您想信任文件名上的文件扩展名,您可以执行以下操作:

import mimetypes
blob_mimetype = mimetypes.guess_type(blob_info.filename)[0]
# or just: blob_mimetype = blob_info.content_type
if not blob_mimetype.startswith('image/'):
    self.error(400)

无论代码在做什么“分解”,如果有人想要上传无效图像,或者如果他们在上传之前重命名文件以具有不同的文件扩展名,这可能不会保护您。只有当您试图阻止大多数善意的用户看到错误时,它才会有所帮助。

理想情况下,如果“代码崩溃”意味着从处理程序代码中获取异常,您可以将其包装在 try/except 中并适当地处理它。这是更 Pythonic 的方法,不会进行额外的前期计算或尝试变得比它必须的更聪明。

于 2012-09-23T05:12:28.703 回答
0

您可以尝试使用ImageMagick来识别文件。只需让上传完成,然后使用他们的命令行工具identify查看它是否真的是图像。

identify命令行文档的链接。但是,我不建议您使用这样的命令。您可能应该使用 PythonMagick 之类的包装器。

编辑:再次查看您的问题后,您正在使用 GAE。我只有 GAE 的 Java 方面的经验,但我认为由于 Java GAE 并没有真正有很多图像处理 API,Python 方面也不会。我能想到的最好的解决方案是将这项工作转移到像 EC2 这样的 VPS 上。

于 2012-09-23T05:05:16.657 回答