다음을 통해 공유


보안 취약성에 대한 패키지 종속성 감사

보안 감사 정보

NuGet과 같은 패키지 관리자에 대한 보안 감사는 소프트웨어 프로젝트에 포함된 패키지의 보안을 분석하는 프로세스입니다. 여기에는 취약성 식별, 위험 평가 및 보안 향상을 위한 권장 사항이 포함됩니다. 감사에는 패키지 자체의 검토뿐만 아니라 종속성 및 관련 위험이 포함될 수 있습니다. 감사의 목표는 코드 삽입 또는 사이트 간 스크립팅 공격과 같이 공격자가 악용할 수 있는 보안 취약성을 식별하고 완화하는 것입니다.

기능 가용성

누겟 .NET SDK 비주얼 스튜디오 기능
5.9 .NET 5 SDK(5.0.200) 해당 없음 dotnet list package --vulnerable
6.8 .NET 8 SDK(8.0.100) Visual Studio 2022 17.8 PackageReference용 NuGetAudit
6.10 해당 없음 Visual Studio 2022 17.10 packages.config에 대한 NuGetAudit
6.11 .NET 8 SDK(8.0.400) Visual Studio 2022 17.11 PackageReference용 NuGetAuditSuppress
6.12 .NET 9 SDK(9.0.100) Visual Studio 2022 17.12 감사 원본. packages.config에 대한 NuGetAuditSuppress 입니다.
7.0 .NET 10 SDK(10.0.100) Visual Studio 2026 .NET 10에 대한 NuGetAuditMode 기본 변경 내용입니다. dotnet package update --vulnerable

다음을 사용하여 보안 감사 실행 restore

restore 명령은 처음으로 프로젝트 로드, 새 패키지 추가, 패키지 버전 업데이트 또는 즐겨찾는 IDE의 프로젝트에서 패키지 제거와 같은 일반적인 패키지 작업을 수행할 때 자동으로 실행됩니다. 종속성은 감사 원본에서 제공하는 알려진 취약성 목록에 대해 확인됩니다.

  1. 명령줄에서 프로젝트 또는 솔루션 디렉터리로 이동합니다.
  2. 원하는 도구(예: dotnet, MSBuild, NuGet.exe, VisualStudio 등)를 사용하여 실행 restore 합니다.
  3. 경고를 검토하고 알려진 보안 취약성을 해결합니다.

NuGet 감사 구성

감사는 프로젝트의 일부로 평가되는 MSBuild 파일의 MSBuild 속성을 .csproj 통해 구성할 수 있습니다. 감사는 리포지토리 수준에서 구성하는 것이 좋습니다.

MSBuild 속성 기본값 사용 가능한 값: 주의
NuGetAuditMode 아래 1을 참조하세요. directall 최상위 종속성만 감사하려는 경우 값을 direct.로 설정할 수 있습니다. NuGetAuditMode는 packages.config 프로젝트에 적용되지 않습니다.
NuGetAuditLevel 낮음 low, moderate, highcritical 보고할 최소 심각도 수준입니다. 및 권고(제외moderate)를 보려면 highcriticallow 값을 moderate
NuGetAudit 맞다 truefalse 보안 감사 보고서를 받지 않으려면 값을 로 설정하여 환경을 완전히 옵트아웃할 수 있습니다. false
  1. NuGetAuditMode는 프로젝트가 all 이상을 대상으로 할 때 net10.0로 기본값이 설정됩니다. 그렇지 않으면 NuGetAuditMode의 기본값은 direct입니다. 프로젝트가 다중 대상인 경우 한 대상 프레임워크가 선택하는 all경우 감사는 모든 대상 프레임워크에 이 값을 사용합니다.

감사 원본

복원은 각 프로젝트에서 사용 중인 패키지 목록을 확인하기 위해 서버 VulnerabilityInfo 의 리소스 를 다운로드합니다. 원본 목록은 NuGet.ConfigauditSources 정의되며 감사 원본 중 하나라도 취약성 정보를 제공하지 않으면 NU1905 경고가 발생합니다. auditSources 정의되지 않았거나 소스를 packageSources 추가하지 않고 지워지면 NU1905 경고가 표시되지 않습니다.

