ossa/doc/source/guidelines/dg_using-file-paths.rst
Grant Murphy 84b5e7ec48 Import the OSSG secure development guidance
This introduces a number of secure development practices that were
written by the OSSG during the mid-cycle meetup of 2015.

Credit goes to the original authors and editors of this content:

    Dave Belcher (HP)
    Eric Brown (VMWare)
    Doug Chivers (HP)
    Rob Clarke (HP)
    Nathaniel Dillon (HP)
    Lucas Fisher (Was Nebula)
    Jamie Finnigan (HP)
    Rob Fletcher (Uber)
    Tim Kelsey (HP)
    Brant Knudson (IBM)
    Paul McMillan (Was Nebula)
    Travis McPeak (HP)
    Grant Murphy (HP)

The following is an attempt to track the origins on this content as it
was developed. It is not a complete version history but indicates the
initial import of the content into respective repositories prior to
ending up here. Hopefully this will be enough to track the changes
and contributions made by members of the OpenStack community.

{
    "origins": [
        {
            "author": "Travis McPeak (HP)",
            "file": "doc/source/guidelines/dg_apply-restrictive-file-permissions.rst",
            "history": [
                {
                    "commit": "d5f6ad970ec24564cfaffc13dba26b0006841d5b",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "c7d0e14e9a71fa9bbe301aa76a8adcc55ade52de",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Lucas Fisher (Nebula)",
            "file": "doc/source/guidelines/dg_avoid-dangerous-input-parsing-libraries.rst",
            "history": [
                {
                    "commit": "9f12b0bacc7bf207df5615dce39940aaede66e17",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "9b4181fe3c2e5451ebf65b99b05fe169b6eda63c",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Paul McMillan (Nebula)",
            "comment": "The file was not renamed correctly!",
            "file": "doc/source/guidelines/dg_avoid-shell-true.rst",
            "history": [
                {
                    "commit": "ef6338caa2a6f5cfb67dd2d77a38574d45ae5d2c",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "c7ade476015c1b0fbb1b100b990a10e8373027c2",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Grant Murphy (HP)",
            "file": "doc/source/guidelines/dg_avoid-unvalidated-redirects.rst",
            "history": [
                {
                    "commit": "2f0c954bd4f25a06b8a1439739d494c3a9d0c2de",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "8fb7804da189c95e9bcd2b19b516077b8fb6a44a",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Dave Belcher (HP)",
            "file": "doc/source/guidelines/dg_cross-site-request-forgery-csrf.rst",
            "history": [
                {
                    "commit": "34146ded7f5c8ca3b0be29c17b30fb887a47b955",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "688a73070e52a693f1fc7b827cfbfe1d03bd7f9c",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Dave Belcher (HP)",
            "file": "doc/source/guidelines/dg_cross-site-scripting-xss.rst",
            "history": [
                {
                    "commit": "f4261162a2b07df282fbfab68245b23c39f46fb9",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "e8a3cf91778081e0c822277951c0f5cbc6293c21",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Rob Clarke (HP)",
            "file": "doc/source/guidelines/dg_move-data-securely.rst",
            "history": [
                {
                    "commit": "5d57e38c71ec7fd9113bb5574c143b4b146b95d5",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "6d266e56a1b4b746deab7b26d6b8bf96774dca72",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Tim Kelsey",
            "file": "doc/source/guidelines/dg_parameterize-database-queries.rst",
            "history": [
                {
                    "commit": "70969ec41f9ce5de47090ac7a5cb4e303671b756",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Eric Brown (VMware)",
            "file": "doc/source/guidelines/dg_protect-sensitive-data-in-files.rst",
            "history": [
                {
                    "commit": "038d65e6fd8c17dffa28f55c99e218d09802f5ec",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "8094050151347ac83b6a05c5895dc9f670b70c29",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Eric Brown (VMware)",
            "file": "doc/source/guidelines/dg_validate-certificates.rst",
            "history": [
                {
                    "commit": "f74fecc0360a9f9c6984d821b128c4830bd71b0f",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "2ffd29660d9f48079ab1c9a0de170eb660ba22fe",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Lucas Fisher (Nebula)",
            "file": "doc/source/guidelines/dg_rootwrap-recommendations-and-plans.rst",
            "history": [
                {
                    "commit": "bd5a51411420fd70ee410ff72cb396287ce0c60e",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "6a13d1ecd8ec73f7038c8e3238e24ac32ac60e58",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Jamie Finnigan (HP)",
            "file": "doc/source/guidelines/dg_strong-crypto.rst",
            "history": [
                {
                    "commit": "cefac3ea2ab56e4e7c6238f69f63b7f88d1b58ec",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "4d430b4cf18687b322c931f1bddf8147da853bb5",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Eric Brown (VMware)",
            "file": "doc/source/guidelines/dg_use-oslo-rootwrap-securely.rst",
            "history": [
                {
                    "commit": "921f9fc2d949a6a48ba8c936a81b7f15024e50f8",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "3fc0ca5df47cd118d111e6020e1f1101b3c4fbc3",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Paul McMillan (Nebula)",
            "file": "doc/source/guidelines/dg_use-subprocess-securely.rst",
            "history": [
                {
                    "commit": "7a305304d600b1e0d868e1fa174d31bdb460c041",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "f4ccd51a10ca0380737d6be8bc5ae6c677a60b39",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "Grant Murphy (HP)",
            "file": "doc/source/guidelines/dg_using-file-paths.rst",
            "history": [
                {
                    "commit": "f2d93147e7b8e30750b2f6ad548a1478f74e4489",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "d8593eaea31e9d4756005555dfb85f41013ee6d4",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        },
        {
            "author": "b005cc2968ecbcdbf7cc455ecac1e8ede2b2fa21",
            "file": "doc/source/guidelines/dg_using-temporary-files-securely.rst",
            "history": [
                {
                    "commit": "cf1981af0bba72558b8cfa349d841ceee4722b7f",
                    "id": "1",
                    "repo": "git://github.com/hyakuhei/OSSG-Security-Practices"
                },
                {
                    "commit": "",
                    "id": "2",
                    "repo": "github.com/openstack-security/Developer-Guidance"
                }
            ]
        }
    ]
}

Change-Id: I8ae30f526523860c0fc069cf1e683f1b8a69eb4d
2015-05-15 16:46:46 -07:00

136 lines
4.3 KiB
ReStructuredText

.. :Copyright: 2015, OpenStack Foundation
.. :License: This work is licensed under a Creative Commons
Attribution 3.0 Unported License.
http://creativecommons.org/licenses/by/3.0/legalcode
Restrict path access to prevent path traversal
==============================================
Often we will refer to a file on disk or other resource using a path. A path
traversal attack is when an attacker supplies input that gets used with our
path to access a file on the file system that we did not intend. The input
usually attempts to break out of the application's working directory and access
a file elsewhere on the file system. This category of attack can be mitigated
by restricting the scope of file system access and reducing attack surface by
using a restricted file permission profile.
Incorrect
~~~~~~~~~
A typical remote vector for path traversal in web applications might involve
serving or storing files on the file system. Consider the following example:
.. code:: python
import os
from flask import Flask, redirect, request, send_file
app = Flask(__name__)
@app.route('/')
def cat_picture():
image_name = request.args.get('image_name')
if not image_name:
return 404
return send_file(os.path.join(os.getcwd(), image_name))
if __name__ == '__main__':
app.run(debug=True)
As the attacker controls the input that is used directly in constructing a path
they are able to access any file on the system. For example consider what
happens if an attacker makes a request like:
::
curl http://example.com/?image_name=../../../../../../../../etc/passwd
Path traversal flaws also can happen when unpacking a compressed archive of
files. An example of where this has happened within OpenStack is
`OSSA-2011-001 <http://security.openstack.org/ossa/OSSA-2011-001.html>`__. In
this case a tar file from an untrusted source could be unpacked to overwrite
files on the host operating system.
.. code:: python
import tarfile
def untar_image(path, filename):
tar_file = tarfile.open(filename, 'r|gz')
tar_file.extract_all(path)
image_file = tar_file.get_names()[0]
tar_file.close()
return os.path.join(path, image_file)
Correct
~~~~~~~
The following example demonstrates how you can use python code to restrict
access to files within a specific directory. This can be used as a mechanism to
defeat path traversal.
.. code:: python
import os
import sys
def is_safe_path(basedir, path, follow_symlinks=True):
# resolves symbolic links
if follow_symlinks:
return os.path.realpath(path).startswith(basedir)
return os.path.abspath(path).startswith(basedir)
def main(args):
for arg in args:
if is_safe_path(os.getcwd(), path):
print("safe: {}".format(arg))
else:
print("unsafe: {}".format(arg))
if __name__ == "__main__":
main(sys.argv[1:])
Another approach to restricting file system access to maintain an indirect
mapping between a unique identifier and a file path that exists on the
operating system. This prevents users supplying malicious input to access
unintended files.
.. code:: python
localfiles = {
"01" : "/var/www/img/001.png",
"02" : "/var/www/img/002.png",
"03" : "/var/www/img/003.png",
}
# Will raise an error if an invalid key is used.
def get_file(file_id):
return open(localfiles[file_id])
Consequences
~~~~~~~~~~~~
Not validating file paths allows the attacker to read or write to any file
that the application has access to. This can lead to information leakage and
can be used to pivot to other more serious attacks like remote code execution.
- `OSSA-2011-001 <http://security.openstack.org/ossa/OSSA-2011-001.html>`__
- `OSSA-2014-041 <http://security.openstack.org/ossa/OSSA-2014-041.html>`__
- `OSSA-2015-002 <http://security.openstack.org/ossa/OSSA-2015-002.html>`__
References
~~~~~~~~~~
- `CWE-22: Improper Limitation of a Pathname to a Restricted
Directory <http://cwe.mitre.org/data/definitions/22.html>`__
- `OWASP: Path
Traversal <https://www.owasp.org/index.php/Path_Traversal>`__
- `Wikipedia: Directory traversal
attack <http://en.wikipedia.org/wiki/Directory_traversal_attack>`__