2012-12-27 2 views
0

다음은 필자가 작성한 프로그램의 일부입니다. 루틴은 (예 : FileOne\nAnotherFile\nThird file\n)에 저장되고 모두 EXTENSION 인 줄로 구분 된 파일 이름 목록이 저장된 filenamelist (사용 권한 0600)을 거칩니다. 파일 이름 목록은 내 프로그램의 다른 부분에서 가져온 것입니다.파일 집합을 삭제하는 루틴이 파괴되지 않도록 방지

filenamelist이 (가) 시스템의 다른 파일을 삭제하는 데 악용 될 수 있음을 두려워합니다. 그것을 잠그는 더 좋은 방법이 있습니까? 원래는 삭제할 파일의 전체 경로를 저장했지만, 난독 화하려고 할 때 디렉토리와 파일 확장자를 분리하고 하드 코드했습니다.

나는 편집증 적이지만 악의적 인 사용자 (!)가 filenamelist을 다른 파일 경로로 감염시킬 수 있습니다. 예를 들어 ../../another-directory/donotdeleteme.sys 또는 내가 생각조차 할 수없는 곳에서 도망쳐 라.

directory 외부의 파일을 삭제할 때 아래의 삭제 루틴을 잘못 사용할 수 있습니까? 고양이 · astrophe를 막기 위해 내가 어떻게 더 잠글 수 있는지에 대한 제안?

추신 : 프로그램의 루트가 일 때 이 실행되어야 사용자의 홈 디렉토리 외부에서 파일이 수정됩니다. 당신은 파일 이름에 포함 된 어떤 / 문자가 없는지 확인하기 위해 검사를 추가하는 경우

#define EXTENSION ".stuff" 
char *directory = calloc(28); 
directory = "/usr/local/share/stuffings/"; 
char *filenamelist = calloc(24); 
filenamelist = "/etc/stuffing/files.lst"; 

void delete_files(char* filenamelist, char* directory) { 

    if (access(filenamelist, F_OK | R_OK) == 0) { 
    FILE *filenamelist_fp = fopen(filenamelist, "r"); 
    char filename[200]; 

    while(fgets(filename, 200, filenamelist_fp) != NULL) { 
     char *pos; 
     char *path = calloc((strlen(directory) + strlen(filename) + strlen(EXTENSION) + 1), sizeof(char)); 

     if ((pos=strchr(filename, '\n')) != NULL) 
     *pos = '\0'; 

     strcat(path, directory); 
     strcat(path, filename); 
     strcat(path, EXTENSION); 

     if (access(path, F_OK | W_OK) == 0) 
     unlink(path); 
     free(path); 
    } 

    fclose(filenamelist_fp); 
    unlink(filenamelist); 
    } 
} /* © */ 
+0

'filenamelist = "/etc/stuffing/files.lst";'이전에'calloc' 한 메모리에 핸들을 잃어 버렸습니다. 아마도'strcpy (filenamelist, "/ etc/...");와 같은 것을 의미했을 것입니다. –

+0

유닉스에서 '\ n'은 파일 이름에 유효한 문자입니다. 또한 : 당신은 크기를 기억하고 strcat() 대신 snprintf()를 사용할 수 있습니다. 그리고 access()는 쓸모가 없습니다. IMHO. 그리고 : 파일의 링크를 해제하려면 디렉토리에 대한 쓰기 권한이 있어야합니다.이 디렉토리는 확인하지 않습니다. Daniel이 dirname에도 똑같이 말합니다. – wildplasser

+0

모호함을 통해 보안을 시도하지 마십시오. 거의 작동하지 않는 나쁜 생각입니다. 대신 샌드 박스, 암호화 등과 같은 입증 된 작업을 수행하십시오. – Linuxios

답변

4

, 당신은 (A POSIX 플랫폼을 가정) 지정된 디렉토리 외부에 파일을 삭제에 대한 완벽하게 안전 할 것이다. 불행히도 이것은 또한 주어진 디렉토리 아래의 서브 디렉토리에있는 파일을 삭제하는 것을 막을 것입니다. 이것이 정상이면 해당 솔루션을 사용할 수 있습니다.

주어진 디렉토리의 하위 디렉토리에서 파일을 삭제할 수 있도록 지원하려면 첫 번째 단계는 ..이 경로명의 구성 요소로 나타나지 않도록 차단하는 것입니다. 그러나 충분하지 않습니다. 디렉토리에 대한 심볼릭 링크를주의해야합니다 주어진 디렉토리 아래 어디에서나, 트리를 벗어나는 파일을 삭제할 수 있기 때문에. 이 경우 가장 강력한 솔루션은 경로 이름의 각 구성 요소를 직접 구문 분석하고 openat을 사용하여 각 디렉토리 구성 요소를 수동으로 열고 (symlink를 따르지 않았 음을 확인한 후 fstatlstat의 결과를 비교) 사용하고 unlinkat 끝에 파일을 삭제하십시오.

그런데 access(filenamelist, F_OK | R_OK)으로 전화하는 것은 불필요하며 불필요합니다. 파일을 열기 전에 파일에 대한 액세스를 테스트 할 필요가 없습니다. 파일이 fopen() 일 수도 있습니다.

+0

내가 확인해야하는 것은 슬래시뿐입니다. 어떻게 든 도망 갈 수 없습니까? 문자를 이스케이프/인코딩하는 다양한 방법을 사용하여 간단한 테스트를 수행 할 수있는 여러 가지 방법이있는 웹 서비스에 대해 생각하고 있습니다. – Aeyoun

+1

예 /는 확인해야 할 유일한 것입니다. 아니, 탈출 할 수 없다.경로 이름에 대한 규칙은 URL 규칙보다 훨씬 간단합니다. – Celada

관련 문제