패키지 대체 공격에 대한 일반적인 완화는 nuget.org 업스트림하는 단일 패키지 원본을 사용하는 것이므로 NuGet이 nuget.org 패키지 원본으로 사용하도록 구성되지 않도록 감사 원본을 사용하여 패키지 원본으로 사용하지 않고도 nuget.org(또는 취약성 정보를 제공하는 다른 소스)를 사용할 수 있습니다.

nuget.org의 취약성 데이터베이스에 대한 데이터 원본은 GitHub 자문 데이터베이스입니다. V2 프로토콜은 더 이상 사용되지 않으므로 nuget.config가 여전히 V2 엔드포인트를 사용하는 경우 V3 엔드포인트로 마이그레이션해야 합니다.

<configuration>
    <auditSources>
        <clear />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    </auditSources>
</configuration>

참고: 아래 표에는 감사 원본을 지원하는 기능이 나와 있습니다.

소개 감사 원본을 지원하는 기능
NuGet 6.12, .NET 9.0.100 SDK 및 Visual Studio 2022 17.12 Restore
NuGet 6.14, .NET 9.0.300 SDK dotnet package list --vulnerable
NuGet 7.0 및 Visual Studio 2026 Visual Studio 패키지 관리자 UI에서 NuGet AuditSources 지원

경고 코드

경고 코드 원인
NU1900 취약성 정보를 가져오는 동안 패키지 원본과 통신하는 동안 오류가 발생했습니다.
NU1901 심각도가 낮은 패키지가 검색됨
NU1902 보통 심각도가 검색된 패키지
NU1903 심각도가 높은 패키지가 검색됨
NU1904 심각도가 검색된 패키지
NU1905 감사 원본은 취약성 데이터베이스를 제공하지 않습니다.

이러한 경고를 오류로 처리하도록 빌드를 사용자 지정하여 경고를 오류로 처리하거나 오류가 아닌 경고를 처리할 수 있습니다. 예를 들어 모든 경고(C#, NuGet, MSBuild 등)를 오류로 처리하는 데 이미 사용하고 <TreatWarningsAsErrors> 있는 경우 나중에 검색된 취약성이 빌드를 중단하지 않도록 방지하는 데 사용할 <WarningsNotAsErrors>$(WarningsNotAsErrors);NU1901;NU1902;NU1903;NU1904</WarningsNotAsErrors> 수 있습니다. 또는 낮음 및 보통 취약성을 경고로 유지하지만 높고 중요한 취약성을 오류로 처리하고 사용하지 TreatWarningsAsErrors않는 경우 사용할 <WarningsAsErrors>$(WarningsAsErrors);NU1903;NU1904</WarningsAsErrors>수 있습니다.

참고 항목

packages.config 프로젝트와 같은 NoWarn 메시지 심각도에 대한 MSBuild 속성은 TreatWarningsAsErrors 지원되지 않습니다.

권고 제외

각 권고에 대해 새 NuGetAuditSuppress MSBuild 항목을 추가하여 권고를 제외할 수 있습니다. NuGetAuditSuppress 표시하지 않으려는 권고 URL로 설정된 메타데이터를 사용하여 Include= 항목을 정의합니다.

<ItemGroup>
    <NuGetAuditSuppress Include="https://github.com/advisories/XXXX" />
</ItemGroup>

다른 NuGet 감사 구성 속성 NuGetAuditSuppress 과 마찬가지로 항목은 프로젝트 또는 리포지토리 수준에서 정의할 수 있습니다.

NuGetAuditSuppress는 NuGet 6.11, Visual Studio 17.11 및 .NET 8.0.400 SDK부터 시작하는 PackageReference 프로젝트에 사용할 수 있습니다. Visual Studio 17.12 및 NuGet 6.12의 packages.config에 사용할 수 있습니다.

권고를 제외하는 경우

특정 권고를 분석하고 시나리오에 적용되지 않거나 적용되는 위험에 익숙한 경우 감사 보고서에서 특정 권고를 제외하도록 선택할 수 있습니다. 권고가 프로젝트의 일부가 아닌 패키지와 공유되는 경우에도 이러한 권고가 완전히 억제됨을 유의하십시오. NuGetAuditSuppress 는 권고를 관리하기 위한 최후의 수단으로 간주되어야 합니다.

알려진 취약성이 있는 패키지가 보고되는 경우의 작업

알려진 취약성이 있는 패키지에 대한 경고를 받는 것은 프로세스의 일부일 뿐입니다. 검색되면 솔루션에서 잠재적 취약성을 제거하기 위해 조치를 취해야 합니다.

가장 쉬운 경우는 직접 참조하는 패키지에 알려진 취약성이 있는 경우입니다. 이 경우 패키지 버전을 취약성을 해결하는 버전으로 업데이트합니다.

패키지 취약성은 직접 및 전이적 패키지 참조 모두에서 보고될 수 있습니다. 이 때문에 해결하기 위해 수행하는 작업이 다를 수 있습니다.

업데이트로 발견된 보안 취약성

보안 취약성이 발견되고 패키지에 대한 업데이트를 사용할 수 있는 경우 다음 중 하나를 수행할 수 있습니다.

  • 보안 수정 사항이 .csproj 포함된 최신 버전으로 또는 다른 패키지 버전 위치(Directory.Packages.props)를 편집합니다.
  • Visual Studio에서 NuGet 패키지 관리자 사용자 인터페이스를 사용하여 개별 패키지를 업데이트합니다.
  • dotnet package update --vulnerable 명령을 실행하여 프로젝트의 모든 취약한 패키지를 알려진 취약성 없이 첫 번째 버전으로 업데이트합니다.
  • dotnet package update 해당 패키지 ID를 사용하여 또는 dotnet package add 명령을 실행하여 최신 버전으로 업데이트합니다. .NET 9 이하를 사용할 때 사용합니다dotnet add package.
  • 프로젝트의 패키지를 알려진 취약성을 해결하는 버전으로 업데이트할 수 있는 MCP(NuGet 모델 컨텍스트 프로토콜) 서버를 사용합니다. 자세한 내용은 패키지 취약성 수정 을 참조하세요.

전이적 패키지

종종 취약성은 전이적 종속성에 있습니다. 직접 참조에 "가장 가까운" 패키지에 대한 업데이트를 선호하는 것이 좋습니다. 하지만 알려진 취약성으로 패키지를 업그레이드하는 것은 아무 문제가 없습니다.

예를 들어 프로젝트에서 패키지 A를 참조한다고 가정해 보겠습니다. 패키지 A는 패키지 B에 종속되어 있으며, 그러면 패키지 C에 대한 종속성이 있습니다. 이 예제에서는 패키지 C 버전 1.0.0에 알려진 취약성이 있으며 버전 2.0.0에서 수정되었습니다. 먼저 패키지 A를 업그레이드하는 것이 좋습니다. 감사 경고가 해결되지 않으면 패키지 B를 업그레이드해 봅니다. 감사 경고가 해결되지 않으면 C를 직접 업그레이드합니다. 이를 지원하려면 전이적 패키지 경로를 찾아야 합니다.

요약하면 알려진 취약성이 최상위 패키지의 전이적 종속성에 있는 경우 다음과 같은 옵션이 있습니다.

  • 최상위 패키지에 전이적 취약성이 없는 업데이트가 포함되어 있는지 확인하고 대신 업데이트합니다.
  • 취약성을 참조하지 않는 직접 참조로 가장 가까운 패키지를 업데이트합니다.
  • 고정 패키지 버전을 직접 패키지 참조로 추가합니다. 참고: 새 패키지 버전 업데이트를 사용할 수 있게 되면 이 참조를 제거하고 예상 동작에 대해 정의된 특성을 유지 관리해야 합니다.
  • 전이적 고정 기능과 함께 중앙 패키지 관리를 사용합니다. 프로젝트를 자신의 패키지로 압축하여 다른 사람들과 공유할 경우, 전이적 고정 기능이 있는 CPM으로 인해 해당 프로젝트가 그 패키지에서 API를 직접 호출하지 않더라도 패키지가 종속성으로 간주됩니다.
  • 권고를 처리할 수 있을 때까지 표시하지 않습니다.
  • 업데이트를 요청하기 위해 최상위 패키지의 추적기에서 문제를 제출합니다.
전이적 패키지 경로 찾기

패키지 경로를 찾는 방법에는 여러 가지가 있습니다. 선호하는 방법은 개발 중에 일반적으로 사용하는 도구에 따라 달라집니다.

dotnet nuget 왜

명령줄에서 이 명령을 사용하여dotnet nuget why 프로젝트의 패키지 그래프에 전이적 패키지가 포함된 이유를 이해할 수 있습니다.

dotnet nuget 이유 설명 예제

Visual Studio 솔루션 탐색기

또한 SDK 스타일 프로젝트는 프로젝트의 종속성 노드 아래에 전체 패키지 그래프를 제공합니다. 검색할 수도 있습니다! 검색 옵션을 확장하고 "외부 파일 검색"을 사용하도록 설정합니다.

Visual Studio 솔루션 탐색기 검색 옵션

패키지 이름을 검색하면 각 프로젝트의 종속성 노드 아래에 모든 인스턴스가 표시됩니다.

Visual Studio 솔루션 탐색기 검색 결과

Visual Studio NuGet 패키지 관리자 UI

Visual Studio의 패키지 관리자 UI에서 설치된 탭을 보면 프로젝트에서 패키지 관리에 PackageReference를 사용하는 경우 직접 및 전이적 패키지가 모두 표시됩니다. 현재 이 문제는 솔루션이 아닌 프로젝트에 대한 패키지를 관리하는 경우에만 발생합니다.

패키지 목록의 패키지 위로 마우스를 가져가면 도구 설명에 해당 전이적 패키지가 프로젝트에 포함되도록 한 직접 패키지의 이름이 포함됩니다.

Visual Studio 패키지 관리자 UI 도구 설명

업데이트 없이 발견된 보안 취약성

보안 수정 없이 패키지에 알려진 취약성이 있는 경우 다음을 수행할 수 있습니다.

  • 권고 보고서에 설명된 완화 요인을 확인합니다.
  • 패키지가 사용되지 않는 것으로 표시되거나 중단된 경우 제안된 패키지를 사용합니다.
  • 패키지가 오픈 소스 경우 수정 사항을 제공하는 것이 좋습니다.
  • 패키지의 문제 추적기에서 문제를 엽니다.

완화 요인 확인

취약성이 있는 패키지를 계속 사용할 수 있는 완화 요인은 보안 관리자를 검토합니다. 이 취약성은 코드가 특정 프레임워크, 운영 체제 또는 특수 함수에서 호출되는 경우에만 존재할 수 있습니다.

제안된 패키지 사용

사용 중인 패키지에 대한 보안 권고가 보고되고 패키지가 더 이상 사용되지 않는 것으로 표시되거나 중단된 것으로 보이는 경우 패키지 작성자가 선언한 제안된 대체 패키지 또는 유지 관리되는 유사한 기능으로 구성된 패키지를 사용하는 것이 좋습니다.

수정 사항 기여

보안 권고에 대한 수정 사항이 없는 경우 패키지의 오픈 소스 리포지토리에서 끌어오기 요청의 취약성을 해결하는 변경 내용을 제안하거나 NuGet.org 패키지 세부 정보 페이지의 섹션을 통해 Contact owners 작성자에게 문의할 수 있습니다.

문제 열기

취약성을 수정하지 않거나 패키지를 업데이트하거나 바꿀 수 없는 경우 패키지의 문제 추적기 또는 기본 연락처 메서드에서 문제를 엽니다. NuGet.org 패키지 세부 정보 페이지로 이동하여 작성자와 연락하도록 안내하는 항목을 클릭 Report package 할 수 있습니다.

보안 취약성을 찾을 수 없음

보안 취약성이 없는 경우 이는 확인된 현재 시점에 알려진 취약성이 있는 패키지를 패키지 그래프에서 찾을 수 없음을 의미합니다. 권고 데이터베이스는 언제든지 업데이트할 수 있으므로 정기적으로 출력을 dotnet restore 확인하고 연속 통합 프로세스에서 동일한지 확인하는 것이 좋습니다.

CI에서 NuGet 감사 실행

전용 감사 파이프라인을 사용하여 경고에서 오류 분리

MSBuild의 조건문을 사용하여 감사 경고가 다른 파이프라인 또는 로컬 빌드에서 오류로 처리되지 않고 감사를 실행하기 위한 전용 CI 파이프라인을 구성할 수 있습니다. CI 시스템 및 팀 프로세스에 따라, 감사 파이프라인의 실패한 실행 결과를 팀에 이메일로 알리거나, 파이프라인의 최신 실행 배지를 표시하는 대시보드를 갖출 수 있습니다.

프로그래밍의 많은 것들과 마찬가지로 결과를 달성하는 방법에는 여러 가지가 있습니다. 한 가지 옵션은 NuGet 감사 경고를 감사 파이프라인에서만 오류로 처리하는 것입니다.

<PropertyGroup>
  <NuGetAuditCodes>NU1900;NU1901;NU1902;NU1903;NU1904;NU1905</NuGetAuditCodes>
  <WarningsAsErrors Condition=" '$(AuditPipeline)' == 'true' ">$(WarningsAsErrors);$(NuGetAuditCodes)</WarningsAsErrors>
  <WarningsNotAsErrors Condition=" '$(AuditPipeline)' != 'true' ">$(WarningsNotAsErrors);$(NuGetAuditCodes)</WarningsNotAsErrors>
</PropertyGroup>

그런 다음 파이프라인에서 조건에서 사용하는 속성을 지정하는 복원을 실행합니다. 예를 들어 GitHub Actions 구문을 사용합니다.

- name: Restore with NuGet Auditing
  run: dotnet restore -p:AuditPipeline=true

속성 이름은 AuditPipeline 예제일 뿐이며 MSBuild 조건과 명령줄 모두에서 이름이 같으면 원하는 대로 사용자 지정할 수 있습니다. MSBuild는 아직 정의되지 않은 속성을 읽을 때도 환경 변수를 사용하므로 환경 변수는 명령줄 매개 변수의 대안입니다.

조건을 사용하여 NuGet 감사 경고가 복원에 실패하도록 함으로써 전용 파이프라인을 사용하여 패키지에서 알려진 취약성을 확인하는 동시에 새로운 보안 권고가 불편한 시간에 버그 수정을 차단하지 않도록 할 수 있습니다. 로컬 빌드에 대해 NuGet 감사 경고를 사용하도록 설정하면 개발자가 새 보안 권고에 대한 비차단 알림을 받을 수 있으며, 누군가가 감사 파이프라인 상태를 확인할 때까지 기다리는 것보다 더 빨리 취약성을 수정하도록 패키지 버전을 업그레이드하도록 권장할 수 있습니다.

감사된 프로젝트가 복원되었는지 확인하세요.

MSBuild 17.13 및 .NET 9.0.200의 NuGet은 복원 작업에서 출력 속성 RestoreProjectCount, RestoreSkippedCountRestoreProjectsAuditedCount를 추가했습니다. 복원하는 동안 해당 감사를 실행하도록 적용하는 데 사용할 수 있습니다. 정적 그래프 복원에서는 이러한 출력 속성을 사용할 수 없습니다.

MSBuild는 스크립팅 언어이므로 여러 가지 방법으로 달성할 수 있지만 MSBuild와 동일한 제한 사항이 있습니다. 한 가지 예는 콘텐츠에 다음과 유사한 대상이 있는 솔루션 파일과 동일한 디렉터리에 Directory.Solution.targets 파일을 만드는 것입니다. Directory.Build.props는 일반적으로 사용되지만 프로젝트에서 가져옵니다. 그러나 NuGet의 복원 대상 및 작업은 솔루션 수준에서 실행되므로 프로젝트/빌드 파일이 아닌 MSBuild의 솔루션 확장성 파일에 있어야 합니다.

<Project>
    <Target Name="AssertRestoreTaskOutputProperties"
            AfterTargets="Restore"
            Condition="'$(CI)' == 'true'">
        <Error
            Condition="'$(RestoreProjectsAuditedCount)' != '$(RestoreProjectCount)'"
            Text=""Restore did not audit every project in the solution. Expected: $(RestoreProjectCount) Found: $(RestoreProjectsAuditedCount)"" />
    </Target>
</Project>

사용 사례에 따라, 복원이 이미 최신 상태여서 건너뛴 프로젝트에 대해 오류 메시지 조건 '$(RestoreProjectCount)' != '$([MSBuild::Add($(RestoreProjectsAuditedCount), $(RestoreSkippedCount))'을 사용할 수 있습니다. 마찬가지로, 이 오류가 어디서나 또는 CI 파이프라인에서만 수행되도록 하고 CI 환경에서 정의된 환경 변수를 생각해 보고 이를 대상의 조건으로 고려합니다. MSBuild는 스크립팅 언어이므로 원하는 대로 리포지토리를 사용자 지정하는 기능을 사용할 수 있습니다. MSBuild의 metaprojbinlog를 보는 것은 솔루션 수준 대상을 개발하고 문제를 해결하는 데 유용합니다.

dotnet list package --vulnerable

dotnet list package 에는 --vulnerable 알려진 취약성이 있는 패키지에 따라 패키지를 필터링하는 인수가 있습니다. --include-transitive 기본값은 아니므로 포함해야 합니다.