15

我正在使用 Python 开发一个程序,并希望用户能够保存他们正在处理的数据。我研究过 cPickle;看起来这将是一种快速简便的数据保存方法,但似乎不安全。由于可以腌制整个函数、类等,我担心流氓保存文件可能会将有害代码注入程序。有没有办法可以防止这种情况发生,或者我应该研究其他保存数据的方法,例如直接转换为字符串(这也似乎不安全)或创建 XML 层次结构,并将数据放入其中。

我是python新手,所以请多多包涵。

提前致谢!

编辑:至于我存储的数据类型,主要是字典和列表。名称,速度等信息。现在相当简单,但将来可能会变得更加复杂。

4

7 回答 7

23

根据您的描述,JSON 编码是安全且快速的解决方案。python2.6中有一个json模块,可以这样使用:

import json
obj = {'key1': 'value1', 'key2': [1, 2, 3, 4], 'key3': 1322}
encoded = json.dumps(obj)
obj = json.loads(encoded)

JSON 格式是人类可读的,与 python 中的字典字符串表示非常相似。并且没有任何像泡菜这样的安全问题。如果没有python2.6可以安装cjson或者simplejson

您不能使用 JSON 来保存像 Pickle 这样的 python 对象。但是你可以用它来保存:字符串、字典、列表……对于大多数情况来说已经足够了。

解释为什么泡菜不安全。来自 python文档

围绕 pickle 和 cPickle 模块的大多数安全问题都涉及 unpickling。没有已知的与 pickle 相关的安全漏洞,因为您(程序员)控制 pickle 将与之交互的对象,并且它产生的只是一个字符串。

但是,对于 unpickling,对来源可疑的不受信任的字符串进行 unpickle绝不是一个好主意,例如从套接字读取的字符串。这是因为 unpickling 可能会创建意外的对象,甚至可能会运行这些对象的方法,例如它们的类构造函数或析构函数……这个故事的寓意是,您应该非常小心应用程序 unpickles 的字符串的来源。

有一些方法可以保护自己,但在你的情况下使用 JSON 更容易。

于 2009-09-07T15:00:30.597 回答
3

您可以执行以下操作:

来写

  • 泡菜
  • 签署腌制文件
  • 完毕

读书

  • 检查腌制文件的签名
  • 解封
  • 利用

我想知道是什么让您认为数据文件会被篡改,但您的应用程序不会被篡改?

于 2009-09-07T14:59:33.143 回答
1

您应该使用某种数据库。以泡菜格式存储不是一个好主意(在大多数情况下)。你可以考虑:

  • SQLite -(包含在 Python 2.5+ 中)快速简单,但需要 SQL 和 DB-API 知识
  • buzhug - 具有 Pythonic 语法的非 SQL、基于文件的数据库
  • SQL 数据库 - 您可以使用一些 DBMS 的接口(如 MySQL、PostreSQL 等),但它只适用于大量数据(数千条记录)。

您可能会在此处找到其他一些解决方案。

于 2009-09-07T16:09:03.653 回答
1

您可能会喜欢在 http://yserial.sourceforge.net上使用 y_serial 模块

它读起来像一个教程,但在操作上提供了用于序列化和持久性的工作代码。评论讨论了与此处提出的问题相关的一些利弊。

它被设计为使用 SQLite 存储压缩 Python 对象的通用解决方案(几乎没有 SQL 大惊小怪 ;-)

希望这可以帮助。

于 2009-10-03T02:45:42.750 回答
1

在我们回答之前,您需要给我们更多的背景信息:您要保存什么类型的数据,有多少,您想如何访问它?

至于泡菜:它们不存储代码。当您腌制一个函数或类时,它是存储的名称,而不是实际的代码本身。

于 2009-09-07T14:53:33.307 回答
1

谁 - 具体来说 - 是通过破解腌制文件来破坏程序的反社会者?

是蟒蛇。反社会者有你的来源。他们不需要鬼鬼祟祟地破解你的泡菜文件。他们可以编辑您的源代码并做他们想要的所有“损害”。

不要担心“不安全感”,除非您与有组织的犯罪集团进行诉讼。

不要担心“流氓保存文件可能会将有害代码注入程序”。当他们有源时,没有人会为一个流氓保存文件而烦恼。

于 2009-09-08T00:40:10.287 回答
1

*****在这个答案中,我只关心应用程序完整性的意外损坏。*****

泡菜是“安全的”。可能不安全的是访问您未编写的代码,例如在插件中;不过,这与泡菜无关。

当你腌制一个对象时,它的所有数据都会被保存,但代码和实现不会。这意味着当 unpickled 时,更新的对象可能会发现它内部有“旧式”数据(如果您更新实现)。如果适用,这是您必须了解和处理的事情。

Pickling 字符串、列表、数字、dicts 非常简单,而且效果很好,与 JSON 相当。Pickle 的魔力在于——有时无需调整——即使是复杂的 python 对象也可以被腌制。但只有数据被腌制;通过保存的模块名称和对象的类型名称简单地重构实例。

于 2009-09-07T15:04:53.937 回答