VYPR
Moderate severityNVD Advisory· Published Mar 26, 2024· Updated Feb 13, 2025

Apache Airflow: Potentially harmful permission changing by log task handler

CVE-2024-29735

Description

Improper Preservation of Permissions vulnerability in Apache Airflow.This issue affects Apache Airflow from 2.8.2 through 2.8.3.

Airflow's local file task handler in Airflow incorrectly set permissions for all parent folders of log folder, in default configuration adding write access to Unix group of the folders. In the case Airflow is run with the root user (not recommended) it added group write permission to all folders up to the root of the filesystem.

If your log files are stored in the home directory, these permission changes might impact your ability to run SSH operations after your home directory becomes group-writeable.

This issue does not affect users who use or extend Airflow using Official Airflow Docker reference images ( https://hub.docker.com/r/apache/airflow/ ) - those images require to have group write permission set anyway.

You are affected only if you install Airflow using local installation / virtualenv or other Docker images, but the issue has no impact if docker containers are used as intended, i.e. where Airflow components do not share containers with other applications and users.

Also you should not be affected if your umask is 002 (group write enabled) - this is the default on many linux systems.

Recommendation for users using Airflow outside of the containers:

  • if you are using root to run Airflow, change your Airflow user to use non-root
  • upgrade Apache Airflow to 2.8.4 or above
  • If you prefer not to upgrade, you can change the https://airflow.apache.org/docs/apache-airflow/stable/configurations-ref.html#file-task-handler-new-folder-permissions  to 0o755 (original value 0o775).
  • if you already ran Airflow tasks before and your default umask is 022 (group write disabled) you should stop Airflow components, check permissions of AIRFLOW_HOME/logs in all your components and all parent directories of this directory and remove group write access for all the parent directories

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2024-29735: Apache Airflow's local file task handler improperly sets group-write permissions on parent log directories, which can escalate to root if run as root, potentially disrupting SSH operations.

Vulnerability

Overview

CVE-2024-29735 is an Improper Preservation of Permissions vulnerability in Apache Airflow versions 2.8.2 through 2.8.3 [1][3]. The local file task handler, when writing logs, incorrectly sets permissions for all parent directories of the configured log folder. By default, this adds group write access to each parent directory, and when Airflow is executed as the root user (which is not recommended), the handler will propagate group write permission all the way up to the root of the filesystem [3][4].

Attack

Surface and Exploitation

The vulnerability is exploitable in local installations or virtualenv setups where Airflow is installed manually; users of the official Apache Airflow Docker reference images are not affected because those images already require group write permissions [3][4]. An attacker does not need network access or authentication to trigger the issue—it occurs automatically during normal task execution when the file task handler creates log directories. The risk is amplified if the log directory resides under the user's home directory, as the resulting group-writable home directory can interfere with SSH operations, which typically require strict permissions [3][4].

Impact

A successful exploitation allows a local attacker with membership in the affected Unix group (or any user who can traverse the directory tree) to write, modify, or delete files in previously protected directories. If the file permissions are relaxed up to the root, the entire filesystem could become group-writable, enabling privilege escalation or data tampering. The practical impact is particularly severe for users who run Airflow as root, as the permission changes can cascade to system-critical directories [3][4].

Mitigation and

Remediation

Apache has released Airflow version 2.8.4, which fixes the issue by ensuring that the file task handler does not alter permissions on parent directories [3][4]. For users unable to upgrade immediately, setting the file_task_handler_new_folder_permissions configuration option to 0o755 (instead of the default 0o775) prevents the addition of group write permissions [1][3]. Additional mitigations include running Airflow as a non-root user and, after an exposure, manually checking and removing group write access from AIRFLOW_HOME/logs and all its parent directories [3][4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
apache-airflowPyPI
>= 2.8.2, < 2.8.42.8.4

Affected products

3

Patches

1
aae4a83cdfb3

Fix permissions of parent folders for log file handler (#37310)

https://github.com/apache/airflowJarek PotiukFeb 10, 2024via ghsa
2 files changed · +56 11
  • airflow/utils/log/file_task_handler.py+26 11 modified
    @@ -159,6 +159,31 @@ def _ensure_ti(ti: TaskInstanceKey | TaskInstance, session) -> TaskInstance:
             raise AirflowException(f"Could not find TaskInstance for {ti}")
     
     
    +def _change_directory_permissions_up(directory: Path, folder_permissions: int):
    +    """
    +    Change permissions of the given directory and its parents.
    +
    +    Only attempt to change permissions for directories owned by the current user.
    +
    +    :param directory: directory to change permissions of (including parents)
    +    :param folder_permissions: permissions to set
    +    """
    +    if directory.stat().st_uid == os.getuid():
    +        if directory.stat().st_mode % 0o1000 != folder_permissions % 0o1000:
    +            print(f"Changing {directory} permission to {folder_permissions}")
    +            try:
    +                directory.chmod(folder_permissions)
    +            except PermissionError as e:
    +                # In some circumstances (depends on user and filesystem) we might not be able to
    +                # change the permission for the folder (when the folder was created by another user
    +                # before or when the filesystem does not allow to change permission). We should not
    +                # fail in this case but rather ignore it.
    +                print(f"Failed to change {directory} permission to {folder_permissions}: {e}")
    +                return
    +        if directory.parent != directory:
    +            _change_directory_permissions_up(directory.parent, folder_permissions)
    +
    +
     class FileTaskHandler(logging.Handler):
         """
         FileTaskHandler is a python log handler that handles and reads task instance logs.
    @@ -484,17 +509,7 @@ def _prepare_log_folder(self, directory: Path):
                 conf.get("logging", "file_task_handler_new_folder_permissions", fallback="0o775"), 8
             )
             directory.mkdir(mode=new_folder_permissions, parents=True, exist_ok=True)
    -        if directory.stat().st_mode % 0o1000 != new_folder_permissions % 0o1000:
    -            print(f"Changing {directory} permission to {new_folder_permissions}")
    -            try:
    -                directory.chmod(new_folder_permissions)
    -            except PermissionError as e:
    -                # In some circumstances (depends on user and filesystem) we might not be able to
    -                # change the permission for the folder (when the folder was created by another user
    -                # before or when the filesystem does not allow to change permission). We should not
    -                # fail in this case but rather ignore it.
    -                print(f"Failed to change {directory} permission to {new_folder_permissions}: {e}")
    -                pass
    +        _change_directory_permissions_up(directory, new_folder_permissions)
     
         def _init_file(self, ti, *, identifier: str | None = None):
             """
    
  • tests/utils/test_log_handlers.py+30 0 modified
    @@ -21,6 +21,8 @@
     import logging.config
     import os
     import re
    +import shutil
    +import tempfile
     from pathlib import Path
     from unittest import mock
     from unittest.mock import patch
    @@ -40,6 +42,7 @@
     from airflow.utils.log.file_task_handler import (
         FileTaskHandler,
         LogType,
    +    _change_directory_permissions_up,
         _interleave_logs,
         _parse_timestamps_in_log_file,
     )
    @@ -719,3 +722,30 @@ def test_interleave_logs_correct_ordering():
         """
     
         assert sample_with_dupe == "\n".join(_interleave_logs(sample_with_dupe, "", sample_with_dupe))
    +
    +
    +def test_permissions_for_new_directories():
    +    tmp_path = Path(tempfile.mkdtemp())
    +    try:
    +        # Set umask to 0o027: owner rwx, group rx-w, other -rwx
    +        old_umask = os.umask(0o027)
    +        try:
    +            subdir = tmp_path / "subdir1" / "subdir2"
    +            # force permissions for the new folder to be owner rwx, group -rxw, other -rwx
    +            new_folder_permissions = 0o700
    +            # default permissions are owner rwx, group rx-w, other -rwx (umask bit negative)
    +            default_permissions = 0o750
    +            subdir.mkdir(mode=new_folder_permissions, parents=True, exist_ok=True)
    +            assert subdir.exists()
    +            assert subdir.is_dir()
    +            assert subdir.stat().st_mode % 0o1000 == new_folder_permissions
    +            # initially parent permissions are as per umask
    +            assert subdir.parent.stat().st_mode % 0o1000 == default_permissions
    +            _change_directory_permissions_up(subdir, new_folder_permissions)
    +            assert subdir.stat().st_mode % 0o1000 == new_folder_permissions
    +            # now parent permissions are as per new_folder_permissions
    +            assert subdir.parent.stat().st_mode % 0o1000 == new_folder_permissions
    +        finally:
    +            os.umask(old_umask)
    +    finally:
    +        shutil.rmtree(tmp_path)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.