Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ dependencies {
testImplementation(libs.junit)
testImplementation(gradleTestKit())

// 루트 build.gradle.kts 의 bouncycastle 하한은 별도 빌드인 여기까지 미치지 않는다 — 같은 근거(#921).
// 루트 build.gradle.kts 의 보안 하한은 별도 빌드인 여기까지 미치지 않는다 — 같은 근거(#921·#981·
// #982·#985). AGP 9.2.1 이 이 클래스패스에도 같은 취약 버전을 끌어온다(netty 는 여기 없다).
constraints {
listOf("bcprov-jdk18on", "bcpkix-jdk18on", "bcutil-jdk18on").forEach { artifact ->
implementation("org.bouncycastle:$artifact:${libs.versions.bouncycastle.get()}") {
because("GHSA-574f-3g2m-x479 등 1.84 미만 취약 — #921")
}
}
implementation("org.apache.commons:commons-lang3:${libs.versions.commonsLang3.get()}") {
because("GHSA-j288-q9x7-2f5v — 3.18.0 미만 취약 — #981")
}
implementation("org.bitbucket.b_c:jose4j:${libs.versions.jose4j.get()}") {
because("GHSA-3677-xxcr-wjqv — 0.9.6 미만 취약 — #982")
}
implementation("org.jdom:jdom2:${libs.versions.jdom2.get()}") {
because("GHSA-2363-cqg2-863c — 2.0.6.1 미만 취약 — #985")
}
}
}

Expand Down
83 changes: 64 additions & 19 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension
import org.gradle.kotlin.dsl.configure

// AGP 9.2.1 이 buildscript classpath 로 끌어오는 bouncycastle 1.79 는 GHSA-574f-3g2m-x479(critical)
// 영향권이다(#921). 루트 classpath 는 plugins 블록 처리 시점에 리졸브가 끝나 아래 본문 훅으로는 늦고,
// buildscript 블록에서는 버전 카탈로그 accessor 를 쓸 수 없다 — libs.versions.toml 의 bouncycastle
// 과 같은 값을 리터럴로 유지할 것.
// AGP 9.2.1·Firebase App Distribution 5.3.0 이 buildscript classpath 로 끌어오는 전이 의존성 중
// 보안 권고 영향권인 것들의 하한(#921·#975~#985). 루트 classpath 는 plugins 블록 처리 시점에
// 리졸브가 끝나 아래 본문 훅으로는 늦고, buildscript 블록에서는 버전 카탈로그 accessor 를 쓸 수 없다
// — libs.versions.toml 의 같은 이름 버전과 값을 맞춰 유지할 것.
buildscript {
dependencies {
constraints {
Expand All @@ -13,7 +13,22 @@ buildscript {
because("GHSA-574f-3g2m-x479 등 1.84 미만 취약 — #921")
}
}
add("classpath", "org.apache.commons:commons-lang3:3.18.0") {
because("GHSA-j288-q9x7-2f5v — 3.18.0 미만 취약 — #981")
}
add("classpath", "org.bitbucket.b_c:jose4j:0.9.6") {
because("GHSA-3677-xxcr-wjqv — 0.9.6 미만 취약 — #982")
}
add("classpath", "org.jdom:jdom2:2.0.6.1") {
because("GHSA-2363-cqg2-863c — 2.0.6.1 미만 취약 — #985")
}
}
// netty 는 grpc-netty 가 끌어오는 모듈이 10개가 넘고 서로 같은 버전이어야 해 BOM 으로 정렬한다
// (GHSA-558v-64gr-wgg4 등 33건, #975~#980). 이 BOM 을 아래 본문의 allprojects 하한에 함께 걸면
// AGP 의 android-reverse-meta-data usage 가 platform 변형을 못 찾아 리졸브가 깨진다. netty 는
// 루트 buildscript classpath 에만 있고(전 프로젝트 실측 53건 전부 여기) 산출물·테스트 클래스패스에는
// 없으므로 여기서만 건다.
add("classpath", platform("io.netty:netty-bom:4.1.137.Final"))
}
}

Expand All @@ -32,30 +47,60 @@ plugins {
alias(libs.plugins.firebase.crashlytics) apply false
}

// 빌드·테스트 클래스패스의 bouncycastle 하한(#921). Robolectric 4.15.1(bcprov 1.80)·AGP 9.2.1(1.79)
// 전이 의존성이 GHSA-574f-3g2m-x479(critical) 영향권인데 상류 최신판도 1.84 미만이라 constraint 로
// 올린다. androidLintTool 처럼 AGP 가 뒤늦게 만드는 configuration 까지 잡도록 configureEach 로 걸고,
// require 시맨틱이라 상류가 1.84 이상을 선언하게 되면 그쪽이 이긴다. APK 산출물에는 bouncycastle 이
// 없다(releaseRuntimeClasspath 0건 실측). build-logic 은 별도 빌드라 build-logic/build.gradle.kts 가
// 같은 하한을 선언한다.
val bouncycastleArtifacts = listOf("bcprov-jdk18on", "bcpkix-jdk18on", "bcutil-jdk18on")
val bouncycastleFloor = libs.versions.bouncycastle.get()
// 빌드·테스트 클래스패스의 보안 하한(#921·#975~#985). 상류가 취약 버전을 물고 있고 상류 최신판도
// 아직 패치 버전 미만이라 constraint 로 올린다 — Robolectric 4.15.1(bcprov 1.80)·AGP 9.2.1(bcprov
// 1.79·commons-lang3 3.16.0·jose4j 0.9.5·jdom2 2.0.6)·Firebase App Distribution 5.3.0(netty
// 4.1.110.Final). androidLintTool 처럼 AGP 가 뒤늦게 만드는 configuration 까지 잡도록 configureEach
// 로 걸고, require 시맨틱이라 상류가 하한 이상을 선언하게 되면 그쪽이 이긴다. 여기 목록은 전부 빌드
// 도구 경유라 APK 산출물에는 없다(releaseRuntimeClasspath 0건 실측). build-logic 은 별도 빌드라
// build-logic/build.gradle.kts 가 같은 하한을 선언한다.
data class SecurityFloor(
val module: String,
val version: String,
val because: String,
)

