Dependency Security

Swift CocoaPods and SPM Security

Securing iOS and macOS dependencies with Swift Package Manager and CocoaPods, including checksum verification and source control.

Nayan Dey
DevSecOps Lead
4 min read

Apple platform development has two primary dependency management systems: CocoaPods and Swift Package Manager (SPM). Both have different security models and risks. If you ship iOS or macOS apps, you need to understand and secure both.

Swift Package Manager Security

SPM is Apple's first-party dependency manager, integrated directly into Xcode. It resolves dependencies from Git repositories and records exact versions in Package.resolved.

Package.resolved

This file is your lockfile. It records the exact Git revision for every dependency:

{
  "pins": [
    {
      "identity": "alamofire",
      "kind": "remoteSourceControl",
      "location": "https://github.com/Alamofire/Alamofire.git",
      "state": {
        "revision": "f455c2975872ccd2d9c81594c658af65716e9b9a",
        "version": "5.8.1"
      }
    }
  ]
}

Commit Package.resolved. It ensures every team member and CI build uses the same dependency versions.

Source Integrity

SPM pins dependencies to Git commits, not tags. This is important because tags are mutable in Git. An attacker who gains access to a dependency's repository could move a tag to point to malicious code. The commit hash in Package.resolved protects against this.

However, SPM does not verify checksums of downloaded source code against a public database. It trusts the Git hosting provider. If the hosting provider is compromised, SPM will fetch whatever code is at the recorded commit.

Binary Dependencies

SPM supports binary dependencies distributed as XCFrameworks. These are precompiled binaries, which means you cannot inspect the source code:

.binaryTarget(
    name: "SomeSDK",
    url: "https://example.com/SomeSDK-1.0.0.xcframework.zip",
    checksum: "abc123..."
)

The checksum verification is critical for binary targets. Always specify and verify checksums. Be cautious about adding binary dependencies from sources you do not trust.

Restricting SPM Sources

SPM does not have a concept of a registry. Dependencies come from Git URLs. This means:

  • There is no typosquatting risk from a central registry.
  • But there is a risk of URL confusion. github.com/user/package vs github.com/user-typo/package.
  • Dependencies can point to any Git server, including potentially compromised ones.

Review all SPM dependency URLs carefully. Use organization-level GitHub settings to restrict which repositories can be added as dependencies if possible.

CocoaPods Security

CocoaPods uses a centralized spec repository on GitHub and hosts most libraries on trunk.cocoapods.org.

Podfile.lock

Like Gemfile.lock for Ruby, Podfile.lock records exact versions:

PODS:
  - Alamofire (5.8.1)
  - SwiftyJSON (5.0.1)

DEPENDENCIES:
  - Alamofire (~> 5.8)
  - SwiftyJSON (~> 5.0)

SPEC CHECKSUMS:
  Alamofire: 3ca42e259f7c4724f8c0d1f2d7b2289e3c038592
  SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e

COCOAPODS: 1.14.2

The SPEC CHECKSUMS section contains hashes of the podspec files. This verifies the spec integrity but not the source code itself.

Commit Podfile.lock. Run pod install (not pod update) in CI.

CocoaPods Trunk Security

In 2021, a vulnerability in the CocoaPods trunk server could have allowed an attacker to replace any pod with malicious code. The issue was fixed, but it highlighted the risks of centralized package management.

Mitigations:

  • Pin exact versions in your Podfile.
  • Review spec checksum changes in Podfile.lock.
  • Consider migrating to SPM where possible, as it does not rely on a centralized trunk server.

Private Pods

For internal libraries, use a private spec repository:

# Podfile
source 'https://github.com/yourcompany/private-specs.git'
source 'https://cdn.cocoapods.org/'

pod 'YourInternalLib', '~> 2.0'

List your private source first to give it priority over the public CDN.

Migrating from CocoaPods to SPM

Apple is investing heavily in SPM, and the CocoaPods maintainers have acknowledged the project has a smaller active maintainer base. For long-term security, migrating to SPM makes sense:

  1. Check which of your pods are available as SPM packages.
  2. Add SPM packages in Xcode via File > Add Packages.
  3. Remove the corresponding pods from your Podfile.
  4. Test thoroughly, as the build integration is different.

Vulnerability Scanning for Apple Platforms

The Apple platform ecosystem has fewer automated scanning tools compared to other ecosystems:

  • OWASP Dependency-Check supports Swift packages.
  • Snyk has iOS support for both CocoaPods and SPM.
  • GitHub Dependabot can scan Package.resolved files.

Run scanning in CI:

# Check for known vulnerabilities in your Podfile.lock
# Using a third-party tool
pod_audit Podfile.lock

SBOM Generation

For iOS projects, generate SBOMs from your resolved dependency files:

# Using CycloneDX
cyclonedx-cocoapods -p Podfile.lock -o sbom.json

For SPM projects, tools like swift-package-manager-sbom can parse Package.resolved into CycloneDX format.

How Safeguard.sh Helps

Safeguard.sh brings the same dependency monitoring to Apple platform development that backend teams already rely on. It ingests SBOMs from your iOS and macOS builds, tracks framework and library versions across your app portfolio, and alerts your team when vulnerabilities are discovered in your dependencies. For organizations shipping multiple apps with shared dependency trees, Safeguard.sh provides the cross-app visibility to ensure a vulnerability in a common library like Alamofire is addressed everywhere, not just in the first app where it is noticed.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.