Coordinated Disclosure Timeline

Summary

MkDocs is vulnerable to an unsafe deserialization when parsing configuration files.

Note: After a private discussion with the maintainer, we agreed that a complete fix was not possible given the nature of the project. Instead, there were some partial fixes and documentation updates done on the project.

Project

MkDocs

Tested Version

1.5.3

Details

Unsafe deserialization of configuration files (GHSL-2023-208)

MkDocs uses the YAML format for configuration files such as mkdocs.yml and mkdocs_theme.yml. They are loaded using mkdocs.utils.yaml_load (see how mkdocs.yml and mkdocs_theme.yml are loaded), which, if not provided a loader, will use yaml.Loader, known to be able to instantiate arbitrary constructors.

# https://github.com/mkdocs/mkdocs/blob/00b648f0884244a139f034554b59a032113176f6/mkdocs/utils/yaml.py#L124
def get_yaml_loader(loader=yaml.Loader, config: MkDocsConfig | None = None):
    """Wrap PyYaml's loader so we can extend it to suit our needs."""

    class Loader(loader):
        """
        Define a custom loader derived from the global loader to leave the
        global loader unaltered.
        """

    # ...

    return Loader

def yaml_load(source: IO | str, loader: type[yaml.BaseLoader] | None = None) -> dict[str, Any]:
    """Return dict of source YAML file using loader, recursively deep merging inherited parent."""
    loader = loader or get_yaml_loader()
    try:
        result = yaml.load(source, Loader=loader)
    except yaml.YAMLError as e:
        raise exceptions.ConfigurationError(
            f"MkDocs encountered an error parsing the configuration file: {e}"
        )

This issue was found using the Unsafe deserialization CodeQL query for python.

Impact

This issue may lead to Remote Code Execution.

Proof of concept

Resources

Note

Even though the unsafe deserialization of mkdocs.yml has already been discussed and noted as a Won’t Fix given the downsides for the project, there’s still a huge risk in the unsafe deserialization of mkdocs_theme.yml. An attacker may be able to hijack a popular theme, or widely-spread one, and gain access to CI/CD systems and/or developer machines.

Credit

This issue was discovered and reported by GHSL team member @jorgectf (Jorge Rosillo).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2023-208 in any communication regarding this issue.