[Bug #471893] Replace security material with a warning against unpickling

untrusted data.
This commit is contained in:
Andrew M. Kuchling 2003-05-14 16:51:46 +00:00
parent 126d366ea6
commit 7696344182
2 changed files with 30 additions and 73 deletions

View File

@ -26,14 +26,17 @@ mainly to support reading and writing the ``pseudo-compiled'' code for
Python modules of \file{.pyc} files. Therefore, the Python Python modules of \file{.pyc} files. Therefore, the Python
maintainers reserve the right to modify the marshal format in backward maintainers reserve the right to modify the marshal format in backward
incompatible ways should the need arise. If you're serializing and incompatible ways should the need arise. If you're serializing and
de-serializing Python objects, use the \module{pickle} module. There de-serializing Python objects, use the \module{pickle} module instead.
may also be unknown security problems with
\module{marshal}\footnote{As opposed to the known security issues in
the \module{pickle} module!}.
\refstmodindex{pickle} \refstmodindex{pickle}
\refstmodindex{shelve} \refstmodindex{shelve}
\obindex{code} \obindex{code}
\begin{notice}[warning]
The \module{marshal} module is not intended to be secure against
erroneous or maliciously constructed data. Never unmarshal data
received from an untrusted or unauthenticated source.
\end{notice}
Not all Python object types are supported; in general, only objects Not all Python object types are supported; in general, only objects
whose value is independent from a particular invocation of Python can whose value is independent from a particular invocation of Python can
be written and read by this module. The following types are supported: be written and read by this module. The following types are supported:

View File

@ -85,18 +85,14 @@ significant ways:
\module{pickle} serialization format is guaranteed to be \module{pickle} serialization format is guaranteed to be
backwards compatible across Python releases. backwards compatible across Python releases.
\item The \module{pickle} module doesn't handle code objects, which
the \module{marshal} module does. This avoids the possibility
of smuggling Trojan horses into a program through the
\module{pickle} module\footnote{This doesn't necessarily imply
that \module{pickle} is inherently secure. See
section~\ref{pickle-sec} for a more detailed discussion on
\module{pickle} module security. Besides, it's possible that
\module{pickle} will eventually support serializing code
objects.}.
\end{itemize} \end{itemize}
\begin{notice}[warning]
The \module{pickle} module is not intended to be secure against
erroneous or maliciously constructed data. Never unpickle data
received from an untrusted or unauthenticated source.
\end{notice}
Note that serialization is a more primitive notion than persistence; Note that serialization is a more primitive notion than persistence;
although although
\module{pickle} reads and writes file objects, it does not handle the \module{pickle} reads and writes file objects, it does not handle the
@ -251,11 +247,10 @@ the \method{dump()} method.
\end{excdesc} \end{excdesc}
\begin{excdesc}{UnpicklingError} \begin{excdesc}{UnpicklingError}
This exception is raised when there is a problem unpickling an object, This exception is raised when there is a problem unpickling an object.
such as a security violation. Note that other exceptions may also be Note that other exceptions may also be raised during unpickling,
raised during unpickling, including (but not necessarily limited to) including (but not necessarily limited to) \exception{AttributeError},
\exception{AttributeError}, \exception{EOFError}, \exception{EOFError}, \exception{ImportError}, and \exception{IndexError}.
\exception{ImportError}, and \exception{IndexError}.
\end{excdesc} \end{excdesc}
The \module{pickle} module also exports two callables\footnote{In the The \module{pickle} module also exports two callables\footnote{In the
@ -263,8 +258,8 @@ The \module{pickle} module also exports two callables\footnote{In the
subclass to customize the behavior. However, in the \module{cPickle} subclass to customize the behavior. However, in the \module{cPickle}
modules these callables are factory functions and so cannot be modules these callables are factory functions and so cannot be
subclassed. One of the common reasons to subclass is to control what subclassed. One of the common reasons to subclass is to control what
objects can actually be unpickled. See section~\ref{pickle-sec} for objects can actually be unpickled. See section~\ref{pickle-sub} for
more details on security concerns.}, \class{Pickler} and more details.}, \class{Pickler} and
\class{Unpickler}: \class{Unpickler}:
\begin{classdesc}{Pickler}{file\optional{, protocol\optional{, bin}}} \begin{classdesc}{Pickler}{file\optional{, protocol\optional{, bin}}}
@ -445,7 +440,7 @@ serialized. This protocol provides a standard way for you to define,
customize, and control how your objects are serialized and customize, and control how your objects are serialized and
de-serialized. The description in this section doesn't cover specific de-serialized. The description in this section doesn't cover specific
customizations that you can employ to make the unpickling environment customizations that you can employ to make the unpickling environment
safer from untrusted pickle data streams; see section~\ref{pickle-sec} slightly safer from untrusted pickle data streams; see section~\ref{pickle-sub}
for more details. for more details.
\subsubsection{Pickling and unpickling normal class \subsubsection{Pickling and unpickling normal class
@ -647,54 +642,13 @@ the \method{noload()} method on the Unpickler.
% shot at producing a persistent id. Since Jim Fulton can't remember % shot at producing a persistent id. Since Jim Fulton can't remember
% why it was added or what it's for, I'm leaving it undocumented. % why it was added or what it's for, I'm leaving it undocumented.
\subsection{Security \label{pickle-sec}} \subsection{Subclassing Unpicklers \label{pickle-sub}}
Most of the security issues surrounding the \module{pickle} and By default, unpickling will import any class that it finds in the
\module{cPickle} module involve unpickling. There are no known pickle data. You can control exactly what gets unpickled and what
security vulnerabilities gets called by customizing your unpickler. Unfortunately, exactly how
related to pickling because you (the programmer) control the objects you do this is different depending on whether you're using
that \module{pickle} will interact with, and all it produces is a \module{pickle} or \module{cPickle}.\footnote{A word of caution: the
string.
However, for unpickling, it is \strong{never} a good idea to unpickle
an untrusted string whose origins are dubious, for example, strings
read from a socket. This is because unpickling can create unexpected
objects and even potentially run methods of those objects, such as
their class constructor or destructor\footnote{A special note of
caution is worth raising about the \refmodule{Cookie}
module. By default, the \class{Cookie.Cookie} class is an alias for
the \class{Cookie.SmartCookie} class, which ``helpfully'' attempts to
unpickle any cookie data string it is passed. This is a huge security
hole because cookie data typically comes from an untrusted source.
You should either explicitly use the \class{Cookie.SimpleCookie} class
--- which doesn't attempt to unpickle its string --- or you should
implement the defensive programming steps described later on in this
section.}.
You can defend against this by customizing your unpickler so that you
can control exactly what gets unpickled and what gets called.
Unfortunately, exactly how you do this is different depending on
whether you're using \module{pickle} or \module{cPickle}.
One common feature that both modules implement is the
\member{__safe_for_unpickling__} attribute. Before calling a callable
which is not a class, the unpickler will check to make sure that the
callable has either been registered as a safe callable via the
\refmodule[copyreg]{copy_reg} module, or that it has an
attribute \member{__safe_for_unpickling__} with a true value. This
prevents the unpickling environment from being tricked into doing
evil things like call \code{os.unlink()} with an arbitrary file name.
See section~\ref{pickle-protocol} for more details.
For safely unpickling class instances, you need to control exactly
which classes will get created. Be aware that a class's constructor
could be called (if the pickler found a \method{__getinitargs__()}
method) and the the class's destructor (i.e. its \method{__del__()} method)
might get called when the object is garbage collected. Depending on
the class, it isn't very heard to trick either method into doing bad
things, such as removing a file. The way to
control the classes that are safe to instantiate differs in
\module{pickle} and \module{cPickle}\footnote{A word of caution: the
mechanisms described here use internal attributes and methods, which mechanisms described here use internal attributes and methods, which
are subject to change in future versions of Python. We intend to are subject to change in future versions of Python. We intend to
someday provide a common interface for controlling this behavior, someday provide a common interface for controlling this behavior,
@ -705,17 +659,17 @@ In the \module{pickle} module, you need to derive a subclass from
method. \method{load_global()} should read two lines from the pickle method. \method{load_global()} should read two lines from the pickle
data stream where the first line will the the name of the module data stream where the first line will the the name of the module
containing the class and the second line will be the name of the containing the class and the second line will be the name of the
instance's class. It then look up the class, possibly importing the instance's class. It then looks up the class, possibly importing the
module and digging out the attribute, then it appends what it finds to module and digging out the attribute, then it appends what it finds to
the unpickler's stack. Later on, this class will be assigned to the the unpickler's stack. Later on, this class will be assigned to the
\member{__class__} attribute of an empty class, as a way of magically \member{__class__} attribute of an empty class, as a way of magically
creating an instance without calling its class's \method{__init__()}. creating an instance without calling its class's \method{__init__()}.
You job (should you choose to accept it), would be to have Your job (should you choose to accept it), would be to have
\method{load_global()} push onto the unpickler's stack, a known safe \method{load_global()} push onto the unpickler's stack, a known safe
version of any class you deem safe to unpickle. It is up to you to version of any class you deem safe to unpickle. It is up to you to
produce such a class. Or you could raise an error if you want to produce such a class. Or you could raise an error if you want to
disallow all unpickling of instances. If this sounds like a hack, disallow all unpickling of instances. If this sounds like a hack,
you're right. UTSL. you're right. Refer to the source code to make this work.
Things are a little cleaner with \module{cPickle}, but not by much. Things are a little cleaner with \module{cPickle}, but not by much.
To control what gets unpickled, you can set the unpickler's To control what gets unpickled, you can set the unpickler's
@ -724,7 +678,7 @@ To control what gets unpickled, you can set the unpickler's
\exception{UnpicklingError}. If it is a function, \exception{UnpicklingError}. If it is a function,
then it should accept a module name and a class name, and return the then it should accept a module name and a class name, and return the
corresponding class object. It is responsible for looking up the corresponding class object. It is responsible for looking up the
class, again performing any necessary imports, and it may raise an class and performing any necessary imports, and it may raise an
error to prevent instances of the class from being unpickled. error to prevent instances of the class from being unpickled.
The moral of the story is that you should be really careful about the The moral of the story is that you should be really careful about the