루트 사용자로 PHP에서 쉘 스크립트를 실행하시겠습니까?

루트 사용자로 PHP에서 쉘 스크립트를 실행하시겠습니까?

다음 줄은 PHP에서 실행되어야 합니다:

$res = shell_exec('sudo sh /home/nicklas/cronjobs/make_account.sh 사용자 이름 비밀번호');

문제는 실행해도 아무 일도 일어나지 않는다는 것입니다. $res를 echo하려고 하면 공백으로 나옵니다. 나는 또한 동일한 결과를 가지고 system()을 사용해 보았습니다. www-data 사용자에게는 기본적으로 없는 루트 액세스 권한으로 스크립트를 실행해야 하기 때문에 작동하지 않는 것 같습니다. 액세스 권한을 얻기 위해 /etc/sudoers에 다음 줄을 추가했습니다.

www-데이터 ALL=(ALL:ALL) NOPASSWD: /home/nicklas/cronjobs/make_account.sh

그러나 성공하지 못했습니다. 중간에 아파치를 다시 시작해 보았지만 아무런 변화가 없었습니다.

내가 뭐 놓친 거 없니?

답변1

나는 웹 서버에서 높은 권한으로 무언가를 실행하는 것이 항상 나쁜 생각이라는 점에 강력하게 동의하지 않습니다.

웹 애플리케이션 보안 문제는 해당 데이터를 사용하는 정확한 프로세스가 아닌 사용자 제공 데이터에 대한 신뢰에서 발생합니다.

즉, 데이터의 유효성을 검사하고 정리하지 않으면더 안전하지 않아데이터를 처리하고 www-data 사용자가 sudo를 통해 실행할 수 있도록 허용하는 래퍼 스크립트를 작성하는 대신 명명된 파이프를 통해 루트 소유 프로세스에 전달합니다.

현실적으로 대부분의 데이터 처리/검증/정리 작업은 데이터가 sudo 스크립트로 전달되기 전에 수행되어야 합니다. sudo 스크립트는 a) 데이터에 대한 최종 확인을 수행하고 b) 실행해야 합니다.오직더 높은 권한이 필요한 작업.

사실 후자가 더 간단하고 이해하기 쉽기 때문에 더 안전하다고 생각합니다. 뭔가를 더 복잡하게 만들수록 실수할 확률이 더 높아집니다.

어떤 방법을 사용하든 상관없습니다(이름이 지정된 파이프, sudo 래퍼 또는 기타).비판적인중요한 것은 사용자가 제공한 데이터를 확인하고 이를 수행하기 전에 매우 좁게 정의된 기준을 충족하는지 확인하는 것입니다.아무것그걸 써.

Stackexchange 웹 사이트를 포함하여 웹에는 CGI 보안에 관한 많은 기사와 가이드가 있지만 몇 가지 일반적인 주제는 다음과 같습니다.

  • 데이터가 안전한지 확인하기 위해 데이터를 검사 및/또는 수정하기 전까지는 데이터를 "오염된" 것으로 간주하고 신뢰할 수 없는 것으로 취급하십시오.
  • 데이터를 검사합니다. 예를 들어 허용되거나 금지된 문자의 정규식과 일치하는지 테스트합니다. 가장 안전한 방법은 이상한 일이 발생하면 중단하는 것입니다. 그렇지 않으면 정규 표현식이나 변형을 사용하여 잠재적으로 안전하지 않은 요소를 제거합니다.
  • 언제나데이터가 외부 쉘 스크립트로 전달되면 데이터가 인용됩니다. 예를 들어, 쉘 스크립트는 변수 주위에 큰따옴표를 사용해야 합니다.
  • 마찬가지로 데이터베이스에 데이터를 삽입할 때 이스케이프나 인용에 의존하기보다는 자리 표시자 값을 지원하는 데이터베이스 라이브러리를 사용해야 합니다.여기이것은 유머러스한 그림입니다.

계속할 수 있지만 여기 답변에 요약할 내용이 너무 많습니다. CGI 보안은 광범위한 주제입니다. 구글에서 검색해 보세요CGI 안전또는CGI 입력 검증


안전에 대한 귀하의 태도는 "나는 그것을 사용하는 유일한 사람이기 때문에 상관하지 않습니다"입니다. 이로 인해 당신의 발을 날려 버릴 장전된 산탄총을 주는 것처럼 느껴지지만 얼굴에 발을 쏘는 것은 귀중한 학습 경험. 다음은 사용자 계정을 생성하는 간단한 스크립트입니다. 루트 권한이 필요합니다.

이 스크립트는 데비안과 데비안 파생 시스템은 물론 다른 시스템에서 사용할 수 있는 adduser에 따라 다릅니다. 시스템에서 사용할 수 없는 경우 useradd를 사용하도록 수정하세요.

#! /bin/bash 

# make the script abort on any error
set -e

U="$1"
P="$2"

[ -z "$U" ] && echo "Error: No username provided" >&2 && exit 1
[ -z "$P" ] && echo "Error: No password provided" >&2 && exit 1

# simple check - only allow lower-case letters and digits in usernames.
[ "$U" !~ '^[a-z0-9]*$' ] && echo "Error: Invalid Username" >&2 && exit 1

# create user if they don't already exist
if ! getent passwd "$U" > /dev/null ; then

   # create the user using adduser, must provide the gecos field 
   # and disable the password so adduser doesn't ask for them. 
   adduser --gecos "$U" --disabled-password "$U"

   # now change the password
   echo "$U:$P" | chpasswd
else
    echo "Error: Username already exists" >&2
    exit 1
fi

스크립트를 어딘가에 저장하고 chmod를 사용하여 실행 가능하게 만듭니다.

www-data가 비밀번호 없이 루트로 실행되도록 하려면 /etc/sudoers를 편집하고 visudo다음을 추가하세요.

Cmnd_Alias APACHEADDUSER = /path/to/makeaccount.sh

www-data ALL = NOPASSWD: APACHEADDUSER

답변2

보안상의 이유로 원래 가지고 있는 것보다 더 많은 권한을 가진 사용자 www-data로 특정 작업을 수행하려고 시도해서는 안 됩니다. 얼마 전에 Apache 액세스가 www-data로 이동된 이유가 있습니다. 컴퓨터에서 루트로 어떤 작업을 해야 하고 비밀번호를 변경하거나 계정을 만드는 것이 "작업"인 경우 인터페이스를 구축해야 합니다. PHP 스크립트에 무언가를 어딘가에 넣고 루트에서 실행되는 스크립트를 통해 스캔하여 그곳에서 처리하게 합니다. www-data에서 액세스할 수 있는 디렉터리에 추가하려는 사용자가 포함된 파일을 만든 다음 루트 크론 작업을 통해 5분(또는 그 이하)마다 이 작업을 수행하고 타임스탬프 폴더를 사용하여 파일을 완료하도록 이동하여 진행 상황을 제어할 수 있습니다. 에.

관련 정보