CINXE.COM
SLSA • Threats & mitigations
<!DOCTYPE html> <html lang="en"><head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1" /><!-- Begin Jekyll SEO tag v2.8.0 --> <meta name="generator" content="Jekyll v3.9.5" /> <meta property="og:title" content="Threats & mitigations" /> <meta property="og:locale" content="en_US" /> <meta name="description" content="A comprehensive technical analysis of supply chain threats and their corresponding mitigations in SLSA." /> <meta property="og:description" content="A comprehensive technical analysis of supply chain threats and their corresponding mitigations in SLSA." /> <meta property="og:site_name" content="SLSA" /> <meta property="og:image" content="/images/icons/android-chrome-192x192.png" /> <meta property="og:type" content="website" /> <meta name="twitter:card" content="summary_large_image" /> <meta property="twitter:image" content="/images/icons/android-chrome-192x192.png" /> <meta property="twitter:title" content="Threats & mitigations" /> <script type="application/ld+json"> {"@context":"https://schema.org","@type":"WebPage","description":"A comprehensive technical analysis of supply chain threats and their corresponding mitigations in SLSA.","headline":"Threats & mitigations","image":"/images/icons/android-chrome-192x192.png","publisher":{"@type":"Organization","logo":{"@type":"ImageObject","url":"/images/icons/android-chrome-512x512.png"}},"url":"/spec/v1.0/threats"}</script> <!-- End Jekyll SEO tag --> <link rel="stylesheet" href="/vendor/tailwindcss-2.2.19/tailwind.min.css"> <link rel="stylesheet" href="/assets/main.css"> <link rel="apple-touch-icon" sizes="180x180" href="/images/icons/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/images/icons/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/images/icons/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="/images/icons/favicon-16x16.png"> <link rel="icon" type="image/x-icon" href="/images/icons/favicon.ico"> <link rel="mask-icon" href="/images/icons/safari-pinned-tab.svg" color="#5bbad5"> <meta name="msapplication-TileColor" content="#da532c" /> <meta name="msapplication-square150x150logo" content="/images/icons/mstile-150x150.png" /> <meta name="theme-color" content="#ffffff" /> <title>SLSA • Threats & mitigations</title> <link rel="stylesheet" href="/fonts/inter/inter.css"> <link rel="stylesheet" href="/fonts/ibm_plex/IBMPlexMono-Regular.css"> <link rel="stylesheet" href="/fonts/prodigy/ProdigySans.css"> <script src="/vendor/swiper-6.8.4/swiper-bundle.min.js"></script> <link rel="stylesheet" href="/vendor/swiper-6.8.4/swiper-bundle.min.css"> <script defer src="/vendor/alpinejs-3.10.2/cdn.min.js"></script><link type="application/atom+xml" rel="alternate" href="/feed.xml" title="SLSA" /></head> <body x-data="{navOpen: false}" x-init="$refs.body.style.setProperty('--scrollbar-width', `${window.innerWidth - document.body.offsetWidth}px`)" x-ref="body" ><aside class="site-aside flex flex-col flex-none" :class="{'is-open': navOpen}" > <div class="aside-header p-5 flex justify-between items-center show-laptop"> <a rel="author" href="/" class="logo block"> <img class="logo-white" src="/images/logo.svg" alt="SLSA logo" /> </a> <a class="desktop-github-icon" href="https://github.com/slsa-framework/slsa" target="_blank"> <svg width="22" height="22" viewBox="0 0 22 22" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M11.2344 0.150879C5.28641 0.150879 0.468811 4.96848 0.468811 10.9165C0.468811 15.6803 3.55046 19.7039 7.82978 21.1303C8.36806 21.2245 8.56991 20.9016 8.56991 20.619C8.56991 20.3633 8.55646 19.5155 8.55646 18.6139C5.8516 19.1118 5.15184 17.9545 4.93653 17.3489C4.81541 17.0394 4.29059 16.084 3.83306 15.8283C3.45626 15.6264 2.91798 15.1285 3.8196 15.1151C4.66739 15.1016 5.27295 15.8956 5.47481 16.2185C6.44371 17.8468 7.99126 17.3893 8.61028 17.1067C8.70448 16.4069 8.98708 15.9359 9.29659 15.6668C6.90125 15.3977 4.39825 14.4691 4.39825 10.3513C4.39825 9.18051 4.81541 8.21161 5.50172 7.45802C5.39407 7.18888 5.01727 6.08541 5.60938 4.60514C5.60938 4.60514 6.51099 4.32254 8.56991 5.70861C9.43116 5.46639 10.3462 5.34527 11.2613 5.34527C12.1764 5.34527 13.0914 5.46639 13.9527 5.70861C16.0116 4.30909 16.9132 4.60514 16.9132 4.60514C17.5053 6.08541 17.1285 7.18888 17.0209 7.45802C17.7072 8.21161 18.1244 9.16706 18.1244 10.3513C18.1244 14.4826 15.6079 15.3977 13.2126 15.6668C13.6028 16.0032 13.9392 16.6492 13.9392 17.6584C13.9392 19.0983 13.9258 20.2556 13.9258 20.619C13.9258 20.9016 14.1276 21.238 14.6659 21.1303C16.8031 20.4088 18.6602 19.0353 19.9758 17.2031C21.2915 15.3708 21.9994 13.1721 22 10.9165C22 4.96848 17.1824 0.150879 11.2344 0.150879Z" /> </svg> </a> </div> <div class="aside-content px-5 py-1 flex-1 overflow-auto"> <select id="redirectSelect.show-laptop" class="select-dropdown p-1 mx-1 my-4 text-black opacity-80 show-laptop border-gray-400"> <option value="/spec/v1.1/threats" class="inline-block">Version 1.1 RC</option> <option selected value="/spec/v1.0/threats" class="inline-block">Version 1.0</option> <option value="/spec/v0.1/threats" class="inline-block">Version 0.1</option> <option value="/spec/draft/threats" class="inline-block">Working Draft</option> </select> <script> var selectEl = document.getElementById('redirectSelect.show-laptop'); selectEl.onchange = function(){ var goto = this.value; window.location = goto; }; </script> <nav class="site-nav"><ul><li> <a class="nav-link" href="/spec/v1.0/"> Overview </a> </li><li> <span class="section-title">Understanding SLSA</span> <ul><li> <a class="nav-link" href="/spec/v1.0/whats-new"> What's new in v1.0 </a> </li><li> <a class="nav-link" href="/spec/v1.0/about"> About SLSA </a> </li><li> <a class="nav-link" href="/spec/v1.0/threats-overview"> Supply chain threats </a> </li><li> <a class="nav-link" href="/spec/v1.0/use-cases"> Use cases </a> </li><li> <a class="nav-link" href="/spec/v1.0/principles"> Guiding principles </a> </li><li> <a class="nav-link" href="/spec/v1.0/faq"> FAQ </a> </li><li> <a class="nav-link" href="/spec/v1.0/future-directions"> Future directions </a> </li> </ul> </li><li> <span class="section-title">Core specification</span> <ul><li> <a class="nav-link" href="/spec/v1.0/terminology"> Terminology </a> </li><li> <a class="nav-link" href="/spec/v1.0/levels"> Security levels </a> </li><li> <a class="nav-link" href="/spec/v1.0/requirements"> Producing artifacts </a> </li><li> <a class="nav-link" href="/spec/v1.0/distributing-provenance"> Distributing provenance </a> </li><li> <a class="nav-link" href="/spec/v1.0/verifying-artifacts"> Verifying artifacts </a> </li><li> <a class="nav-link" href="/spec/v1.0/verifying-systems"> Verifying build platforms </a> </li><li> <a class="nav-link is-active" href="/spec/v1.0/threats"> Threats & mitigations </a> </li> </ul> </li><li> <span class="section-title">Attestation formats</span> <ul><li> <a class="nav-link" href="/attestation-model"> General model </a> </li><li> <a class="nav-link" href="/spec/v1.0/provenance"> Provenance </a> </li><li> <a class="nav-link" href="/spec/v1.0/verification_summary"> Verification Summary </a> </li> </ul> </li><li> <span class="section-title">How to SLSA</span> <ul><li> <a class="nav-link" href="/get-started"> For developers </a> </li><li> <a class="nav-link" href="/how-to-orgs"> For organizations </a> </li><li> <a class="nav-link" href="/how-to-infra"> For infrastructure providers </a> </li> </ul> </li><li> <a class="nav-link" href="/spec-stages"> Specification stages </a> </li><li> <a class="nav-link" href="/community"> Community </a> </li><li> <a class="nav-link" href="/blog"> Blog </a> </li><li> <a class="nav-link" href="/spec/v1.0/onepage"> Single-page view </a> </li> </ul> </nav> </div> </aside> <div class="site-main"> <header class="site-header flex-none" x-data="{ fixed: false, hidden: false, lastPos: window.scrollY, scrolledPast: false }" x-ref="navbar" x-on:scroll.window=" fixed = window.scrollY > lastPos ? window.scrollY >= $refs.navbar.offsetHeight : window.scrollY > 0; hidden = fixed && window.scrollY > lastPos; if (window.scrollY > $refs.navbar.offsetHeight && !scrolledPast) { setTimeout(() => $refs.navbar.classList.add('is-scrolled-past'), 500); scrolledPast = true; } else if (window.scrollY === 0) { $refs.navbar.classList.remove('is-scrolled-past'); scrolledPast = false; } lastPos = window.scrollY; " x-bind:class="{ 'is-fixed': fixed, 'is-hidden': hidden, 'menu-open': navOpen }" > <div class="site-header-inner h-full flex items-center gap-5" > <button x-on:click="navOpen = !navOpen" :class="{ 'active': navOpen }" class="mobile-menu-button inline-block hide-laptop"> <span></span> <span></span> <span></span> </button> <a rel="author" href="/" class="logo block"> <img class="logo-white" src="/images/logo.svg" alt="SLSA logo" /> </a> <select id="redirectSelect.hide-laptop" class="select-dropdown p-1 mx-1 my-4 text-black opacity-80 hide-laptop border-gray-400"> <option value="/spec/v1.1/threats" class="inline-block">Version 1.1 RC</option> <option selected value="/spec/v1.0/threats" class="inline-block">Version 1.0</option> <option value="/spec/v0.1/threats" class="inline-block">Version 0.1</option> <option value="/spec/draft/threats" class="inline-block">Working Draft</option> </select> <script> var selectEl = document.getElementById('redirectSelect.hide-laptop'); selectEl.onchange = function(){ var goto = this.value; window.location = goto; }; </script> <a class="desktop-github-icon ml-auto" href="https://github.com/slsa-framework/slsa" target="_blank"> <svg width="22" height="22" viewBox="0 0 22 22" fill="currentColor" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M11.2344 0.150879C5.28641 0.150879 0.468811 4.96848 0.468811 10.9165C0.468811 15.6803 3.55046 19.7039 7.82978 21.1303C8.36806 21.2245 8.56991 20.9016 8.56991 20.619C8.56991 20.3633 8.55646 19.5155 8.55646 18.6139C5.8516 19.1118 5.15184 17.9545 4.93653 17.3489C4.81541 17.0394 4.29059 16.084 3.83306 15.8283C3.45626 15.6264 2.91798 15.1285 3.8196 15.1151C4.66739 15.1016 5.27295 15.8956 5.47481 16.2185C6.44371 17.8468 7.99126 17.3893 8.61028 17.1067C8.70448 16.4069 8.98708 15.9359 9.29659 15.6668C6.90125 15.3977 4.39825 14.4691 4.39825 10.3513C4.39825 9.18051 4.81541 8.21161 5.50172 7.45802C5.39407 7.18888 5.01727 6.08541 5.60938 4.60514C5.60938 4.60514 6.51099 4.32254 8.56991 5.70861C9.43116 5.46639 10.3462 5.34527 11.2613 5.34527C12.1764 5.34527 13.0914 5.46639 13.9527 5.70861C16.0116 4.30909 16.9132 4.60514 16.9132 4.60514C17.5053 6.08541 17.1285 7.18888 17.0209 7.45802C17.7072 8.21161 18.1244 9.16706 18.1244 10.3513C18.1244 14.4826 15.6079 15.3977 13.2126 15.6668C13.6028 16.0032 13.9392 16.6492 13.9392 17.6584C13.9392 19.0983 13.9258 20.2556 13.9258 20.619C13.9258 20.9016 14.1276 21.238 14.6659 21.1303C16.8031 20.4088 18.6602 19.0353 19.9758 17.2031C21.2915 15.3708 21.9994 13.1721 22 10.9165C22 4.96848 17.1824 0.150879 11.2344 0.150879Z" /> </svg> </a> </div> </header> <main class="site-clamp" aria-label="Content"> <header class="content-header"> <h1 class="mb-16">Threats & mitigations</h1> </header> <div class="site-content has-toc"> <aside class="table-of-contents flex flex-col"> <div class="rounded-lg p-4 border border-gray-400 mb-4"> Status: <a href="/spec-stages" style="display: inline">Approved</a> </div> <div class="flex-auto rounded-lg p-4 border border-gray-400 overflow-auto"> <p class="header-small uppercase">On this page</p> <ul><li><a href="#source-threats">Source threats</a><ul><li><a href="#a-submit-unauthorized-change">(A) Submit unauthorized change</a></li><li><a href="#b-compromise-source-repo">(B) Compromise source repo</a></li><li><a href="#c-build-from-modified-source">(C) Build from modified source</a></li></ul></li><li><a href="#dependency-threats">Dependency threats</a><ul><li><a href="#d-use-compromised-dependency">(D) Use compromised dependency</a></li></ul></li><li><a href="#build-threats">Build threats</a><ul><li><a href="#e-compromise-build-process">(E) Compromise build process</a></li><li><a href="#f-upload-modified-package">(F) Upload modified package</a></li><li><a href="#g-compromise-package-registry">(G) Compromise package registry</a></li><li><a href="#h-use-compromised-package">(H) Use compromised package</a></li></ul></li><li><a href="#availability-threats">Availability threats</a></li><li><a href="#verification-threats">Verification threats</a></li></ul> </div> </aside> <div class="content markdown"> <p>What follows is a comprehensive technical analysis of supply chain threats and their corresponding mitigations in SLSA. For an introduction to the supply chain threats that SLSA is aiming to protect against, see <a href="threats-overview">Supply chain threats</a>.</p> <p>The examples on this page are meant to:</p> <ul> <li>Explain the reasons for each of the SLSA <a href="/spec/v1.0/requirements">requirements</a>.</li> <li>Increase confidence that the SLSA requirements are sufficient to achieve the desired <a href="/spec/v1.0/levels">level</a> of integrity protection.</li> <li>Help implementers better understand what they are protecting against so that they can better design and implement controls.</li> </ul> <article class="threats"> <p><img src="/spec/v1.0/images/supply-chain-threats.svg" alt="Supply Chain Threats" /></p> <p>See <a href="/spec/v1.0/terminology">Terminology</a> for an explanation of supply chain model.</p> <h2 id="source-threats">Source threats</h2> <p>A source integrity threat is a potential for an adversary to introduce a change to the source code that does not reflect the intent of the software producer. This includes the threat of an authorized individual introducing an unauthorized change—in other words, an insider threat.</p> <p>SLSA v1.0 does not address source threats, but we anticipate doing so in a <a href="/spec/v1.0/future-directions#source-track">future version</a>. In the meantime, the threats and potential mitigations listed here show how SLSA v1.0 can fit into a broader supply chain security program.</p> <h3 id="a-submit-unauthorized-change">(A) Submit unauthorized change</h3> <p>An adversary introduces a change through the official source control management interface without any special administrator privileges.</p> <p>SLSA v1.0 does not address this threat, but it may be addressed in a <a href="future-directions">future version</a>.</p> <h3 id="b-compromise-source-repo">(B) Compromise source repo</h3> <p>An adversary introduces a change to the source control repository through an administrative interface, or through a compromise of the underlying infrastructure.</p> <p>SLSA v1.0 does not address this threat, but it may be addressed in a <a href="future-directions">future version</a>.</p> <h3 id="c-build-from-modified-source">(C) Build from modified source</h3> <p>An adversary builds from a version of the source code that does not match the official source control repository.</p> <p>The mitigation here is to compare the provenance against expectations for the package, which depends on SLSA Build L1 for provenance. (Threats against the provenance itself are covered by (E) and (F).)</p> <details><summary>Build from unofficial fork of code <span>(expectations)</span></summary> <p><em>Threat:</em> Build using the expected CI/CD process but from an unofficial fork of the code that may contain unauthorized changes.</p> <p><em>Mitigation:</em> Verifier requires the provenance’s source location to match an expected value.</p> <p><em>Example:</em> MyPackage is supposed to be built from GitHub repo <code>good/my-package</code>. Instead, it is built from <code>evilfork/my-package</code>. Solution: Verifier rejects because the source location does not match.</p> </details> <details><summary>Build from unofficial branch or tag <span>(expectations)</span></summary> <p><em>Threat:</em> Build using the expected CI/CD process and source location, but checking out an “experimental” branch or similar that may contain code not intended for release.</p> <p><em>Mitigation:</em> Verifier requires that the provenance’s source branch/tag matches an expected value, or that the source revision is reachable from an expected branch.</p> <p><em>Example:</em> MyPackage’s releases are tagged from the <code>main</code> branch, which has branch protections. Adversary builds from the unprotected <code>experimental</code> branch containing unofficial changes. Solution: Verifier rejects because the source revision is not reachable from <code>main</code>.</p> </details> <details><summary>Build from unofficial build steps <span>(expectations)</span></summary> <p><em>Threat:</em> Build the package using the proper CI/CD platform but with unofficial build steps.</p> <p><em>Mitigation:</em> Verifier requires that the provenance’s build configuration source matches an expected value.</p> <p><em>Example:</em> MyPackage is expected to be built by Google Cloud Build using the build steps defined in the source’s <code>cloudbuild.yaml</code> file. Adversary builds with Google Cloud Build, but using custom build steps provided over RPC. Solution: Verifier rejects because the build steps did not come from the expected source.</p> </details> <details><summary>Build from unofficial parameters <span>(expectations)</span></summary> <p><em>Threat:</em> Build using the expected CI/CD process, source location, and branch/tag, but using a parameter that injects unofficial behavior.</p> <p><em>Mitigation:</em> Verifier requires that the provenance’s external parameters all match expected values.</p> <p><em>Example 1:</em> MyPackage is supposed to be built from the <code>release.yml</code> workflow. Adversary builds from the <code>debug.yml</code> workflow. Solution: Verifier rejects because the workflow parameter does not match the expected value.</p> <p><em>Example 2:</em> MyPackage’s GitHub Actions Workflow uses <code>github.event.inputs</code> to allow users to specify custom compiler flags per invocation. Adversary sets a compiler flag that overrides a macro to inject malicious behavior into the output binary. Solution: Verifier rejects because the <code>inputs</code> parameter was not expected.</p> </details> <details><summary>Build from modified version of code modified after checkout <span>(expectations)</span></summary> <p><em>Threat:</em> Build from a version of the code that includes modifications after checkout.</p> <p><em>Mitigation:</em> Build platform pulls directly from the source repository and accurately records the source location in provenance.</p> <p><em>Example:</em> Adversary fetches from MyPackage’s source repo, makes a local commit, then requests a build from that local commit. Builder records the fact that it did not pull from the official source repo. Solution: Verifier rejects because the source repo does not match the expected value.</p> </details> <h2 id="dependency-threats">Dependency threats</h2> <p>A dependency threat is a vector for an adversary to introduce behavior to an artifact through external software that the artifact requires to function.</p> <p>SLSA mitigates dependency threats when you verify your dependencies’ SLSA provenance.</p> <h3 id="d-use-compromised-dependency">(D) Use compromised dependency</h3> <details><summary>Use a compromised build dependency</summary> <p><em>Threat:</em> The adversary injects malicious code into software required to build the artifact.</p> <p><em>Mitigation:</em> N/A - This threat is out of scope of SLSA v1.0, though the build provenance may list build dependencies on a best-effort basis for forensic analysis. You may be able to mitigate this threat by pinning your build dependencies, preferably by digest rather than version number. Alternatively, you can <a href="/spec/v1.0/verifying-artifacts#step-3-optional-check-dependencies-recursively">apply SLSA recursively</a>, but we have not yet standardized how to do so.</p> <p><em>Example:</em> The artifact uses <code>libFoo</code> and requires its source code to compile. The adversary compromises <code>libFoo</code>‘s source repository and inserts malicious code. When your artifact builds, it contains the adversary’s malicious code.</p> </details> <details><summary>Use a compromised runtime dependency</summary> <p><em>Threat:</em> The adversary injects malicious code into software required to run the artifact.</p> <p><em>Mitigation:</em> N/A - This threat is out of scope of SLSA v1.0. However, you can mitigate this threat by verifying SLSA provenance for all of your runtime dependencies that provide provenance.</p> <p><em>Example:</em> The artifact dynamically links <code>libBar</code> and requires a binary version to run. The adversary compromises <code>libBar</code>‘s build process and inserts malicious code. When your artifact runs, it contains the adversary’s malicious code.</p> </details> <h2 id="build-threats">Build threats</h2> <p>A build integrity threat is a potential for an adversary to introduce behavior to an artifact without changing its source code, or to build from a source, dependency, and/or process that is not intended by the software producer.</p> <p>The SLSA Build track mitigates these threats when the consumer <a href="/spec/v1.0/verifying-artifacts">verifies artifacts</a> against expectations, confirming that the artifact they received was built in the expected manner.</p> <h3 id="e-compromise-build-process">(E) Compromise build process</h3> <p>An adversary introduces an unauthorized change to a build output through tampering of the build process; or introduces false information into the provenance.</p> <p>These threats are directly addressed by the SLSA Build track.</p> <details><summary>Forge values of the provenance (other than output digest) <span>(Build L2+)</span></summary> <p><em>Threat:</em> Generate false provenance and get the trusted control plane to sign it.</p> <p><em>Mitigation:</em> At Build L2+, the trusted control plane <a href="/spec/v1.0/requirements#provenance-authentic">generates</a> all information that goes in the provenance, except (optionally) the output artifact hash. At Build L3+, this is <a href="/spec/v1.0/requirements#provenance-unforgeable">hardened</a> to prevent compromise even by determined adversaries.</p> <p><em>Example 1 (Build L2):</em> Provenance is generated on the build worker, which the adversary has control over. Adversary uses a malicious process to get the build platform to claim that it was built from source repo <code>good/my-package</code> when it was really built from <code>evil/my-package</code>. Solution: Builder generates and signs the provenance in the trusted control plane; the worker reports the output artifacts but otherwise has no influence over the provenance.</p> <p><em>Example 2 (Build L3):</em> Provenance is generated in the trusted control plane, but workers can break out of the container to access the signing material. Solution: Builder is hardened to provide strong isolation against tenant projects.</p> </details> <details id="forged-digest"><summary>Forge output digest of the provenance <span>(n/a)</span></summary> <p><em>Threat:</em> The tenant-controlled build process sets output artifact digest (<code>subject</code> in SLSA Provenance) without the trusted control plane verifying that such an artifact was actually produced.</p> <p><em>Mitigation:</em> None; this is not a problem. Any build claiming to produce a given artifact could have actually produced it by copying it verbatim from input to output.<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup> (Reminder: Provenance is only a claim that a particular artifact was <em>built</em>, not that it was <em>published</em> to a particular registry.)</p> <p><em>Example:</em> A legitimate MyPackage artifact has digest <code>abcdef</code> and is built from source repo <code>good/my-package</code>. A malicious build from source repo <code>evil/my-package</code> claims that it built artifact <code>abcdef</code> when it did not. Solution: Verifier rejects because the source location does not match; the forged digest is irrelevant.</p> </details> <details><summary>Compromise project owner <span>(Build L2+)</span></summary> <p><em>Threat:</em> An adversary gains owner permissions for the artifact’s build project.</p> <p><em>Mitigation:</em> The build project owner must not have the ability to influence the build process or provenance generation.</p> <p><em>Example:</em> MyPackage is built on Awesome Builder under the project “mypackage”. Adversary is an administrator of the “mypackage” project. Awesome Builder allows administrators to debug build machines via SSH. An adversary uses this feature to alter a build in progress.</p> </details> <details><summary>Compromise other build <span>(Build L3)</span></summary> <p><em>Threat:</em> Perform a malicious build that alters the behavior of a benign build running in parallel or subsequent environments.</p> <p><em>Mitigation:</em> Builds are <a href="/spec/v1.0/requirements#isolated">isolated</a> from one another, with no way for one to affect the other or persist changes.</p> <p><em>Example 1:</em> A build platform runs all builds for project MyPackage on the same machine as the same Linux user. An adversary starts a malicious build that listens for another build and swaps out source files, then starts a benign build. The benign build uses the malicious build’s source files, but its provenance says it used benign source files. Solution: The build platform changes architecture to isolate each build in a separate VM or similar.</p> <p><em>Example 2:</em> A build platform uses the same machine for subsequent builds. An adversary first runs a build that replaces the <code>make</code> binary with a malicious version, then subsequently runs an otherwise benign build. Solution: The builder changes architecture to start each build with a clean machine image.</p> </details> <details><summary>Steal cryptographic secrets <span>(Build L3)</span></summary> <p><em>Threat:</em> Use or exfiltrate the provenance signing key or some other cryptographic secret that should only be available to the build platform.</p> <p><em>Mitigation:</em> Builds are <a href="/spec/v1.0/requirements#isolated">isolated</a> from the trusted build platform control plane, and only the control plane has <a href="/spec/v1.0/requirements#provenance-unforgeable">access</a> to cryptographic secrets.</p> <p><em>Example:</em> Provenance is signed on the build worker, which the adversary has control over. Adversary uses a malicious process that generates false provenance and signs it using the provenance signing key. Solution: Builder generates and signs provenance in the trusted control plane; the worker has no access to the key.</p> </details> <details><summary>Poison the build cache <span>(Build L3)</span></summary> <p><em>Threat:</em> Add a malicious artifact to a build cache that is later picked up by a benign build process.</p> <p><em>Mitigation:</em> Build caches must be <a href="/spec/v1.0/requirements#isolated">isolate</a> between builds to prevent such cache poisoning attacks.</p> <p><em>Example:</em> Build platform uses a build cache across builds, keyed by the hash of the source file. Adversary runs a malicious build that creates a “poisoned” cache entry with a falsified key, meaning that the value wasn’t really produced from that source. A subsequent build then picks up that poisoned cache entry.</p> </details> <details><summary>Compromise build platform admin <span>(verification)</span></summary> <p><em>Threat:</em> An adversary gains admin permissions for the artifact’s build platform.</p> <p><em>Mitigation:</em> The build platform must have controls in place to prevent and detect abusive behavior from administrators (e.g. two-person approvals, audit logging).</p> <p><em>Example:</em> MyPackage is built on Awesome Builder. Awesome Builder allows engineers on-call to SSH into build machines to debug production issues. An adversary uses this access to modify a build in progress. Solution: Consumers do not accept provenance from the build platform unless they trust sufficient controls are in place to prevent abusing admin privileges.</p> </details> <h3 id="f-upload-modified-package">(F) Upload modified package</h3> <p>An adversary uploads a package not built from the proper build process.</p> <details><summary>Build with untrusted CI/CD <span>(expectations)</span></summary> <p><em>Threat:</em> Build using an unofficial CI/CD pipeline that does not build in the correct way.</p> <p><em>Mitigation:</em> Verifier requires provenance showing that the builder matched an expected value.</p> <p><em>Example:</em> MyPackage is expected to be built on Google Cloud Build, which is trusted up to Build L3. Adversary builds on SomeOtherBuildPlatform, which is only trusted up to Build L2, and then exploits SomeOtherBuildPlatform to inject malicious behavior. Solution: Verifier rejects because builder is not as expected.</p> </details> <details><summary>Upload package without provenance <span>(Build L1)</span></summary> <p><em>Threat:</em> Upload a package without provenance.</p> <p><em>Mitigation:</em> Verifier requires provenance before accepting the package.</p> <p><em>Example:</em> Adversary uploads a malicious version of MyPackage to the package repository without provenance. Solution: Verifier rejects because provenance is missing.</p> </details> <details><summary>Tamper with artifact after CI/CD <span>(Build L1)</span></summary> <p><em>Threat:</em> Take a benign version of the package, modify it in some way, then re-upload it using the original provenance.</p> <p><em>Mitigation:</em> Verifier checks that the provenance’s <code>subject</code> matches the hash of the package.</p> <p><em>Example:</em> Adversary performs a proper build, modifies the artifact, then uploads the modified version of the package to the repository along with the provenance. Solution: Verifier rejects because the hash of the artifact does not match the <code>subject</code> found within the provenance.</p> </details> <details><summary>Tamper with provenance <span>(Build L2)</span></summary> <p><em>Threat:</em> Perform a build that would not meet expectations, then modify the provenance to make the expectations checks pass.</p> <p><em>Mitigation:</em> Verifier only accepts provenance with a valid <a href="/spec/v1.0/requirements#provenance-authentic">cryptographic signature</a> or equivalent proving that the provenance came from an acceptable builder.</p> <p><em>Example:</em> MyPackage is expected to be built by GitHub Actions from the <code>good/my-package</code> repo. Adversary builds with GitHub Actions from the <code>evil/my-package</code> repo and then modifies the provenance so that the source looks like it came from <code>good/my-package</code>. Solution: Verifier rejects because the cryptographic signature is no longer valid.</p> </details> <h3 id="g-compromise-package-registry">(G) Compromise package registry</h3> <p>An adversary modifies the package on the package registry using an administrative interface or through a compromise of the infrastructure.</p> <details><summary>De-list artifact</summary> <p><em>Threat:</em> The package registry stops serving the artifact.</p> <p><em>Mitigation:</em> N/A - This threat is out of scope of SLSA v1.0.</p> </details> <details><summary>De-list provenance</summary> <p><em>Threat:</em> The package registry stops serving the provenance.</p> <p><em>Mitigation:</em> N/A - This threat is out of scope of SLSA v1.0.</p> </details> <h3 id="h-use-compromised-package">(H) Use compromised package</h3> <p>An adversary modifies the package after it has left the package registry, or tricks the user into using an unintended package.</p> <details><summary>Typosquatting</summary> <p><em>Threat:</em> Register a package name that is similar looking to a popular package and get users to use your malicious package instead of the benign one.</p> <p><em>Mitigation:</em> <strong>Mostly outside the scope of SLSA.</strong> That said, the requirement to make the source available can be a mild deterrent, can aid investigation or ad-hoc analysis, and can complement source-based typosquatting solutions.</p> </details> <h2 id="availability-threats">Availability threats</h2> <p>An availability threat is a potential for an adversary to deny someone from reading a source and its associated change history, or from building a package.</p> <p>SLSA v1.0 does not address availability threats, though future versions might.</p> <details><summary>(A)(B) Delete the code</summary> <p><em>Threat:</em> Perform a build from a particular source revision and then delete that revision or cause it to get garbage collected, preventing anyone from inspecting the code.</p> <p><em>Mitigation:</em> Some system retains the revision and its version control history, making it available for inspection indefinitely. Users cannot delete the revision except as part of a transparent legal or privacy process.</p> <p><em>Example:</em> An adversary submits malicious code to the MyPackage GitHub repo, builds from that revision, then does a force push to erase that revision from history (or requests that GitHub delete the repo.) This would make the revision unavailable for inspection. Solution: Verifier rejects the package because it lacks a positive attestation showing that some system, such as GitHub, ensured retention and availability of the source code.</p> </details> <details><summary>(D) A dependency becomes temporarily or permanently unavailable to the build process</summary> <p><em>Threat:</em> Unable to perform a build with the intended dependencies.</p> <p><em>Mitigation:</em> <strong>Outside the scope of SLSA.</strong> That said, some solutions to support hermetic and reproducible builds may also reduce the impact of this threat.</p> </details> <h2 id="verification-threats">Verification threats</h2> <p>Threats that can compromise the ability to prevent or detect the supply chain security threats above.</p> <details><summary>Tamper with recorded expectations</summary> <p><em>Threat:</em> Modify the verifier’s recorded expectations, causing the verifier to accept an unofficial package artifact.</p> <p><em>Mitigation:</em> Changes to recorded expectations requires some form of authorization, such as two-party review.</p> <p><em>Example:</em> The package ecosystem records its expectations for a given package name in a configuration file that is modifiable by that package’s producer. The configuration for MyPackage expects the source repository to be <code>good/my-package</code>. The adversary modifies the configuration to also accept <code>evil/my-package</code>, and then builds from that repository and uploads a malicious version of the package. Solution: Changes to the recorded expectations require two-party review.</p> </details> <details><summary>Forge change metadata</summary> <p><em>Threat:</em> Forge the change metadata to alter attribution, timestamp, or discoverability of a change.</p> <p><em>Mitigation:</em> Source control platform strongly authenticates actor identity, timestamp, and parent revisions.</p> <p><em>Example:</em> Adversary submits a git commit with a falsified author and timestamp, and then rewrites history with a non-fast-forward update to make it appear to have been made long ago. Solution: Consumer detects this by seeing that such changes are not strongly authenticated and thus not trustworthy.</p> </details> <details><summary>Exploit cryptographic hash collisions</summary> <p><em>Threat:</em> Exploit a cryptographic hash collision weakness to bypass one of the other controls.</p> <p><em>Mitigation:</em> Require cryptographically secure hash functions for commit checksums and provenance subjects, such as SHA-256.</p> <p><em>Examples:</em> Construct a benign file and a malicious file with the same SHA-1 hash. Get the benign file reviewed and then submit the malicious file. Alternatively, get the benign file reviewed and submitted and then build from the malicious file. Solution: Only accept cryptographic hashes with strong collision resistance.</p> </details> </article> <!-- Links --> <section class="footnotes"> <ol> <li id="fn1"> <p>Technically this requires the artifact to be known to the adversary. If they only know the digest but not the actual contents, they cannot actually build the artifact without a <a href="https://en.wikipedia.org/wiki/Preimage_attack">preimage attack</a> on the digest algorithm. However, even still there are no known concerns where this is a problem. <a href="#fnref1" class="footnote-backref">↩</a></p> </li> </ol> </section> <div class="mt-10 pt-10 border-t flex flex-col sm:flex-row space-between gap-5"> <a href="/spec/v1.0/verifying-systems" class="border rounded px-4 py-2 text-left">‹ Verifying build platforms</a> <a href="/spec/v1.0/provenance" class="sm:ml-auto border rounded px-4 py-2 text-right">Provenance ›</a> </div> </div> </div> </main><footer class="site-footer flex-none h-card text-white"> <div class="site-clamp py-4 flex flex-wrap items-start justify-between w-full"> <div class="w-full md:w-1/3 mb-8 md:mb-0"> <p><strong>SLSA is a cross-industry collaboration.</strong><br> © 2024 The Linux Foundation, under the terms of the <a href="https://github.com/slsa-framework/governance">Community Specification License 1.0</a></p> </div> <div class="w-full md:w-1/3 mb-8 md:mb-0"> <p><strong>Privacy statement</strong><br> We use <a href="https://goatcounter.com">GoatCounter</a> to help us improve our website by collecting and reporting information on how it's used. We do not store advertising or tracking cookies. The information we collect does not identify anyone and does not track an individual's use of the site.</p> </div> <div class="w-full md:w-1/4 mb-8 md:mb-0 flex md:justify-end"> <p> <a href="https://github.com/slsa-framework/slsa/blob/910587ad00cc1f893b1e1ef6af3fb00c382e72f3/docs/spec/v1.0/threats.md?plain=1" target="_blank" class="flex gap-4 h5 font-normal"> View source on GitHub <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M11.2344 0.150879C5.28641 0.150879 0.468811 4.96848 0.468811 10.9165C0.468811 15.6803 3.55046 19.7039 7.82978 21.1303C8.36806 21.2245 8.56991 20.9016 8.56991 20.619C8.56991 20.3633 8.55646 19.5155 8.55646 18.6139C5.8516 19.1118 5.15184 17.9545 4.93653 17.3489C4.81541 17.0394 4.29059 16.084 3.83306 15.8283C3.45626 15.6264 2.91798 15.1285 3.8196 15.1151C4.66739 15.1016 5.27295 15.8956 5.47481 16.2185C6.44371 17.8468 7.99126 17.3893 8.61028 17.1067C8.70448 16.4069 8.98708 15.9359 9.29659 15.6668C6.90125 15.3977 4.39825 14.4691 4.39825 10.3513C4.39825 9.18051 4.81541 8.21161 5.50172 7.45802C5.39407 7.18888 5.01727 6.08541 5.60938 4.60514C5.60938 4.60514 6.51099 4.32254 8.56991 5.70861C9.43116 5.46639 10.3462 5.34527 11.2613 5.34527C12.1764 5.34527 13.0914 5.46639 13.9527 5.70861C16.0116 4.30909 16.9132 4.60514 16.9132 4.60514C17.5053 6.08541 17.1285 7.18888 17.0209 7.45802C17.7072 8.21161 18.1244 9.16706 18.1244 10.3513C18.1244 14.4826 15.6079 15.3977 13.2126 15.6668C13.6028 16.0032 13.9392 16.6492 13.9392 17.6584C13.9392 19.0983 13.9258 20.2556 13.9258 20.619C13.9258 20.9016 14.1276 21.238 14.6659 21.1303C16.8031 20.4088 18.6602 19.0353 19.9758 17.2031C21.2915 15.3708 21.9994 13.1721 22 10.9165C22 4.96848 17.1824 0.150879 11.2344 0.150879Z" fill="white"/> </svg> </a> <br> This site is powered by <a href="https://www.netlify.com">Netlify</a> </p> </div> </div> <div class="site-clamp py-4 flex items-start justify-between w-full mb-16 md:mb-0"> <a rel="author" href="/"><img src="/images/logo.svg" alt="SLSA logo" /></a> </div> </footer> </div> </body> </html>