
wordexp(3)은 C에서 셸 방식의 확장을 수행하는 POSIX API다. ~/foo를 /home/me/foo처럼 바꾸는 물결표 확장에 쓰라고 권하는 경우가 있지만, 기본 설정에서는 명령 치환을 포함한 모든 확장 기능이 활성화된다.
예를 들어 입력에 $(whoami)/foo나 $(cat /etc/passwd)/foo가 포함되면 명령이 실행될 수 있다. 플래그 인수에 WRDE_NOCMD를 전달해 명령 치환을 막을 수 있지만, 일부 libc 구현에서는 이 방법도 안전을 보장하지 못한다.
- musl은 시스템 셸에 처리를 맡기기 전에 명령 치환을 간단히 검사하지만, GNU Bash 같은 셸이 유효한 명령 치환으로 받아들이는 일부 패턴은 잡아내지 못한다는 설명이다.
- macOS의 libc도
/usr/lib/system/wordexp-helper에 처리를 맡기는 비슷한 방식이다. Julian Squires에 따르면 2023년에도 musl과 같은 우회가 가능했지만, 기본 셸이 Bash에서 zsh로 바뀐 뒤에도 여전히 유효한지는 확인하지 않았다.
따라서 이 글은 WRDE_NOCMD를 설정하더라도 신뢰할 수 없는 입력에 wordexp(3)를 사용하지 말라고 권한다. macOS의 wordexp(3)는 과거 Perl을 실행했으며, wordexp-helper는 그 뒤의 ‘현대적’ 대안으로 보인다고 덧붙인다.
부록: 원문 예시
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wordexp.h>
int expand_tilde(const char *input, char **output) {
wordexp_t p;
int ret = wordexp(input, &p, 0);
if (ret == 0) {
*output = strdup(p.we_wordv[0]);
wordfree(&p);
}
return ret;
}
int main(void) {
char *expanded = NULL;
expand_tilde("~/foo", &expanded);
printf("expanded: %s\n", expanded);
return 0;
}
expand_tilde("$(whoami)/foo", &expanded);
expand_tilde("$(cat /etc/passwd)/foo", &expanded);
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요