Skip to content

chore(deps): update dependency lxml to v6.1.0 [security] - autoclosed#19194

Closed
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/pypi-lxml-vulnerability
Closed

chore(deps): update dependency lxml to v6.1.0 [security] - autoclosed#19194
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/pypi-lxml-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
lxml (source, changelog) 6.0.46.1.0 age confidence

lxml: Default configuration of iterparse() and ETCompatXMLParser() allows XXE to local files

CVE-2026-41066 / GHSA-vfmq-68hx-4jfw

More information

Details

Impact

Using either of the two parsers in the default configuration (with resolve_entities=True) allows untrusted XML input to read local files.

Patches

lxml 6.1.0 changes the default to resolve_entities='internal', thus disallowing local file access by default.

Workarounds

Setting the resolve_entities option explicitly to resolve_entities='internal' or resolve_entities=False disables the local file access.

Resources

Original report: https://bugs.launchpad.net/lxml/+bug/2146291

The default option was changed to resolve_entities='internal' for the normal XML and HTML parsers in lxml 5.0. The default was not changed for iterparse() and ETCompatXMLParser() at the time. lxml 6.1 makes the safe option the default for all parsers.

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

lxml/lxml (lxml)

v6.1.0

Compare Source

==================

This release fixes a possible external entity injection (XXE) vulnerability in
iterparse() and the ETCompatXMLParser.

Features added

  • GH#486: The HTML ARIA accessibility attributes were added to the set of safe attributes
    in lxml.html.defs. This allows lxml_html_clean to pass them through.
    Patch by oomsveta.

  • The default chunk size for reading from file-likes in iterparse() is now configurable
    with a new chunk_size argument.

Bugs fixed

  • LP#2146291: The resolve_entities option was still set to True for
    iterparse and ETCompatXMLParser, allowing for external entity injection (XXE)
    when using these parsers without setting this option explicitly.
    The default was now changed to 'internal' only (as for the normal XML and HTML parsers
    since lxml 5.0).
    Issue found by Sihao Qiu as CVE-2026-41066.

Configuration

📅 Schedule: (UTC)

  • Branch creation
    • ""
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the dependencies PR: Third-party library dependencies. label Apr 23, 2026
@renovate renovate Bot enabled auto-merge (squash) April 23, 2026 11:51
@renovate renovate Bot force-pushed the renovate/pypi-lxml-vulnerability branch from 57a13c8 to 903059b Compare April 23, 2026 12:04
@argos-ci

argos-ci Bot commented Apr 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 19 changed Apr 23, 2026, 4:27 PM

@renovate renovate Bot force-pushed the renovate/pypi-lxml-vulnerability branch 3 times, most recently from d5845f6 to 3edd326 Compare April 23, 2026 14:10
@renovate renovate Bot force-pushed the renovate/pypi-lxml-vulnerability branch from 3edd326 to 4f586cf Compare April 23, 2026 15:37
@renovate renovate Bot changed the title chore(deps): update dependency lxml to v6.1.0 [security] chore(deps): update dependency lxml to v6.1.0 [security] - autoclosed Apr 23, 2026
@renovate renovate Bot closed this Apr 23, 2026
auto-merge was automatically disabled April 23, 2026 15:52

Pull request was closed

@renovate renovate Bot deleted the renovate/pypi-lxml-vulnerability branch April 23, 2026 15:52
@codecov

codecov Bot commented Apr 23, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
7084 1 7083 724
View the top 1 failed test(s) by shortest run time
weblate.trans.tests.test_commands.ImportDemoTestCase::test_import
Stack Traces | 3.6s run time
self = <weblate.trans.tests.test_commands.ImportDemoTestCase testMethod=test_import>

    def test_import(self) -> None:
        try:
            requests.get("https://github.com/", timeout=1)
        except requests.exceptions.ConnectionError as error:
            self.skipTest(f"GitHub not reachable: {error}")
        output = StringIO()
>       call_command("import_demo", stdout=output)

.../trans/tests/test_commands.py:443: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.12.../core/management/__init__.py:195: in call_command
    return command.execute(*args, **defaults)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../utils/management/base.py:40: in execute
    return super().execute(*args, **options)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.12.../core/management/base.py:460: in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.../management/commands/import_demo.py:52: in handle
    component = Component.objects.create(
.venv/lib/python3.12.../db/models/manager.py:87: in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.venv/lib/python3.12.../db/models/query.py:669: in create
    obj.save(force_insert=True, using=self.db)
.../trans/models/component.py:1130: in save
    self.after_save(
.../trans/models/component.py:4249: in after_save
    self.sync_git_repo(skip_push=skip_push, skip_commit=create)
.../trans/models/component.py:3667: in sync_git_repo
    self.repository.clone_from(self.repo)
weblate/vcs/base.py:612: in clone_from
    self._clone(source, self.path, self.branch)
weblate/vcs/git.py:325: in _clone
    cls._popen(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

cls = <class 'weblate.vcs.git.GitRepository'>
args = ['git', 'clone', '--depth', '1', '--branch', 'main', ...]

    @classmethod
    def _popen(
        cls,
        args: list[str],
        *,
        cwd: str | None = None,
        merge_err: bool = True,
        fullcmd: bool = False,
        raw: bool = False,
        local: bool = False,
        stdin: str | None = None,
        environment: dict[str, str] | None = None,
        retry: bool = True,
    ):
        """Execute the command using popen."""
        if args is None:
            raise RepositoryError(0, "Not supported functionality")
        if not fullcmd:
            args = [cls._cmd, *list(args)]
        text_cmd = " ".join(args)
        try:
            # These are mutually exclusive, gevent actually checks
            # for their presence, not a avalue
            kwargs: SubprocessArgs = {}
            if stdin is None:
                kwargs["stdin"] = subprocess.PIPE
            else:
                kwargs["input"] = stdin
    
            process = subprocess.run(
                args=args,
                cwd=cwd,
                env=environment or {} if local else cls._getenv(environment, cwd=cwd),
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT if merge_err else subprocess.PIPE,
                text=not raw,
                check=False,
                # Excessively long timeout to catch misbehaving processes
                timeout=3600,
                **kwargs,
            )
        except subprocess.TimeoutExpired as error:
            stdout = (
                error.stdout.decode()
                if isinstance(error.stdout, bytes)
                else error.stdout
            )
            stderr = (
                error.stderr.decode()
                if isinstance(error.stderr, bytes)
                else error.stderr
            )
            raise RepositoryCommandError(
                0,
                f"Subprocess didn't complete before {error.timeout} seconds\n{stdout}{stderr or ''}",
            ) from error
        cls.add_breadcrumb(
            text_cmd,
            retcode=process.returncode,
            output=process.stdout,
            stderr=process.stderr,
            cwd=cwd,
        )
        if process.returncode:
            errormessage: str = cls.sanitize_error_message(
                process.stdout + (process.stderr or "")
            )
            if retry and cls.should_retry_popen(errormessage):
                return cls._popen(
                    args,
                    cwd=cwd,
                    merge_err=merge_err,
                    fullcmd=fullcmd,
                    raw=raw,
                    local=local,
                    stdin=stdin,
                    environment=environment,
                    retry=False,
                )
    
>           raise RepositoryCommandError(process.returncode, errormessage)
E           weblate.vcs.base.RepositoryCommandError: Cloning into '.../vcs/demo/gettext'...
E           remote: Internal Server Error
E           fatal: unable to access 'https://github.com/WeblateOrg/demo.git/': The requested URL returned error: 500
E            (128)

weblate/vcs/base.py:480: RepositoryCommandError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies PR: Third-party library dependencies.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants