Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to stop the 
 “Gradle Snatchers”

How to stop the 
 “Gradle Snatchers”

Following on from one of the first recorded supply chain attacks against Gradle, this talk will discuss the security concerns surrounding our favorite 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 Android 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

July 06, 2023
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 @ Droidcon Berlin 23
  2. @sp4ghetticode / spght.dev Who am I? • Lead Android Dev

    @ ASOS • Android Google Dev Expert • I like to talk about mobile security a lot • Pomeranian Dad • Available on all good social media platforms (and also Twitter) • Danke fürs Kommen! I hope you learn something new Introduction
  3. @sp4ghetticode / spght.dev Android & Gradle 2008-2012 ‘The Eclipse Years’

    Ant + ADT Fall 2012 ‘New Build Tool’ AGP v0.1 A timeline…
  4. @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…
  5. @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…
  6. @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’
  7. @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) 💧
  8. @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’ }
  9. @sp4ghetticode / spght.dev 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… 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
  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' } Shouldn’t exist…
  12. @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' }
  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 Dependency Verification • Are my app’s dependencies

    legitimate? • Is integrity compromised? • Is the origin compromised? • What about transitive dependencies?
  16. @sp4ghetticode / spght.dev • Gradle offers a solution for both

    • Checksum Verification • Signature Verification Dependency Verification
  17. @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
  18. @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…
  19. @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
  20. @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
  21. @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
  22. @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>
  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> {project root}/gradle.properties org.gradle.dependency.verification.console=verbose
  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}/build/reports/dependency-verification
  26. @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
  27. @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
  28. @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
  29. @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)
  30. @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
  31. @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
  32. @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\\..*") } } }
  33. @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
  34. @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’
  35. @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’
  36. @sp4ghetticode / spght.dev (It’s relevant I promise) • MinecraftOnline.com •

    Oldest multiplayer Minecraft Server (2010- present) • 290,000 unique players Background
  37. @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
  38. @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
  39. @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
  40. @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)!
  41. @sp4ghetticode / spght.dev Verifying the Distribution {project root}/gradle/wrapper/gradle-wrapper.properties 
 


    distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
  42. @sp4ghetticode / spght.dev Verifying the Distribution The pros… • Guarantees

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

    to update via wrapper command and flag • Again, not many other cons (that I can think of)!
  44. @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!
  45. @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
  46. @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 at Gradle booth @ Droidcon