Improve PEPs 551 and 578 (#679)
This commit is contained in:
parent
267ef773c6
commit
0440c6d4f7
43
pep-0551.rst
43
pep-0551.rst
|
@ -10,16 +10,16 @@ Created: 23-Aug-2017
|
||||||
Python-Version: 3.7
|
Python-Version: 3.7
|
||||||
Post-History: 24-Aug-2017 (security-sig), 28-Aug-2017 (python-dev)
|
Post-History: 24-Aug-2017 (security-sig), 28-Aug-2017 (python-dev)
|
||||||
|
|
||||||
Status
|
Relationship to PEP 578
|
||||||
======
|
=======================
|
||||||
|
|
||||||
This PEP is currently in the process of being split into two.
|
This PEP has been split into two since its original posting.
|
||||||
|
|
||||||
See PEP 578 for the new auditing APIs proposed for addition to the next
|
See `PEP 578 <https://www.python.org/dev/peps/pep-0578/>`_ for the
|
||||||
version of Python.
|
auditing APIs proposed for addition to the next version of Python.
|
||||||
|
|
||||||
PEP 551 is now a draft informational PEP, providing guidance to those
|
This is now an informational PEP, providing guidance to those planning
|
||||||
planning to integrate Python into their secure or audited environments.
|
to integrate Python into their secure or audited environments.
|
||||||
|
|
||||||
Abstract
|
Abstract
|
||||||
========
|
========
|
||||||
|
@ -417,7 +417,30 @@ Since ``importlib``'s use of ``open_for_import`` may be easily bypassed
|
||||||
with monkeypatching, an audit hook **should** be used to detect
|
with monkeypatching, an audit hook **should** be used to detect
|
||||||
attribute changes on type objects.
|
attribute changes on type objects.
|
||||||
|
|
||||||
[TODO: more good advice; less bad advice]
|
Rejected Advice
|
||||||
|
===============
|
||||||
|
|
||||||
|
This section discusses common or "obviously good" recommendations that
|
||||||
|
we are specifically *not* making. These range from useless or incorrect
|
||||||
|
through to ideas that are simply not feasible in any real world
|
||||||
|
environment.
|
||||||
|
|
||||||
|
**Do not** attempt to implement a sandbox within the Python runtime.
|
||||||
|
There is a long history of attempts to allow arbitrary code limited use
|
||||||
|
of Python features (such as [14]_), but no general success. The best
|
||||||
|
options are to run unrestricted Python within a sandboxed environment
|
||||||
|
with at least hypervisor-level isolation, or to prevent unauthorised
|
||||||
|
code from starting at all.
|
||||||
|
|
||||||
|
**Do not** rely on static analysis to verify untrusted code before use.
|
||||||
|
The best options are to pre-authorise trusted code, such as with code
|
||||||
|
signing, and if not possible to identify known-bad code, such as with
|
||||||
|
an anti-malware scanner.
|
||||||
|
|
||||||
|
**Do not** use audit hooks to abort operations without logging the
|
||||||
|
event first. You will regret not knowing why your process disappeared.
|
||||||
|
|
||||||
|
[TODO - more bad advice]
|
||||||
|
|
||||||
Further Reading
|
Further Reading
|
||||||
===============
|
===============
|
||||||
|
@ -474,7 +497,7 @@ References
|
||||||
|
|
||||||
.. [4] `<https://aka.ms/deviceguard>`_
|
.. [4] `<https://aka.ms/deviceguard>`_
|
||||||
|
|
||||||
.. [5] AMSI, `<https://msdn.microsoft.com/en-us/library/windows/desktop/dn889587(v=vs.85).aspx>`_
|
.. [5] Antimalware Scan Interface, `<https://msdn.microsoft.com/en-us/library/windows/desktop/dn889587(v=vs.85).aspx>`_
|
||||||
|
|
||||||
.. [6] Persistent Zone Identifiers, `<https://msdn.microsoft.com/en-us/library/ms537021(v=vs.85).aspx>`_
|
.. [6] Persistent Zone Identifiers, `<https://msdn.microsoft.com/en-us/library/ms537021(v=vs.85).aspx>`_
|
||||||
|
|
||||||
|
@ -492,6 +515,8 @@ References
|
||||||
|
|
||||||
.. [13] SELinux access decisions `<http://man7.org/linux/man-pages/man3/avc_entry_ref_init.3.html>`_
|
.. [13] SELinux access decisions `<http://man7.org/linux/man-pages/man3/avc_entry_ref_init.3.html>`_
|
||||||
|
|
||||||
|
.. [14] The failure of pysandbox `<https://lwn.net/Articles/574215/>`_
|
||||||
|
|
||||||
Acknowledgments
|
Acknowledgments
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
|
83
pep-0578.rst
83
pep-0578.rst
|
@ -356,6 +356,10 @@ see which operations provide audit events.
|
||||||
``_ctypes._CData``, ``ctypes.cdata``, "``(ptr_as_int,)``", "Detect
|
``_ctypes._CData``, ``ctypes.cdata``, "``(ptr_as_int,)``", "Detect
|
||||||
when code is accessing arbitrary memory using ``ctypes``.
|
when code is accessing arbitrary memory using ``ctypes``.
|
||||||
"
|
"
|
||||||
|
"``new_mmap_object``",``mmap.__new__``,"``(fileno, map_size, access,
|
||||||
|
offset)``", "Detects creation of mmap objects. On POSIX, access may
|
||||||
|
have been calculated from the ``prot`` and ``flags`` arguments.
|
||||||
|
"
|
||||||
``sys._getframe``, ``sys._getframe``, "``(frame_object,)``", "Detect
|
``sys._getframe``, ``sys._getframe``, "``(frame_object,)``", "Detect
|
||||||
when code is accessing frames directly.
|
when code is accessing frames directly.
|
||||||
"
|
"
|
||||||
|
@ -374,21 +378,23 @@ see which operations provide audit events.
|
||||||
members that are marked as restricted, and members that may allow
|
members that are marked as restricted, and members that may allow
|
||||||
bypassing imports.
|
bypassing imports.
|
||||||
"
|
"
|
||||||
|
"``urllib.urlopen``",``urllib.Request``,"``(url, data, headers,
|
||||||
|
method)``", "Detects URL requests.
|
||||||
|
"
|
||||||
|
|
||||||
Performance Impact
|
Performance Impact
|
||||||
==================
|
==================
|
||||||
|
|
||||||
The important performance impact is the case where events are being
|
The important performance impact is the case where events are being
|
||||||
raised but there are no hooks attached. This is the unavoidable case -
|
raised but there are no hooks attached. This is the unavoidable case -
|
||||||
once a distributor or sysadmin begins adding audit hooks they have
|
once a distributor begins adding audit hooks they have explicitly
|
||||||
explicitly chosen to trade performance for functionality. Performance
|
chosen to trade performance for functionality. Performance import
|
||||||
impact using ``spython`` or with hooks added are not of interest here,
|
with hooks added are not of interest here, since this is considered
|
||||||
since this is considered opt-in functionality.
|
opt-in functionality.
|
||||||
|
|
||||||
Analysis using the ``performance`` tool shows no significant impact,
|
Analysis using the Python Performance Benchmark Suite [1]_ shows no
|
||||||
with the vast majority of benchmarks showing between 1.05x faster to
|
significant impact, with the vast majority of benchmarks showing
|
||||||
1.05x slower.
|
between 1.05x faster to 1.05x slower.
|
||||||
|
|
||||||
In our opinion, the performance impact of the set of auditing points
|
In our opinion, the performance impact of the set of auditing points
|
||||||
described in this PEP is negligible.
|
described in this PEP is negligible.
|
||||||
|
@ -407,7 +413,7 @@ The proposal is to add a new module for audit hooks, hypothetically
|
||||||
Any such module would need to be a built-in module that is guaranteed to
|
Any such module would need to be a built-in module that is guaranteed to
|
||||||
always be present. The nature of these hooks is that they must be
|
always be present. The nature of these hooks is that they must be
|
||||||
callable without condition, as any conditional imports or calls provide
|
callable without condition, as any conditional imports or calls provide
|
||||||
more opportunities to intercept and suppress or modify events.
|
opportunities to intercept and suppress or modify events.
|
||||||
|
|
||||||
Given its nature as one of the most core modules, the ``sys`` module is
|
Given its nature as one of the most core modules, the ``sys`` module is
|
||||||
somewhat protected against module shadowing attacks. Replacing ``sys``
|
somewhat protected against module shadowing attacks. Replacing ``sys``
|
||||||
|
@ -415,7 +421,8 @@ with a sufficiently functional module that the application can still run
|
||||||
is a much more complicated task than replacing a module with only one
|
is a much more complicated task than replacing a module with only one
|
||||||
function of interest. An attacker that has the ability to shadow the
|
function of interest. An attacker that has the ability to shadow the
|
||||||
``sys`` module is already capable of running arbitrary code from files,
|
``sys`` module is already capable of running arbitrary code from files,
|
||||||
whereas an ``audit`` module can be replaced with a single statement::
|
whereas an ``audit`` module can be replaced with a single line in a
|
||||||
|
``.pth`` file anywhere on the search path::
|
||||||
|
|
||||||
import sys; sys.modules['audit'] = type('audit', (object,),
|
import sys; sys.modules['audit'] = type('audit', (object,),
|
||||||
{'audit': lambda *a: None, 'addhook': lambda *a: None})
|
{'audit': lambda *a: None, 'addhook': lambda *a: None})
|
||||||
|
@ -425,28 +432,27 @@ against either ``sys`` or ``audit``, but assignments or insertions to
|
||||||
``sys.modules`` are not audited.
|
``sys.modules`` are not audited.
|
||||||
|
|
||||||
This idea is rejected because it makes substituting ``audit`` calls
|
This idea is rejected because it makes substituting ``audit`` calls
|
||||||
throughout all callers near trivial.
|
throughout all callers trivial.
|
||||||
|
|
||||||
Flag in sys.flags to indicate "secure" mode
|
Flag in sys.flags to indicate "audited" mode
|
||||||
-------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
The proposal is to add a value in ``sys.flags`` to indicate when Python
|
The proposal is to add a value in ``sys.flags`` to indicate when Python
|
||||||
is running in a "secure" mode. This would allow applications to detect
|
is running in a "secure" or "audited" mode. This would allow
|
||||||
when some features are enabled and modify their behaviour appropriately.
|
applications to detect when some features are enabled or when hooks
|
||||||
|
have been added and modify their behaviour appropriately.
|
||||||
|
|
||||||
Currently there are no guarantees made about security by this PEP - this
|
Currently, we are not aware of any legitimate reasons for a program to
|
||||||
section is the first time the word "secure" has been used. Security
|
behave differently in the presence of audit hooks.
|
||||||
**transparency** does not result in any changed behaviour, so there is
|
|
||||||
no appropriate reason for applications to modify their behaviour.
|
|
||||||
|
|
||||||
Both application-level APIs ``sys.audit`` and ``_imp.open_for_import``
|
Both application-level APIs ``sys.audit`` and
|
||||||
are always present and functional, regardless of whether the regular
|
``importlib.util.open_for_import`` are always present and functional,
|
||||||
``python`` entry point or some alternative entry point is used. Callers
|
regardless of whether the regular ``python`` entry point or some
|
||||||
cannot determine whether any hooks have been added (except by performing
|
alternative entry point is used. Callers cannot determine whether any
|
||||||
side-channel analysis), nor do they need to. The calls should be fast
|
hooks have been added (except by performing side-channel analysis), nor
|
||||||
enough that callers do not need to avoid them, and the sysadmin is
|
do they need to. The calls should be fast enough that callers do not
|
||||||
responsible for ensuring their added hooks are fast enough to not affect
|
need to avoid them, and the program is responsible for ensuring that
|
||||||
application performance.
|
any added hooks are fast enough to not affect application performance.
|
||||||
|
|
||||||
The argument that this is "security by obscurity" is valid, but
|
The argument that this is "security by obscurity" is valid, but
|
||||||
irrelevant. Security by obscurity is only an issue when there are no
|
irrelevant. Security by obscurity is only an issue when there are no
|
||||||
|
@ -459,16 +465,23 @@ This idea is rejected because there are no appropriate reasons for an
|
||||||
application to change its behaviour based on whether these APIs are in
|
application to change its behaviour based on whether these APIs are in
|
||||||
use.
|
use.
|
||||||
|
|
||||||
|
Relationship to PEP 551
|
||||||
|
=======================
|
||||||
|
|
||||||
Acknowledgments
|
This API was originally presented as part of
|
||||||
===============
|
`PEP 551 <https://www.python.org/dev/peps/pep-0551/>`_ Security
|
||||||
|
Transparency in the Python Runtime.
|
||||||
|
|
||||||
Thanks to all the people from Microsoft involved in helping make the
|
For simpler review purposes, and due to the broader applicability of
|
||||||
Python runtime safer for production use, and especially to James Powell
|
these APIs beyond security, the API design is now presented separately.
|
||||||
for doing much of the initial research, analysis and implementation, Lee
|
|
||||||
Holmes for invaluable insights into the info-sec field and PowerShell's
|
PEP 551 is an informational PEP discussing how to integrate Python into
|
||||||
responses, and Brett Cannon for the restraining and grounding
|
a secure or audited environment.
|
||||||
discussions.
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. [1] Python Performance Benchmark Suite `<https://github.com/python/performance>`_
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
=========
|
=========
|
||||||
|
|
Loading…
Reference in New Issue