권한이 낮은 사용자가 높은 권한으로 사용자 정의 스크립트를 실행할 수 있도록 하는 레거시 C 코드가 있습니다. 여기에는 SUID 비트가 설정되어 있습니다. 이 코드는 PATH 환경을 특정 폴더로 제한한 다음 system()
api를 사용하여 제한된 셸을 통해 스크립트를 실행합니다.
/bin/bash -r -c "script <arg>"
경로가 제한되어 있으므로 해당 특정 폴더에서만 스크립트를 실행할 수 있습니다.
이제 API 명령 주입의 모든 함정을 알았으니 system()
명령 주입을 피하기 위해 어떤 조치를 취할 수 있나요? 이는 다양한 스크립트 등 여러 곳에서 사용되므로 회귀를 피하기 위해 완전히 새로운 구현을 만들고 싶지 않습니다.
답변1
올바르게 작성하기가 어렵기 때문에 코드에서 SUID를 제거하는 것이 좋습니다. 을 사용하도록 C 코드를 변경하세요 sudo
. 보안 시스템 프로그래밍의 어려운 측면은 sudo를 사용하여 수행됩니다.
그런 다음 visudo를 사용하여 작업을 수행하는 데 필요한 최소한의 작업을 수행하고 필요한 사용자/그룹으로 제한하는 sudo 구성을 신중하게 구축할 수 있습니다. sudo를 구성한 후에는 다른 사람에게 테스트를 요청하여 예상되는 제한 사항을 깨도록 하세요.
답변2
코드 삽입을 위해서는 사용자가 임의의 문자열을 호출에 대한 인수로 전달할 수 있어야 합니다 system()
. 이는 SQL 주입과 매우 유사하며 유사한 방식으로 피해야 합니다. 사용자 정의 문자열을 호출에 직접 전달하지 마십시오.
숫자 인수는 정수로 변환되어야 하며 호출 시 다시 문자열로 변환되어야 합니다.
고정 사전의 일부인 매개변수는 "enum" 값 또는 이와 유사한 값으로 변환된 다음 호출 시 문자열로 반환되어야 합니다.
[a-zA-Z0-9]*
자유 텍스트 입력은 가능하면 무해한 문자 집합(예: )으로 제한되어야 합니다 . 문제가 있는 문자(공백 포함)가 필요한 경우 적절한 이스케이프를 적용해야 합니다(예: 다음a b
으로 대체해야 함a\ b
).