변수를 루트 가능 스크립트에 안전하게 전달하는 방법은 무엇입니까? 이렇게하려면 /etc/sudoers이 줄을 포함 하도록 수정 하려고합니다. joe

이 질문은 완전히 일반적이며 내 상황에만 적용 할 수 있지만 루트 사용자가 아닌 사용자가 루트 권한으로 특정 스크립트를 실행할 수있게하려는 작은 busybox 장비가 있습니다. 예를 들어, $1cmdline (!!)에서 보낼 변수 ( ) 만 보낼 호스트 이름은 DHCP를 활성화하는이 작은 스크립트와 같은 것입니다.

#!/bin/bash
udhcpc -b -i eth0 -h $1

다음과 같이 udhcpc를 실행하려면 루트 액세스 권한이 필요합니다. 이렇게하려면 /etc/sudoers이 줄을 포함 하도록 수정 하려고합니다.

joe ALL = NOPASSWD: /path/to/enable_dhcp.sh

“joe”를 사용하면 간단하게 다음을 실행하여 루트 권한으로 해당 스크립트를 쉽게 실행할 수 있습니다.

sudo /path/to/enable_dhcp.sh

암호를 요구하지 않습니다 (joe가 이것을 스크립팅 할 수 있기를 원하기 때문에 원하는 것입니다).

이제 .. 내가 알고있는 (또는 적어도 내가 생각하는)을 사용하는 것이 $1당신은 당신이에 원하는대로 삽입 할 수 있기 때문에 쉽게 루트 권한으로 실행할 수있는 스크립트에서하는 끔찍한 생각입니다.

그래서 … 이것을 다루는 가장 좋은 방법은 무엇입니까? 어떻게 루트 권한으로 원하는 것을 수행하고, 주입 공격에 광범위하게 노출되지 않은 상태에서 변수를 전달할 수 있도록 (또는 환경 변수와 같이 효과적으로 수행 할 수 있도록) 어떻게해야합니까?



답변

아래의 쉘 스크립트를 실행하면 sudo안전 이 제공 sudo환경을 재설정하도록 구성되어 있습니다 . 반대로 sudo환경을 재설정하지 않으면 스크립트가 해당 매개 변수를 사용하지 않더라도 쉘 스크립트를 실행하는 것이 안전하지 않습니다 ( 쉘 스크립트에서 setuid 허용 참조 ). 당신이이 있는지 확인 Defaults env_reset/etc/sudoers또는이 옵션 (컴파일시 기본값임을 sudo sudo -V | grep env포함한다 Reset the environment to a default set of variables).

스크립트 매개 변수를 사용할 때는 특별한 위험이 없습니다. $1문자열입니다. 문자열로 사용하고 있는지 확인하십시오. (예를 들어,하지 마십시오 eval "$1".) 변수의 내용에 대해 가정하지 않고 모든 변수 대체 (즉, write "$1", not $1)를 큰 따옴표로 묶는 것이 여기에서 특히 중요합니다 . 변수 대체를 큰 따옴표로 묶는 것은 특권으로 실행되는 스크립트에만 국한된 것이 아니라 항상 수행해야하는 작업입니다.

udhcpc호스트 이름처럼 보이지 않는 대상 에 따라 매개 변수의 유효성을 추가로 검증 할 수 있습니다 . 예를 들어, 첫 번째 구문 검사를 수행합니다.

#!/bin/sh
case "$1" in
  *[!:-.0-9A-Za-z]*|-*) echo 1>&2 "Badly formed host name!"; exit 3;;
esac
udhcpc -b -i eth0 -h "$1"


답변

전달 된 입력을 알려진 올바른 패턴과 일치시켜야합니다.

예를 들어, IP 주소가 유효한 입력 인 것 같습니다. 따라서 다음과 같은 것을 사용할 수 있습니다.

if [[ "$1" =~ ^[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9].[0-9]?[0-9]?[0-9]$ ]]
then
  udhcpc -b -i eth0 -h "$1"
else
  echo "Don't mess with me pork chop."
fi

regexp는 테스트되지 않았으므로 regexp가 위험한 것을 허용하지 않도록해야합니다.


답변