🇰🇷 한글 설명
keyring_info.py 모듈이 OS 네이티브 키링에서 가져온 비밀번호를 출력 시 보호 조치 없이 그대로 노출하는 취약점입니다. 이로 인해 마스터 비밀번호나 SSH 키 암호와 같은 민감한 정보가 Ansible 로그 및 캐시 시스템에 평문으로 저장될 수 있습니다.
💡 쉬운 설명
비밀번호를 안전하게 보관하는 도구에서 비밀번호를 꺼내올 때, 실수로 화면에 그대로 보여주는 보안 결함입니다. 이로 인해 로그 파일이나 관리 화면에 비밀번호가 글자 그대로 노출될 위험이 있습니다.
🇺🇸 원문 (English)
Module: plugins/modules/keyring_info.py
CVSS 3.1: 5.5 MEDIUM — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Issue: The module retrieves a passphrase from the OS native keyring (GNOME Keyring, macOS Keychain, Windows Credential Manager) and places it directly into result["passphrase"] with no output suppression, no no_log protection, and no documentation warning.
Root Cause:
Line 105 (protected): keyring_password=dict(type="str", required=True, no_log=True)
Line 127 (NOT protected): result["passphrase"] = passphrase
Observed Output:
{
"changed": false,
"passphrase": "MyMasterP@ssw0rd!SSH_Key_Secret"
}
Visible via register + debug:
{
"keyring_result": {
"changed": false,
"passphrase": "MyMasterP@ssw0rd!SSH_Key_Secret"
}
}
Impact:
Master passwords, SSH key passphrases and service credentials appear in all Ansible output
register: keyring_result followed by debug: var=keyring_result prints passphrase in full
Ansible fact caching backends (Redis, JSON file, memcached) may persist the passphrase
AWX/Tower job logs silently store the live credential
Fix:
module.exit_json(changed=False, passphrase=passphrase, _ansible_no_log=True)
Also add a documentation warning requiring callers to use no_log: true at the task level.
PoCs
Fig 1: PoC execution showing passphrase in plaintext output
Fig 2: Source code showing no_log=True on input (line 105) vs unprotected output (line 127)
📍 영향받는 시스템
Ansible keyring_info 모듈을 사용하는 시스템
⚔️ 공격 벡터
로컬 접근 권한을 가진 사용자가 Ansible 실행 로그, 디버그 출력 또는 팩트 캐시(Redis, JSON 등)를 확인하여 탈취
🛡️ 대응 방법
모듈 출력 시 _ansible_no_log=True 옵션을 적용하고, 사용자에게 작업 수준에서 no_log: true 사용을 권고하는 문서를 추가해야 합니다.
🔧 검증 코드
모듈의 결과값(result)에 passphrase 필드가 포함되어 있고, 해당 출력에 no_log 처리가 되어 있지 않으면 취약한 상태입니다.
python3 -c 'import ansible_modules; print("Check if keyring_info.py uses no_log for output")' 2>/dev/null