This is an automated email from the ASF dual-hosted git repository.

vatsrahul1001 pushed a commit to branch v3-4-test
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/v3-4-test by this push:
     new b06c51bfe82 [v3-4-test] Redact secrets written through 
RedactedIO.writelines() (#72063) (#75463)
b06c51bfe82 is described below

commit b06c51bfe825aa99573c2cc37dd0f453bb2d5964
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Sat Oct 24 16:09:06 2026 +0530

    [v3-4-test] Redact secrets written through RedactedIO.writelines() (#72063) 
(#75463)
    
    RedactedIO exists so that output produced by user code is masked before it
    reaches stdout, and its docstring says "Writes to stdout will be redacted".
    write() applied redact(); writelines() forwarded straight to the target, so 
a
    secret written that way was printed verbatim.
    
    The one call site is task_test() in cli/commands/task_command.py, so this is
    reachable from `airflow tasks test`, which deliberately routes task output 
up
    to the console handler for local debugging.
    
    Non-string elements now stringify rather than raising TypeError, matching 
what
    write() already does.
    (cherry picked from commit 3d5c533cccc75a4c9fb2093782fa2fbe67747be1)
    
    Co-authored-by: Mahathir Mohammad Shuvo 
<[email protected]>
---
 .../src/airflow_shared/secrets_masker/secrets_masker.py             | 2 +-
 shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py   | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git 
a/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py 
b/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py
index 1286e296f12..178b451c10b 100644
--- a/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py
+++ b/shared/secrets_masker/src/airflow_shared/secrets_masker/secrets_masker.py
@@ -719,4 +719,4 @@ class RedactedIO(TextIO):
         return self.target.write(s)
 
     def writelines(self, lines) -> None:
-        self.target.writelines(lines)
+        self.target.writelines(str(redact(line)) for line in lines)
diff --git a/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py 
b/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py
index 7bd72c101c1..f993a723eba 100644
--- a/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py
+++ b/shared/secrets_masker/tests/secrets_masker/test_secrets_masker.py
@@ -973,6 +973,12 @@ class TestRedactedIO:
         stdout = capsys.readouterr().out
         assert stdout == "***"
 
+    def test_writelines(self, capsys):
+        RedactedIO().writelines([f"{PASSWORD}\n", f"and {PASSWORD}\n"])
+        stdout = capsys.readouterr().out
+        assert stdout == "***\nand ***\n"
+        assert PASSWORD not in stdout
+
     def test_input_builtin(self, monkeypatch):
         """
         Test that when redirect is inplace the `input()` builtin works.

Reply via email to