mirror of
https://github.com/certbot/certbot.git
synced 2025-07-31 20:04:25 +03:00
[Windows] Security model for files permissions - STEP 2 (#6895)
This PR is the second part of #6497 to ease the integration, following the new plan propose by @bmw here: #6497 (comment) This PR creates the module certbot.compat.os, that delegates everything to os, and that will be the safeguard against problematic methods of the standard module. On top of that, a quality check wrapper is called in the lint tox environment. This wrapper calls pylint and ensures that standard os module is no used directly in the certbot codebase. Finally local oldest requirements are updated to ensure that tests will take the new logic when running. * Add executable permissions * Add the delegate certbot.compat.os module, add check coding style to enforce usage of certbot.compat.os instead of standard os * Load certbot.compat.os instead of os * Move existing compat test * Update local oldest requirements * Import sys * Update account_test.py * Update os.py * Update os.py * Update local oldest requirements * Implement the new linter_plugin * Fix local oldest for nginx * Remove check coding style * Update linter_plugin.py * Add several comments * Update the setup.py * Add documentation * Update acme dependencies * Update certbot/compat/os.py * Update docs/contributing.rst * Update linter_plugin.py * Handle os.path. Simplify checker. * Add a comment to a reference implementation * Update changelog * Fix module registering * Update docs/contributing.rst * Update config and changelog
This commit is contained in:
committed by
Brad Warren
parent
9c54f3dec8
commit
d5de24d9fc
@ -1,31 +1,51 @@
|
||||
"""Certbot ACME PyLint plugin.
|
||||
|
||||
"""Certbot PyLint plugin.
|
||||
http://docs.pylint.org/plugins.html
|
||||
|
||||
"""
|
||||
from astroid import MANAGER
|
||||
from astroid import nodes
|
||||
# The built-in ImportChecker of Pylint does a similar job to ForbidStandardOsModule to detect
|
||||
# deprecated modules. You can check its behavior as a reference to what is coded here.
|
||||
# See https://github.com/PyCQA/pylint/blob/b20a2984c94e2946669d727dbda78735882bf50a/pylint/checkers/imports.py#L287
|
||||
from pylint.checkers import BaseChecker
|
||||
from pylint.interfaces import IAstroidChecker
|
||||
|
||||
|
||||
def register(unused_linter):
|
||||
"""Register this module as PyLint plugin."""
|
||||
pass
|
||||
# Modules in theses packages can import the os module.
|
||||
WHITELIST_PACKAGES = ['acme', 'certbot_compatibility_test', 'letshelp_certbot', 'lock_test']
|
||||
|
||||
|
||||
def _transform(cls):
|
||||
# fix the "no-member" error on instances of
|
||||
# letsencrypt.acme.util.ImmutableMap subclasses (instance
|
||||
# attributes are initialized dynamically based on __slots__)
|
||||
class ForbidStandardOsModule(BaseChecker):
|
||||
"""
|
||||
This checker ensures that standard os module (and submodules) is not imported by certbot
|
||||
modules. Otherwise a 'os-module-forbidden' error will be registered for the faulty lines.
|
||||
"""
|
||||
__implements__ = IAstroidChecker
|
||||
|
||||
# TODO: this is too broad and applies to any tested class...
|
||||
name = 'forbid-os-module'
|
||||
msgs = {
|
||||
'E5001': (
|
||||
'Forbidden use of os module, certbot.compat.os must be used instead',
|
||||
'os-module-forbidden',
|
||||
'Some methods from the standard os module cannot be used for security reasons on Windows: '
|
||||
'the safe wrapper certbot.compat.os must be used instead in Certbot.'
|
||||
)
|
||||
}
|
||||
priority = -1
|
||||
|
||||
#if cls.slots() is not None:
|
||||
# for slot in cls.slots():
|
||||
# cls.locals[slot.value] = [nodes.EmptyNode()]
|
||||
def visit_import(self, node):
|
||||
os_used = any(name for name in node.names if name[0] == 'os' or name[0].startswith('os.'))
|
||||
if os_used and not _check_disabled(node):
|
||||
self.add_message('os-module-forbidden', node=node)
|
||||
|
||||
if cls.name == 'JSONObjectWithFields':
|
||||
# _fields is magically introduced by JSONObjectWithFieldsMeta
|
||||
cls.locals['_fields'] = [nodes.EmptyNode()]
|
||||
def visit_importfrom(self, node):
|
||||
if node.modname == 'os' or node.modname.startswith('os.') and not _check_disabled(node):
|
||||
self.add_message('os-module-forbidden', node=node)
|
||||
|
||||
|
||||
MANAGER.register_transform(nodes.Class, _transform)
|
||||
def register(linter):
|
||||
"""Pylint hook to auto-register this linter"""
|
||||
linter.register_checker(ForbidStandardOsModule(linter))
|
||||
|
||||
|
||||
def _check_disabled(node):
|
||||
module = node.root()
|
||||
return any(package for package in WHITELIST_PACKAGES
|
||||
if module.name.startswith(package + '.') or module.name == package)
|
||||
|
Reference in New Issue
Block a user