2014-10-28 7 views
0
is_exec = lambda x: subprocess.call("type " + x, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 and (os.path.isfile(x) and os.access(x, os.X_OK)) 

이 코드를 보았지만 제대로 작동하지만 중복되어 있습니까?Python : 실행 파일 확인

Isnt is_exec = lambda x: os.access(x, os.X_OK)으로 충분합니까?

질문 : is_exec = lambda x: os.access(x, os.X_OK)은 잡히지 않지만 첫 번째 경우는 있습니까?

+0

저는 그것이 중복되어 있음을 확신합니다. 두 코드 모두 제대로 작동합니다. 두 번째 것만이 더 간결합니다. 차이점은 실제로 하나의 테스트를 수행하고 다른 하나는 특성을 검사한다는 것입니다. 게다가 임의의 코드 실행에 취약 할 수 있으므로 첫 번째 코드는 사용하지 마십시오. –

+1

'x'의 값을 신중하게 검사하지 않으면 첫 번째는 백도어처럼 보입니다. – chepner

답변

1

여기에 미묘한 차이가있다 - 첫 번째 통화에서,이 또한 예를 들어, 쉘 내장 기능을 감지합니다 : '

$ type cd 
cd is a shell builtin 
$ echo $? 
0 

을하지만, 당신이 할 수 있도록, 같은 실제 cd 실행이 없습니다 정확하게 os.access()으로 확인하십시오. 그게 내가 실제로 중간 운영자가 지금 or 것을

is_exec = lambda x: subprocess.call("type " + x, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 or (os.path.isfile(x) and os.access(x, os.X_OK)) 

참고해야한다 생각했다. 또한, 서브 프로세스 파이프는 여기서 약간 불필요하게 보이며 고려해야 할 쉘 인젝션으로 사용될 수 있다는주의 사항이 있습니다.

전체적으로, 만만치 않은 파일을 확인하는 데 신경 쓰면 첫 번째 비트를 버리는 것이 좋습니다.

1

모두 True를 반환하려면 os.access(x, os.X_OK)이 필요합니다. 그러나 os.access을 호출하기 전에 불필요한 테스트를 수행하는 것 외에도, 먼저 사용하기 전에 x의 값을 신중하게 화면에 표시하지 않으면 먼저 쉘 분사 공격이 시작됩니다. 을 subprocess.call과 함께 사용하면 단순히 실행을 위해 문자열을 셸로 전달합니다. x의 값을 신중하게 구성하면 type 명령 이상을 실행하게됩니다. 예를 들어, 실행 중의 두 명령이 아니라 하나의 결과로, 쉘

x = "somefile.txt; rm foo.txt" 
subprocess.call("type " + x, shell=True, 
       stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

문자열 "RM foo.txt의 유형 somefile.txt"를 전달한다.