다음을 통해 공유


보안 고려 사항: Microsoft Windows Shell

이 항목에서는 Windows 셸과 관련된 보안 고려 사항에 대한 정보를 제공합니다. 이 문서는 보안 문제에 대해 알아야 할 모든 것을 제공할 수 없습니다. 대신 이 특정 기술 영역에 대한 시작점 및 참조로 사용합니다.

Shell은 제대로 처리되지 않을 경우 잠재적인 보안 위험을 나타내는 몇 가지 요소를 포함하여 시스템의 여러 중요한 측면을 제어합니다. 이 항목에서는 몇 가지 일반적인 문제와 애플리케이션에서 문제를 해결하는 방법을 간략하게 설명합니다. 보안은 인터넷 기반 익스플로잇에 국한되지 않습니다. 터미널 서비스를 통해 액세스할 수 있는 시스템을 비롯한 공유 시스템에서는 사용자가 시스템을 공유하는 다른 사람에게 해를 끼칠 수 있는 작업을 수행할 수 없도록 해야 합니다.

애플리케이션을 제대로 설치

애플리케이션을 올바르게 설치하여 대부분의 잠재적인 Shell 보안 문제를 완화할 수 있습니다.

  • Program Files 폴더 아래에 애플리케이션을 설치합니다.

    운영 체제 Location
    Windows XP, Windows Server 2003 및 이전 버전 CSIDL_PROGRAM_FILES
    Windows Vista 이상 FOLDERID_ProgramFiles, FOLDERID_ProgramFilesX86, FOLDERID_ProgramFilesX64, FOLDERID_ProgramFilesCommon, FOLDERID_ProgramFilesCommonX86 또는 FOLDERID_ProgramFilesCommonX64. 자세한 내용은 KNOWNFOLDERID 를 참조하세요.

     

  • Program Files 폴더 아래에 사용자 데이터를 저장하지 마세요.

    모든 사용자에게 공통적인 데이터에 적절한 데이터 폴더를 사용합니다.

    운영 체제 Location
    Windows XP, Windows Server 2003 및 이전 버전 CSIDL_COMMON_APPDATA
    Windows Vista 이상 FOLDERID_ProgramData

     

    특정 사용자에게 속한 데이터에 적절한 사용자 데이터 폴더를 사용합니다.

    운영 체제 Location
    Windows XP, Windows Server 2003 및 이전 버전 CSIDL_APPDATA, CSIDL_PERSONAL 등
    Windows Vista 이상 FOLDERID_RoamingAppData, FOLDERID_Documents 등

     

  • Program Files 폴더 이외의 위치에 설치해야 하는 경우 사용자가 파일 시스템의 부적절한 부분에 액세스할 수 없도록 ACL(액세스 제어 목록)을 올바르게 설정해야 합니다. 특정 사용자와 관련된 모든 데이터에는 다른 사용자가 액세스하지 못하도록 하는 ACL이 있어야 합니다.

  • 파일 연결을 설정할 때 명령줄을 올바르게 지정해야 합니다. 정규화된 경로를 사용하고 공백이 포함된 요소를 따옴표로 묶습니다. 명령 매개 변수를 별도의 따옴표로 래핑합니다. 그렇지 않으면 문자열이 잘못 구문 분석되고 애플리케이션이 제대로 시작되지 않을 수 있습니다. 올바르게 구성된 명령줄의 두 가지 예가 여기에 나와 있습니다.

    "C:\Program Files\MyApp\MyApp.exe" "%1" "%2"
    C:\MyAppDir\MyApp\MyApp.exe "%1"
    

참고

표준 설치 폴더의 위치는 시스템마다 다를 수 있습니다. 특정 Windows Vista 이상 시스템에서 표준 폴더의 위치를 얻으려면 적절한 KNOWNFOLDERID 값으로 SHGetKnownFolderPath를 호출합니다. Windows XP, Windows Server 2003 또는 이전 시스템에서 적절한 CSIDL 값으로 SHGetFolderLocation 또는 SHGetFolderPath를 호출합니다.

 

Shlwapi

셸 경량 API(Shlwapi)에는 여러 문자열 조작 함수가 포함되어 있습니다. 이러한 함수를 잘못 사용하면 잘림이 반환되는 알림 없이 예기치 않게 잘린 문자열이 발생할 수 있습니다. 다음 경우 Shlwapi 함수를 사용하면 안 됩니다. 위험을 더 적게 초래하는 나열된 대체 함수를 해당 위치에서 사용해야 합니다.

Shlwapi 함수 대체 함수
StrCat, StrNCat StringCchCat, StringCbCat 및 관련 함수
StrCpy, StrCpyN StringCchCopy, StringCbCopy 및 관련 함수
wnsprintf, wvnsprintf StringCchPrintf, StringCbPrintf 및 관련 함수

 

파일 경로를 반환하는 PathRelativePathTo 와 같은 함수를 사용하면 항상 버퍼 크기를 MAX_PATH 문자로 설정합니다. 이렇게 하면 버퍼가 가능한 가장 큰 파일 경로와 종료 null 문자를 저장할 수 있을 만큼 충분히 커집니다.

대체 문자열 함수에 대한 자세한 내용은 Strsafe.h 정보를 참조하세요.

자동 완성

암호에 자동 완성 기능을 사용하지 마세요.

