Skip to content

Commit

Permalink
Make the addition of JitPack repository configurable (#48595)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #48595

Historically React Native used to include the JitPack repository be default in the default repositories.

This sadly exposes React Native projects to supply chain attacks as explained here:
https://blog.oversecured.com/Introducing-MavenGate-a-supply-chain-attack-method-for-Java-and-Android-applications/

Moreover, artifacts on Jitpack are not GPG signed it's complicated to verify the identity of artifact authors.
I'm introducing a Gradle property to control if Jitpack should be included by default or not.

User can control this behavior by changing their `gradle.properties` file as such:

```
includeJitpackRepository=false
```

The default value of this property is currently true, but we're looking into changing it to false in the future.

Changelog:
[Android] [Added] - Make the addition of JitPack repository configurable

Reviewed By: cipolleschi

Differential Revision: D68016028

fbshipit-source-id: 392513fef389a4835b4e00a8184459e00d51fdd0
  • Loading branch information
cortinico authored and facebook-github-bot committed Jan 10, 2025
1 parent c85be01 commit a98528e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
package com.facebook.react.utils

import com.facebook.react.utils.PropertyUtils.DEFAULT_INTERNAL_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY
import com.facebook.react.utils.PropertyUtils.INCLUDE_JITPACK_REPOSITORY_DEFAULT
import com.facebook.react.utils.PropertyUtils.INTERNAL_PUBLISHING_GROUP
import com.facebook.react.utils.PropertyUtils.INTERNAL_REACT_NATIVE_MAVEN_LOCAL_REPO
import com.facebook.react.utils.PropertyUtils.INTERNAL_USE_HERMES_NIGHTLY
import com.facebook.react.utils.PropertyUtils.INTERNAL_VERSION_NAME
import com.facebook.react.utils.PropertyUtils.SCOPED_INCLUDE_JITPACK_REPOSITORY
import java.io.File
import java.net.URI
import java.util.*
Expand Down Expand Up @@ -55,12 +58,14 @@ internal object DependencyUtils {
it.excludeGroup("com.facebook.react")
}
}
mavenRepoFromUrl("https://www.jitpack.io") { repo ->
repo.content {
// We don't want to fetch JSC or React from JitPack
it.excludeGroup("org.webkit")
it.excludeGroup("io.github.react-native-community")
it.excludeGroup("com.facebook.react")
if (shouldAddJitPack()) {
mavenRepoFromUrl("https://www.jitpack.io") { repo ->
repo.content { content ->
// We don't want to fetch JSC or React from JitPack
content.excludeGroup("org.webkit")
content.excludeGroup("io.github.react-native-community")
content.excludeGroup("com.facebook.react")
}
}
}
}
Expand Down Expand Up @@ -167,4 +172,13 @@ internal object DependencyUtils {
it.url = uri
action(it)
}

internal fun Project.shouldAddJitPack() =
when {
hasProperty(SCOPED_INCLUDE_JITPACK_REPOSITORY) ->
property(SCOPED_INCLUDE_JITPACK_REPOSITORY).toString().toBoolean()
hasProperty(INCLUDE_JITPACK_REPOSITORY) ->
property(INCLUDE_JITPACK_REPOSITORY).toString().toBoolean()
else -> INCLUDE_JITPACK_REPOSITORY_DEFAULT
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ object PropertyUtils {
const val REACT_NATIVE_ARCHITECTURES = "reactNativeArchitectures"
const val SCOPED_REACT_NATIVE_ARCHITECTURES = "react.nativeArchitectures"

/** Public property that allows to control whether the JitPack repository is included or not */
const val INCLUDE_JITPACK_REPOSITORY = "includeJitpackRepository"
const val SCOPED_INCLUDE_JITPACK_REPOSITORY = "react.includeJitpackRepository"

/** By default we include JitPack till React Native 0.80 where this is going to become false */
internal const val INCLUDE_JITPACK_REPOSITORY_DEFAULT = true

/**
* Internal Property that acts as a killswitch to configure the JDK version and align it for app
* and all the libraries.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.facebook.react.utils.DependencyUtils.getDependencySubstitutions
import com.facebook.react.utils.DependencyUtils.mavenRepoFromURI
import com.facebook.react.utils.DependencyUtils.mavenRepoFromUrl
import com.facebook.react.utils.DependencyUtils.readVersionAndGroupStrings
import com.facebook.react.utils.DependencyUtils.shouldAddJitPack
import java.net.URI
import org.assertj.core.api.Assertions.assertThat
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
Expand Down Expand Up @@ -98,6 +99,60 @@ class DependencyUtilsTest {
.isNotNull()
}

@Test
fun configureRepositories_withIncludeJitpackRepositoryFalse_doesNotContainJitPack() {
val repositoryURI = URI.create("https://www.jitpack.io")
var project = createProject()
project.extensions.extraProperties.set("includeJitpackRepository", "false")

configureRepositories(project, tempFolder.root)

assertThat(
project.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
.isNull()

// We test both with scoped and unscoped property
project = createProject()
project.extensions.extraProperties.set("react.includeJitpackRepository", "false")

configureRepositories(project, tempFolder.root)

assertThat(
project.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
.isNull()
}

@Test
fun configureRepositories_withincludeJitpackRepositoryTrue_containJitPack() {
val repositoryURI = URI.create("https://www.jitpack.io")
var project = createProject()
project.extensions.extraProperties.set("includeJitpackRepository", "true")

configureRepositories(project, tempFolder.root)

assertThat(
project.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
.isNotNull()

// We test both with scoped and unscoped property
project = createProject()
project.extensions.extraProperties.set("react.includeJitpackRepository", "true")

configureRepositories(project, tempFolder.root)

assertThat(
project.repositories.firstOrNull {
it is MavenArtifactRepository && it.url == repositoryURI
})
.isNotNull()
}

@Test
fun configureRepositories_withProjectPropertySet_hasHigherPriorityThanMavenCentral() {
val localMaven = tempFolder.newFolder("m2")
Expand Down Expand Up @@ -404,4 +459,24 @@ class DependencyUtilsTest {

assertThat(mavenRepo.url).isEqualTo(repoFolder.toURI())
}

@Test
fun shouldAddJitPack_withScopedProperty() {
val project = createProject(tempFolder.root)
project.extensions.extraProperties.set("react.includeJitpackRepository", "false")
assertThat(project.shouldAddJitPack()).isFalse()
}

@Test
fun shouldAddJitPack_withUnscopedProperty() {
val project = createProject(tempFolder.root)
project.extensions.extraProperties.set("react.includeJitpackRepository", "false")
assertThat(project.shouldAddJitPack()).isFalse()
}

@Test
fun shouldAddJitPack_defaultIsTrue() {
val project = createProject(tempFolder.root)
assertThat(project.shouldAddJitPack()).isTrue()
}
}

0 comments on commit a98528e

Please sign in to comment.