Tailscale SSH "-i" 사용자명으로 root 접근 허용하는 취약점, 1.98.9에서 총 4건 패치
- Tailscale SSH가 하이픈으로 시작하는 사용자명을 검증 없이
getent(1)인자로 넘겨, 사용자명을-i로 접속하면--no-idn플래그로 해석되어 passwd 파일 전체가 출력되고 root 인터랙티브 세션이 열림 - Tailscale SSH는 사용자명 대신 숫자 UID로도 접속 가능했는데 ACL의 root 제한은 사용자명만 검사해,
0@host로 접속하면 autogroup:nonroot 제한을 우회해 root 권한 획득 가능했음 - Tailscale Serve/Funnel은 요청 경로가 "/"로 시작하지 않으면 상위 디렉터리 탐색 루프가 무한 반복되어 CPU 코어 하나를 영구 점유하는 DoS 취약점이 있었음, Funnel의 경우 인터넷상 인증되지 않은 호스트도 공격 가능
- Tailscale Services는 광고하지 않은 포트로 들어온 패킷을 노드의 loopback 리스너로 그대로 전달해, ACL 권한만 있으면 loopback 전용으로 격리된 프로세스에 원격 접근 가능했음
- 네 가지 취약점 모두 버전 1.98.9에서 수정됐고, 신고자는 Anthropic과 Ada Logics
Hacker News opinions
이거 완전 옛날부터 있던 버그 종류잖아, AIX 3 시절부터 있었던 거임. -i로 로그인하면 root 되는 거 진짜 클래식하네.
비슷하게 몇몇 클라우드 서비스에서도 환경변수에 파라미터 넣어서 같은 효과 낼 수 있어.
근데 SSH 로그인 프로세스가 기본적으로 root 로그인까지 가능한 권한을 갖고 있다는 게 더 신경 쓰이는데, 왜 그렇게 설계된 거지?
그럼 Tailscale로 접근 주고 OpenSSH 쓰면 안전한 거지?
맞음, 이 버그는 Tailscale이 관리하는 ACL 래퍼에서만 발생하는 문제라 OpenSSH 자체는 영향 없음.
CVE 대신 자체 번호(TS-2026-009) 쓰는 이유가 뭐야?
자체 번호 쓰면 공개 시점이랑 서술을 회사가 직접 통제할 수 있어서 그런 거임. CNA 되면 나중에 CVE 번호도 따로 붙긴 함.
'하이픈으로 시작하는 사용자명 거부'가 진짜 수정이라고? --로 인자 구분하는 게 제대로 된 방법인데.
그냥 재발 방지용 방어선일 뿐이지, 진짜 수정은 아예 명령어 shell out 안 하고 getpwnam(3) 같은 함수 쓰는 거임.
--도 getent 버전마다 동작 안 하는 경우 있어서, 그냥 유저 입력 없이 getent passwd 통째로 불러서 파싱하는 게 제일 확실함.
나는 Tailscale 열심히 쓰는데 SSH 기능은 한 번도 안 씀. OpenSSH 보안 트랙레코드가 워낙 좋아서 굳이 바꿀 이유를 못 느낌.
이 SSH 취약점은 공격자가 이미 네트워크 안에 있어야 성립하는 거라, ACL 위반이긴 해도 외부에서 바로 root 따는 것보다는 나은 상황이긴 함.
Tailscale SSH가 22번 포트를 그냥 가져가버려서 예전에 골치 아팠음, 별로 안 좋아함.
그건 원래 그렇게 동작하는 거임, 숨겨진 동작 아니고 Tailscale 인터페이스 쪽 22번만 가져가는 거라 다른 서비스랑은 안 겹침.
난 그냥 100% 셀프호스팅 Wireguard 계속 쓸래.
25년 묵은 검증된 코드베이스를 스타트업이 Go로 새로 짜놓고 버그 나오니까 놀라는 척하는 거 좀 웃김.
Rust로 재작성한다고 해도 이건 순수 로직 에러라 못 막음. clap 같은 표준 argument 파싱 크레이트 썼으면 이런 일 자체가 안 생겼을 거임.
Tailscale이 root로 도는 부분이 계속 늘어나면 이런 root 우회 경로도 계속 나올 듯.
사용자명 제한하는 대신 근본적인 권한 처리 로직을 고치는 게 맞는 방향 아니야?
보안 공지는 냈는데 Docker Hub 이미지는 8일 전에 마지막 업데이트라 실제 패치 배포가 너무 느림, 이런 식이면 공지 의미가 없음.