애플리케이션을 시작하는 데 사용할 수 있는 몇 가지 Shell 함수는 ShellExecute, ShellExecuteEx, WinExecSHCreateProcessAsUserW입니다. 실행할 애플리케이션의 명확한 정의를 제공해야 합니다.

  • 실행 파일의 경로를 제공할 때 정규화된 경로를 제공합니다. 셸에 의존하여 파일을 찾지 마세요.
  • 공백이 포함된 명령줄 문자열을 제공하는 경우 문자열을 따옴표로 래핑합니다. 그렇지 않으면 파서는 공백을 포함하는 단일 요소를 여러 요소로 해석할 수 있습니다.

파일 이동 및 복사

시스템 보안의 한 가지 핵심은 ACL을 올바르게 할당하는 것입니다. 암호화된 파일을 사용할 수도 있습니다. 파일을 이동하거나 복사할 때 올바른 ACL이 할당되고 실수로 암호가 해독되지 않았는지 확인합니다. 여기에는 파일 시스템 내에서 뿐만 아니라 휴지통으로 파일을 이동하는 것도 포함됩니다. IFileOperation(Windows Vista 이상) 또는 SHFileOperation(Windows XP 이하)을 사용합니다. 대상 파일에 대해 예상되는 ACL을 설정하지 않을 수 있는 MoveFile을 사용하지 마세요.

보안 네임스페이스 확장 작성

셸 네임스페이스 확장은 사용자에게 데이터를 제공하는 강력하고 유연한 방법입니다. 그러나 올바르게 작성되지 않은 경우 시스템 오류가 발생할 수 있습니다. 유의해야 할 몇 가지 핵심 사항은 다음과 같습니다.

  • 이미지와 같은 데이터의 형식이 올바르게 지정되었다고 가정하지 마세요.
  • MAX_PATH 문자열의 바이트 수와 같다고 가정하지 마세요. 문자 수입니다.

보안 경고

다음 표에서는 잘못 사용되는 경우 애플리케이션의 보안을 손상할 수 있는 몇 가지 기능을 나열합니다.

기능 완화 방법
ShellExecute, ShellExecuteEx 일련의 기본 위치를 확인하여 특정 파일을 찾는 데 의존하는 검색은 스푸핑 공격에 사용할 수 있습니다. 정규화된 경로를 사용하여 원하는 파일에 액세스하도록 합니다.
StrCat 첫 번째 인수 인 psz1psz2 를 보유할 수 있을 만큼 커야 하며 닫는 '\0'이면 버퍼 오버런이 발생할 수 있습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCat, StringCbCatEx, StringCbCatN, StringCbCatNEx, StringCchCatCat, StringCchCatEx, StringCchCatN 또는 StringCchCatNEx.
StrCatBuff 최종 문자열은 null로 종료되지 않습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCat, StringCbCatEx, StringCbCatN, StringCbCatNEx, StringCchCatCat, StringCchCatEx, StringCchCatN 또는 StringCchCatNEx.
StrCatChainW 최종 문자열은 null로 종료되지 않습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCatEx, StringCbCatNEx, StringCchCatEx 또는 StringCchCatNEx.
Strcpy 첫 번째 인수 인 psz1psz2 를 보유할 수 있을 만큼 커야 하며 닫는 '\0'이면 버퍼 오버런이 발생할 수 있습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCopy, StringCbCopyEx, StringCbCopyN, StringCbCopyNEx, StringCchCopy, StringCchCopyEx, StringCchCopyN 또는 StringCchCopyNEx.
StrCpyN 복사된 문자열은 null로 종료되지 않습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCopy, StringCbCopyEx, StringCbCopyN, StringCbCopyNEx, StringCchCopy, StringCchCopyEx, StringCchCopyN, StringCchCopyNEx.
StrDup StrDuplpsz 가 null로 끝나는 문자열이라고 가정합니다. 또한 반환된 문자열은 null로 종료되지 않습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCat, StringCbCopyEx, StringCbCopyN, StringCbCopyNEx, StringCchCopy, StringCchCopyEx, StringCchCopyN 또는 StringCchCopyNEx.
StrNCat 첫 번째 인수인 pszFrontpszBack 을 보유할 수 있을 만큼 커야 하며 닫는 '\0'이면 버퍼 오버런이 발생할 수 있습니다. 마지막 인수인 cchMaxpszFront에 복사할 문자 수이며 반드시 pszFront 의 크기(바이트)가 아닙니다. 대신 다음 대안 중 하나를 사용합니다. StringCbCat, StringCbCatEx, StringCbCatN, StringCbCatNEx, StringCchCatCat, StringCchCatEx, StringCchCatN 또는 StringCchCatNEx.
wnsprintf 복사된 문자열은 null로 종료되지 않습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbPrintf, StringCbPrintfEx, StringCbVPrintf, StringCbVPrintfEx, StringCchPrintf, StringCchPrintfEx, StringCchVPrintf 또는 StringCchVPrintfEx.
wvnsprintf 복사된 문자열은 null로 종료되지 않습니다. 대신 다음 대안 중 하나를 사용합니다. StringCbPrintf, StringCbPrintfEx, StringCbVPrintf, StringCbVPrintfEx, StringCchPrintf, StringCchPrintfEx, StringCchVPrintf 또는 StringCchVPrintfEx.

 

Microsoft 보안

Security Developer Center

Microsoft Solution Accelerator

보안 TechCenter

Strsafe.h 정보