val securityFloors =
listOf("bcprov-jdk18on", "bcpkix-jdk18on", "bcutil-jdk18on").map { artifact ->
SecurityFloor(
module = "org.bouncycastle:$artifact",
version = libs.versions.bouncycastle.get(),
because = "GHSA-574f-3g2m-x479 등 1.84 미만 취약 — #921",
)
} +
listOf(
SecurityFloor(
module = "org.apache.commons:commons-lang3",
version = libs.versions.commonsLang3.get(),
because = "GHSA-j288-q9x7-2f5v — 3.18.0 미만 취약 — #981",
),
SecurityFloor(
module = "org.bitbucket.b_c:jose4j",
version = libs.versions.jose4j.get(),
because = "GHSA-3677-xxcr-wjqv — 0.9.6 미만 취약 — #982",
),
SecurityFloor(
module = "org.jdom:jdom2",
version = libs.versions.jdom2.get(),
because = "GHSA-2363-cqg2-863c — 2.0.6.1 미만 취약 — #985",
),
)

fun Project.bouncycastleConstraintSet() =
bouncycastleArtifacts.map { artifact ->
dependencies.constraints.create("org.bouncycastle:$artifact:$bouncycastleFloor") {
because("GHSA-574f-3g2m-x479 등 1.84 미만 취약 — #921")
fun Project.securityFloorConstraintSet() =
securityFloors.map { floor ->
dependencies.constraints.create("${floor.module}:${floor.version}") {
because(floor.because)
}
}

allprojects {
// Gradle 9 는 declarable 이 아닌 configuration(compileClasspath 등)에 constraint 선언을 금지한다.
// 전용 declarable configuration 에 담아 모든 resolvable configuration 이 extend 하게 한다.
val floor =
configurations.create("bouncycastleConstraints") {
configurations.create("securityFloors") {
isCanBeResolved = false
isCanBeConsumed = false
bouncycastleConstraintSet().forEach { dependencyConstraints.add(it) }
securityFloorConstraintSet().forEach { dependencyConstraints.add(it) }
}
configurations.configureEach {
if (name != floor.name && isCanBeResolved) extendsFrom(floor)
Expand All @@ -65,7 +110,7 @@ allprojects {
// 직접 단다. 루트 자신의 classpath 는 최상단 buildscript 블록이 담당한다(여기 시점엔 리졸브 완료라 불가).
subprojects {
buildscript.configurations.named("classpath") {
bouncycastleConstraintSet().forEach { dependencyConstraints.add(it) }
securityFloorConstraintSet().forEach { dependencyConstraints.add(it) }
}
}

Expand Down
7 changes: 6 additions & 1 deletion feature/mindrecord/presentation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ dependencies {
implementation(projects.core.ui)
implementation(projects.core.model)
implementation(libs.coil.compose)
implementation(libs.compose.rich.editor)
// 쓰는 건 BasicRichTextEditor(foundation 계열)뿐인데, richeditor 가 딸려 보내는 Compose
// Multiplatform material3 1.11.0-alpha07 이 androidx material3 를 BOM 판 1.4.0 대신
// 1.5.0-alpha17(alpha)로 끌어올린다(#973). 쓰지 않는 material3 갈래를 끊어 BOM 을 정본으로 되돌린다.
implementation(libs.compose.rich.editor) {
exclude(group = "org.jetbrains.compose.material3", module = "material3")
}

testImplementation(libs.coroutines.test)

Expand Down
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ kover = "0.9.9"
# 빌드·테스트 클래스패스 전용 보안 하한 — GHSA-574f-3g2m-x479(critical) 등 3건이 1.84 에서 패치(#921).
# 루트 build.gradle.kts 의 buildscript 블록은 카탈로그 accessor 를 못 써 같은 값을 리터럴로 둔다.
bouncycastle = "1.84"
netty = "4.1.137.Final"
commonsLang3 = "3.18.0"
jose4j = "0.9.6"
jdom2 = "2.0.6.1"

[libraries]
androidx-biometric = { module = "androidx.biometric:biometric", version.ref = "biometric" }
Expand Down
9 changes: 9 additions & 0 deletions konsist/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,13 @@ kotlin {
dependencies {
testImplementation(libs.konsist)
testImplementation(libs.junit)

// konsist 0.17.3 이 kotlin-compiler-embeddable 2.0.21 경유로 coroutines 1.9.0 을 끌어와, 카탈로그
// 선언(1.11.0)과 어긋난 채 해석된다(#974). 이 모듈은 아키텍처 테스트 전용이라 산출물에 영향이 없지만
// 감사가 보는 testRuntimeClasspath 를 카탈로그 하나의 의도로 맞춘다.
constraints {
testImplementation(libs.coroutines.core) {
because("카탈로그 선언 버전으로 정렬 — konsist 전이 1.9.0 과 불일치(#974)")
}
}
}
Loading