如何(安全)将Python对象发送到我的Flask API? [英] How do I (safely) send a Python object to my Flask API?

查看:80
本文介绍了如何(安全)将Python对象发送到我的Flask API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试构建一个Flask Web API,该API可以在POST请求中接收python对象.

I am currently trying to build a Flask Web API that is able to receive a python object in a POST-request.

我正在使用Python 3.7.1创建请求,并使用Python 2.7运行API.该API设置为在我的本地计算机上运行.我要发送到我的API的对象是sklearn.ensemble中的RandomForestClassifier对象,但这可能是各种各样的对象类型.

I am using Python 3.7.1 for creating the request and Python 2.7 for running the API. The API is set up to run on my local machine. The object I am trying to send to my API is a RandomForestClassifier object from sklearn.ensemble, but this could be any of a wide variety of object types.

到目前为止,我已经尝试了json.dumps()我的对象,但是该对象不是JSON可序列化的.我还尝试了pickle.dumps()我的对象,但是当尝试在API端加载对象时,这导致了错误.另外,由于API将接收来自匿名用户的请求,因此我担心对可能是恶意对象的对象执行pickle.loads().

So far I have tried to json.dumps() my object, but this object is not JSON serializable. I have also tried to pickle.dumps() my object, but this caused an error when trying to load the object on the API side. Also, since the API will receive requests from anonymous users, I am worried about performing a pickle.loads() on a possibly malicious object.

这是有根有根的担心吗?如果是这样,在POST请求中发送任何python对象的最佳方法是什么?

Is this a grounded worry? And if so, what is the best way to send any python object in a POST request?

执行POST请求的脚本:

The script performing the POST request:

import requests
import pickle

url = "http://localhost:5000/flask-api-function"

# the object I want to send is the 'model' object
data = pickle.dumps(model)

r = requests.post(url,data=data)

Flask API:

The Flask API:

@app.route('/flask-api-function', methods=['POST'])
def flask_api_function():

  model = pickle.loads(request.get_data())

此设置实际上在尝试用pickle解码数据时导致错误:

This setup actually causes an error when trying to decode the data with pickle:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/larssuanet/Documents/enjins/dscs/flask_api.py", line 39, in store_model
model = pickle.loads(request.get_data())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1382, in loads
return Unpickler(file).load()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 886, in load_proto
raise ValueError, "unsupported pickle protocol: %d" % proto
ValueError: unsupported pickle protocol: 3

有没有一种不错且安全的方法?

Is there a nice and safe way to do is?

推荐答案

在python 3中腌制该对象时,传递protocol关键字并将其设置为2.这将确保它可以在python 2上使用.

When you pickle the object in python 3, pass the protocol keyword and set it to 2. This will ensure that it will work on python 2.

import requests
import pickle

url = "http://localhost:5000/flask-api-function"

# the object I want to send is the 'model' object
data = pickle.dumps(model,protocol=2)

r = requests.post(url,data=data)

通常,我会尝试找到一种将对象序列化为JSON的方法,因为pickle具有重大的安全风险

Generally I would try to find a way to serialize the object into JSON since pickle has major security risks

这篇关于如何(安全)将Python对象发送到我的Flask API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