문제

응용 프로그램은 파일을 구문 분석하고 "실행"하고 싶고 파일이 보안상의 이유로 실행 가능한 것이라고 주장하려고합니다.

이 초기 코드는 보안 체계를 비효율적으로 만드는 경주 조건이 있다는 것을 생각하고 순간에 다음과 같습니다.

import os

class ExecutionError (Exception):
    pass

def execute_file(filepath):
    """Execute serialized command inside @filepath

    The file must be executable (comparable to a shell script)
    >>> execute_file(__file__)  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ExecutionError: ... (not executable)
    """
    if not os.path.exists(filepath):
        raise IOError('"%s" does not exist' % (filepath, ))
    if not os.access(filepath, os.X_OK):
        raise ExecutionError('No permission to run "%s" (not executable)' %
                filepath)

    data = open(filepath).read()

    print '"Dummy execute"'
    print data

인종 조건이 존재합니다

os.access(filepath, os.X_OK)

그리고

data = open(filepath).read()

이 두 시스템 호출 사이에 다른 컨텐츠의 실행 불가능한 파일로 파일을 덮어 쓰일 가능성이 있기 때문에.

내가 가진 첫 번째 해결책은 중요한 통화의 순서를 변경하고 (현재 중복 된 존재 점검을 건너 뛰는 것) :

fobj = open(filepath, "rb")
if not os.access(filepath, os.X_OK):
    raise ExecutionError('No permission to run "%s" (not executable)' %
            filepath)

data = fobj.read()

이것이 레이스 조건을 해결합니까? 어떻게 올바르게 해결할 수 있습니까?

보안 제도 이론적 근거, 간단히 (나는 생각했다)

이 파일은 환경 내에서 임의의 명령을 수행 할 수 있으므로 쉘 스크립트와 비슷합니다.

응용 프로그램을 정의하는 .desktop 파일이있는 무료 데스크톱에 보안 구멍이있었습니다. 파일은 인수가있는 실행 파일을 지정할 수 있으며 자체 아이콘과 이름을 선택할 수 있습니다. 무작위로 다운로드 된 파일은 이름이나 아이콘 뒤에 숨어서 무엇이든 할 수 있습니다. 그것은 나빴다.

이는 .desktop 파일에 실행 파일 비트 세트가 있어야함으로써 해결되었습니다. 그렇지 않으면 이름/아이콘으로 렌더링되지 않으며 무료 데스크톱은 사용자에게 시작하기 전에 프로그램을 시작하려는 지 묻습니다.

이것을 Mac OS X의 매우 좋은 디자인과 비교하십시오. "이 프로그램은 웹에서 다운로드 되었으나 열고 싶습니까?"

그래서 이것으로 우화에서, 그리고 당신이 chmod +x 다운로드 한 쉘 스크립트, 위의 질문에서 디자인에 대해 생각했습니다.

닫는 단어

결론적으로는 간단하게 유지해야 할 수도 있습니다. 파일을 실행할 수 있어야하는 경우 실행 가능하게 만들고 사용자가 호출 할 때 커널이 실행하도록하십시오. 과제가 속한 위치에 대한 위임.

도움이 되었습니까?

해결책

실행 가능성은 열린 파일에 첨부되어 있으며 여러 파일이 읽을 데이터가 포함 된 inode를 가리키는 것을 중지하는 것은 없습니다. 다시 말해, 동일한 파일 시스템의 다른 곳에서는 실행 불가능한 파일에서 동일한 데이터를 읽을 수 있습니다. 또한 파일을 열면 동일한 파일의 실행 가능성이 변경되는 것을 방지 할 수 없으며 intine가 해제 될 수도 있습니다.

내가 볼 수 있듯이 "최선의 노력"은 사용하는 수표입니다. os.fstat 열린 파일에서, 전후에 보호 모드 및 수정 시간을 확인하지만, 기껏해야 파일을 읽는 동안 변경되지 않을 가능성 만 줄어 듭니다.

두 번째 생각에,이 파일의 데이터의 원래 제작자라면, 처음에는 파일 시스템에 연결되지 않은 inode를 작성하는 것을 고려할 수 있습니다. 이는 파일을 통해 메모리 공유의 일반적인 기술입니다. 또는 포함 된 데이터가 결국 다른 사용자에게 공개 해야하는 경우 파일 잠금을 사용한 다음 필요한 사용자에게 보호 비트를 점차적으로 확장 할 수 있습니다.

궁극적으로 악의적 인 사용자가 파일에 대한 쓰기 액세스가 없도록해야합니다.

다른 팁

이 레이스 조건을 완전히 해결할 수는 없습니다. 예를 들어, 처음 열린 버전에서 권한을 확인하십시오. 가능한 파일을 열고 권한을 변경하기 직전에 권한이 변경됩니다.

파일을 잠재적 인 나쁜 사람에게 도달 할 수없는 디렉토리로 파일을 원자 적으로 이동할 수 있다면, 파일에 대해 아무것도 다루는 동안 코 아래에서 아무것도 변경되지 않을 것이라는 확신을 줄 수 있습니다. 잠재적 인 나쁜 사람이 도달 할 수 있다면 어디에나, 또는 파일을 도달 할 수없는 곳으로 이동할 수 없으며 방어가 없습니다.

BTW,이 계획이 어떻게 작동하도록해도 어떻게 보안을 추가 할 것인지는 분명하지 않습니다. 반드시 나쁜 녀석이 파일에 중독 된 콘텐츠를 넣을 수 있다면 그 이상이 아닙니다. chmod +x 그것도?

당신이 할 수있는 최선은 다음과 같습니다.

  • 허가를 저장하십시오.
  • 자신의 고유 한 사용자 (프로그램 이름이있는)로 변경하고 다른 사람들이 실행하는 것을 금지하십시오.
  • 확인하십시오 (필요한 경우 저장된 권한에서).
  • 프로세스를 실행하십시오.
  • 저장된 사람에게 허가를 돌려주십시오.

물론 단점이 있지만 사용 사례가 말하는 것처럼 간단하다면 트릭을 수행 할 수 있습니다.

공격자가 "chown root : root file_name"에 액세스 할 수 없도록 파일 소유권을 변경해야합니다. 다른 계정이 파일을 읽고/쓰기/실행할 수 없도록 "chmod 700 file_name"을 수행하십시오. 이렇게하면 Toctou의 문제가 모두 함께 발생하지 않으며 이는 시스템에 사용자 계정이있는 공격자가 사람들이 파일을 수정하는 것을 방지하는 방법입니다.

이를 수행하는 또 다른 방법은 파일 이름을 예상치 못한 것으로 변경하거나 전체 파일을 너무 크지 않은 경우 전체 파일을 온도 (필요한 경우 암호화)로 복사 한 다음 파일 이름을 바꾸고 다시 복사하는 것입니다.

물론 그것은 매우 무거운 과정입니다.

그러나 시스템이 처음부터 안전을 위해 설정되지 않았기 때문에 결국 끝납니다. 안전한 프로그램은 안전을 유지하려는 데이터에 서명하거나 암호화합니다. 귀하의 경우에는 불가능합니다.

당신이 정말로 암호화하지 않는 한, 당신이 제어하지 않는 기계에서 100 안전을 보장 할 수있는 방법은 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top