Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

How to stop the “Gradle Snatchers”: Securing yo...

How to stop the “Gradle Snatchers”: Securing your builds from baddies @ AMxDC 24

Following on from one of the first recorded supply chain attacks against Gradle, this talk will discuss the security concerns surrounding our favourite build tool and how we can protect against them. This starts with gaining an understanding of some of Gradle's common vulnerabilities and how to avoid these within our projects. You'll leave this talk with:

- Insights on the Gradle Wrapper supply-chain attack and how to protect against it.
- An overview of a Gradle dependency attack and how to protect against them.
- A concrete list of security setting best practices within Gradle, including wrapper verification, repository filtering, dependency verification and others.

Ed Holloway-George

May 02, 2024
Tweet

More Decks by Ed Holloway-George

Other Decks in Technology

Transcript

  1. @sp4ghetticode / spght.dev How to stop the “Gradle Snatchers” Securing

    your builds from baddies Ed Holloway-George @ AMxDC24
  2. @sp4ghetticode / spght.dev Who am I? • Lead Android Dev

    @ ASOS • Android Google Dev Expert • I like to talk about mobile security a lot • Available on all good social media platforms (and also Twitter) • First talk in Paris, thanks for inviting me • Merci for coming! I hope you learn something new Introduction
  3. @sp4ghetticode / spght.dev • Real-world stories • Securing Dependencies •

    How to do it via Gradle • Securing Tooling • Securing Gradle wrappers • Securing Gradle distros What we will look at today Stickers available from me (while stocks last!)
  4. @sp4ghetticode / spght.dev Android & Gradle 2008-2012 ‘The Eclipse Years’

    Ant + ADT Fall 2012 ‘New Build Tool’ AGP v0.1 A timeline…
  5. @sp4ghetticode / spght.dev Android & Gradle 2008-2012 ‘The Eclipse Years’

    Ant + ADT Fall 2012 ‘New Build Tool’ AGP v0.1 Winter 2014 ‘Initial Release’ AGP v1.0 A timeline…
  6. @sp4ghetticode / spght.dev l 2012 uild Tool’ P v0.1 Winter

    2014 ‘Initial Release’ AGP v1.0 2024 Present Day AGP v8.x Android & Gradle A timeline…
  7. @sp4ghetticode / spght.dev l 2012 uild Tool’ P v0.1 Winter

    2014 ‘Initial Release’ AGP v1.0 2024 Present Day AGP v8.x Android & Gradle A timeline… Winter 2018 ‘A Confusing Dependency’
  8. @sp4ghetticode / spght.dev Márton Braun @zsmb13 A Confusing Dependency… java.lang.SecurityException:

    Permission denied (missing INTERNET permission?) at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:135) at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90) at java.net.InetAddress.getByName(InetAddress.java:743) 💧
  9. @sp4ghetticode / spght.dev Márton Braun @zsmb13 A Confusing Dependency… repositories

    { google() jcenter() maven { url "https://jitpack.io" } } dependencies { implementation ‘com.example:foo:0.0.1’ }
  10. @sp4ghetticode / spght.dev A Confusing Dependency… repositories { google() jcenter()

    maven { url "https://jitpack.io" } } dependencies { implementation 'com.example:foo:0.0.1' }
  11. @sp4ghetticode / spght.dev A Confusing Dependency… com.example:foo:0.0.1 repositories { google()

    jcenter() maven { url "https://jitpack.io" } } dependencies { implementation 'com.example:foo:0.0.1' } Does not exist
  12. @sp4ghetticode / spght.dev A Confusing Dependency… com.example:foo:0.0.1 repositories { google()

    jcenter() maven { url "https://jitpack.io" } } dependencies { implementation 'com.example:foo:0.0.1' } Shouldn’t exist…
  13. @sp4ghetticode / spght.dev A Confusing Dependency… jakewhaarton/timber/com.example:foo:0.0.1 repositories { google()

    jcenter() maven { url "https://jitpack.io" } } dependencies { implementation 'com.example:foo:0.0.1' }
  14. @sp4ghetticode / spght.dev A Confusing Dependency… jakewhaarton/timber/com.example:foo:0.0.1 repositories { google()

    jcenter() maven { url "https://jitpack.io" } } dependencies { implementation ‘com.example:foo:0.0.1' }
  15. @sp4ghetticode / spght.dev A Confusing Dependency… jakewhaarton/timber/com.example:foo:0.0.1 repositories { google()

    jcenter() maven { url "https://jitpack.io" } } dependencies { implementation 'com.example:foo:0.0.1' }
  16. @sp4ghetticode / spght.dev Dependency Verification • Are my app’s dependencies

    legitimate? 🧐 • Is integrity compromised? • i.e. Are the files the ones we expected? • Is the origin compromised? • i.e. Was it published by the expected author?
  17. @sp4ghetticode / spght.dev • Gradle offers a solution for both

    • Checksum Verification • Signature Verification Dependency Verification
  18. @sp4ghetticode / spght.dev Checksum Verification Example • Common algorithms to

    use MD5 / SHA-1 / SHA-256 • MD5 was proved to be broken in late 90s • SHA-1 also proved to be broken in 2017
  19. @sp4ghetticode / spght.dev Checksum Verification Example $ echo "Hello World"

    >> example.txt SHA-1 $ shasum example.txt 648a6a6ffffdaa0badb23… SHA-256 $ shasum -a 256 example.txt d2a84f4b8b650937ec8f73…
  20. @sp4ghetticode / spght.dev Gradle Dependency Setup ./gradlew --write-verification-metadata sha256 <verification-metadata>

    <configuration> <verify-metadata>true</verify-metadata> <verify-signatures>false</verify-signatures> </configuration> <components>…</components> </verification-metadata> {project root}/gradle/verification-metadata.xml
  21. @sp4ghetticode / spght.dev Gradle Dependency Setup ./gradlew --write-verification-metadata sha256 <components>

    <component group="com.jakewharton.timber" name="timber" version="5.0.1"> <artifact name="timber-5.0.1.aar"> <sha256 value="c6edddfc..." origin="Generated by Gradle"/> <sha512 value="37a3e784..." origin="Generated by Gradle"/> </artifact> </component> </components> {project root}/gradle/verification-metadata.xml
  22. @sp4ghetticode / spght.dev How it works… <components> <component group="com.jakewharton.timber" name="timber"

    version="5.0.1"> <artifact name="timber-5.0.1.aar"> <sha256 value="c6edddfc..." origin="Generated by Gradle"/> <sha512 value="37a3e784..." origin="Generated by Gradle"/> </artifact> </component> </components> .sha256 .sha512 Maven Repo
  23. @sp4ghetticode / spght.dev Reporting issues <components> <component group="com.jakewharton.timber" name="timber" version="5.0.1">

    <artifact name="timber-5.0.1.aar"> <sha256 value="ffedddfc..." origin="Generated by Gradle"/> <sha512 value="ffa3e784..." origin="Generated by Gradle"/> </artifact> </component> </components>
  24. @sp4ghetticode / spght.dev Reporting issues <components> <component group="com.jakewharton.timber" name="timber" version="5.0.1">

    <artifact name="timber-5.0.1.aar"> <sha256 value="ffedddfc..." origin="Generated by Gradle"/> <sha512 value="ffa3e784..." origin="Generated by Gradle"/> </artifact> </component> </components>
  25. @sp4ghetticode / spght.dev Reporting issues <components> <component group="com.jakewharton.timber" name="timber" version="5.0.1">

    <artifact name="timber-5.0.1.aar"> <sha256 value="ffedddfc..." origin="Generated by Gradle"/> <sha512 value="ffa3e784..." origin="Generated by Gradle"/> </artifact> </component> </components> {project root}/gradle.properties org.gradle.dependency.verification.console=verbose
  26. @sp4ghetticode / spght.dev Reporting issues <components> <component group="com.jakewharton.timber" name="timber" version="5.0.1">

    <artifact name="timber-5.0.1.aar"> <sha256 value="ffedddfc..." origin="Generated by Gradle"/> <sha512 value="ffa3e784..." origin="Generated by Gradle"/> </artifact> </component> </components> {project root}/build/reports/dependency-verification
  27. @sp4ghetticode / spght.dev Signature Verification Example • Public Maven repos

    often require signed artifacts • Signed using PGP standard • Developer must create a key-pair • Upload public key to key-server • Sign artifacts and upload to Maven repo
  28. @sp4ghetticode / spght.dev Gradle Dependency Setup ./gradlew --write-verification-metadata sha256,pgp <verification-metadata>

    <configuration> <verify-metadata>true</verify-metadata> <verify-signatures>true</verify-signatures> </configuration> <trusted-keys>…</trusted-keys> </verification-metadata> {project root}/gradle/verification-metadata.xml
  29. @sp4ghetticode / spght.dev Gradle Dependency Setup ./gradlew --write-verification-metadata sha256,pgp <trusted-keys>

    <trusted-key id=“47bf5922…” group="com.jakewharton.timber" name=“timber" version="5.0.1"/> </trusted-keys> {project root}/gradle/verification-metadata.xml
  30. @sp4ghetticode / spght.dev Dependency Verification The pros… • Gain trust

    in your app’s dependencies • Flexible in the type of verification you wish to use Supply chain attacks mitigated • You will sleep a lot easier at night! (and so will I)
  31. @sp4ghetticode / spght.dev The cons… • This is not a

    frictionless process • You MUST start with total trust in the dependencies • You could still include compromised dependencies • XML 💩 • Simplest solution: Ship with no dependencies! (Yes, really 😅) Dependency Verification
  32. @sp4ghetticode / spght.dev Repository Filter • Filter what packages can

    be fetched from repos • Rules to include and exclude dependencies • Works for dependencies and plugins • Note: Use Gradle 7.0+ (Due to CVE-2021-29427)* * Discovered by Droidcon regular @ZacSweers
  33. @sp4ghetticode / spght.dev Repository Filter repositories { maven { url

    "https://jitpack.io" content { // Fetch dependencies includeGroup "com.example" includeModule("com.example", "foo") // Exclude dependencies excludeGroupByRegex("dev\\.spght\\..*") } } }
  34. @sp4ghetticode / spght.dev Repository Filter • Gain trust your dependencies

    come from the right source • Ordering issues eliminated • Can easily create simple or complex rulesets • Do not leak dependencies by calling multiple repos * Discovered by Droidcon regular @ZacSweers
  35. @sp4ghetticode / spght.dev l 2012 uild Tool’ P v0.1 Winter

    2014 ‘Initial Release’ AGP v1.0 2023 Present Day AGP v8.x Android & Gradle A timeline… Winter 2018 ‘A Confusing Dependency’
  36. @sp4ghetticode / spght.dev 014 lease’ 0 2023 Present Day AGP

    v8.x Android & Gradle A timeline… Winter 2018 ‘A Confusing Dependency’ Winter 2022 ‘Wrapper Exploit Observed’
  37. @sp4ghetticode / spght.dev (It’s relevant I promise) • MinecraftOnline.com •

    Oldest multiplayer Minecraft Server (2010- present) • 290,000 unique players Background
  38. @sp4ghetticode / spght.dev (It’s relevant I promise) • Minecraft servers

    use ‘plugins’ • Plugins are JVM language projects (like Android) • Gradle is the build system used (like Android) Background
  39. @sp4ghetticode / spght.dev How to prevent this! • First known

    public supply-chain attack on the Wrapper • Verification of wrapper’s integrity prevents this • Verification of Gradle binary is a good second step • Hashes of wrapper and distributions available • gradle.org/release-checksums
  40. @sp4ghetticode / spght.dev Verifying the Wrapper The pros… • Mega

    straightforward • You could probably do it before I finish this talk • Easily slips into most CI pipelines • GitHub users pretty much get it for free
  41. @sp4ghetticode / spght.dev Verifying the Wrapper The cons… • Still

    fairly unlikely to be an attack vector • Otherwise, no other cons (that I can think of)!
  42. @sp4ghetticode / spght.dev Verifying the Distribution ./gradlew wrapper --gradle-version=7.5 \

    --gradle-distribution-sha256-sum=cb87f222c… Remember: Run this cmd twice!
  43. @sp4ghetticode / spght.dev Verifying the Distribution The pros… • Guarantees

    integrity of your Gradle distro • Simple to setup • Verification is quick
  44. @sp4ghetticode / spght.dev Verifying the Distribution The cons… • Remembering

    to update via wrapper command and flag • As well as remembering to call it twice… • Again, not many other cons (that I can think of)!
  45. @sp4ghetticode / spght.dev Verifying the gradlew file (Not yet) •

    The gradlew script is also often overlooked • No official process for verifying • Roll your own solution? 😅 • Have thorough PR review processes!
  46. @sp4ghetticode / spght.dev In summary… • Gradle supply-chain attacks are

    very rare but do occur • Consider dependency verification • Use repository filtering to ensure the origin • Verify your wrappers • Verify your distribution
  47. @sp4ghetticode / spght.dev I want to learn more… (Perhaps from

    someone better?!) • Great talk by Cédric Champeau from Gradle at Devoxx 2019 • Gradle Security documentation • Speak to a nice human from Gradle @ Android Makers