Skip to content

bpo-42988: Fix security issue in the pydoc server #24337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Jan 26, 2021

Route /getfile?key= no longer allows to get content of arbitrary file.
It serves now only source files of Python modules available to pydoc.

https://bugs.python.org/issue42988

Route `/getfile?key=` no longer allows to get content of arbitrary file.
It serves now only source files of Python modules available to pydoc.
Lib/pydoc.py Outdated
if path == sourcepath:
return
else:
raise ValueError('not found {found}')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this code can be factorized with ModuleScanner.run()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it cannot. ModuleScanner.run() contains too much specific to its primary function: it only calls callback if key is not None and is found in module name or description.

But it is a temporary solution. For 3.10 we can change API (pass not path, but a module name, so the loop will be unnecessary).

Copy link
Member

@Fidget-Spinner Fidget-Spinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran some tests on large codebases and I'm not sure why, but this doesn't seem to work when I launch it in conda environment with a pip installed editable mode local package. It seems that pkgutil.walk_packages() doesn't find the pip dependencies of editable package.

Granted this is a weird scenario, but I would think people want to see the docs of their own package they're developing locally.

Currently some example code that triggers it:
setup.py:

import setuptools
setuptools.setup(
    name="foo",
    version="0.0.0",
    author="a",
    author_email="b",
    description="Sample",
    long_description="Sample text",
    long_description_content_type="text/markdown",
    url="https://example.com",
    packages=[""],
    include_package_data=True,
    install_requires=["regex"],
    classifiers=[],
    python_requires='>=3.7',
)

__init__.py:

import regex

Then pydoc -b for this fails:

import foo

I'll report back if it affects venv or other stuff, maybe it's just my computer and it can't be reproduced anywhere else.

Lib/pydoc.py Outdated
@@ -2544,9 +2544,38 @@ def bltinlink(name):
'key = %s' % key, '#ffffff', '#ee77aa', '<br>'.join(results))
return 'Search Results', contents

def validate_source_path(path):
for importer, modname, ispkg in pkgutil.walk_packages():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkgutil.walk_packages() can seemingly fail if a module has no __version__. Eg. on my computer I get AttributeError for some weird packages:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "......\lib\pkgutil.py", line 92, in walk_packages
    __import__(info.name)
  File "......\lib\site-packages\brotli_asgi\__init__.py", line 12, in <module>
    brotli = import_brotli()
  File "......\lib\site-packages\brotli_asgi\_import_resolver.py", line 22, in import_brotli
    spec.loader.exec_module(brotli)
  File "......\lib\site-packages\brotli.py", line 12, in <module>
    __version__ = _brotli.__version__
AttributeError: module 'brotli._brotli' has no attribute '__version__'

Because:

>>> import brotli
>>> brotli._brotli
<module 'brotli._brotli' from '......\\lib\\site-packages\\brotli\\_brotli.cp38-win_amd64.pyd'>
>>> brotli._brotli.__version__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'brotli._brotli' has no attribute '__version__'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Fixed.

if path == sourcepath:
return
else:
raise ValueError('not found {found}')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I've randomly opened this PR. I'd like to ask you to check this error message, it looks like unfinished.

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Walking into all packages sounds overkill to me. Moreover, it doesn't prevent to read sensitiva data from Python modules source code.

I proposed a simpler approach in PR #25015: just remove the feature.

@vstinner
Copy link
Member

I merged PR #25015 fix instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants