Skip to content

Commit 041e12e

Browse files
authored
feat: add warnings for public repository downloads in multiple SDKs (#36476)
* feat: add warnings for public repository downloads in multiple SDKs add warnings when downloading dependencies from public repositories in Java, Go, and Python SDKs warn users about potential risks and suggest pre-staging dependencies or using private mirrors * logger * added cached_jar_path
1 parent 090b17b commit 041e12e

4 files changed

Lines changed: 84 additions & 2 deletions

File tree

sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"archive/zip"
2222
"fmt"
2323
"io"
24+
"log"
2425
"net/http"
2526
"os"
2627
"os/exec"
@@ -106,6 +107,15 @@ func getLocalJar(url string) (string, error) {
106107
return jarPath, nil
107108
}
108109

110+
// Issue warning when downloading from public repositories
111+
if strings.Contains(url, "repo.maven.apache.org") ||
112+
strings.Contains(url, "repo1.maven.org") ||
113+
strings.Contains(url, "maven.google.com") ||
114+
strings.Contains(url, "maven-central.storage-download.googleapis.com") {
115+
log.Printf("WARNING: Downloading JAR file from public repository: %s. "+
116+
"This may pose security risks or cause instability due to repository availability. Consider pre-staging dependencies or using private mirrors.", url)
117+
}
118+
109119
resp, err := http.Get(string(url))
110120
if err != nil {
111121
return "", err
@@ -334,6 +344,16 @@ func (j *jarGetter) getJar(gradleTarget, version string) (string, error) {
334344
gradleTarget)
335345
}
336346

347+
// Issue warning when downloading from public repositories
348+
fullURLStr := string(fullURL)
349+
if strings.Contains(fullURLStr, "repo.maven.apache.org") ||
350+
strings.Contains(fullURLStr, "repo1.maven.org") ||
351+
strings.Contains(fullURLStr, "maven.google.com") ||
352+
strings.Contains(fullURLStr, "maven-central.storage-download.googleapis.com") {
353+
log.Printf("WARNING: Downloading JAR file from public repository: %s. "+
354+
"This may pose security risks or cause instability due to repository availability. Consider pre-staging dependencies or using private mirrors.", fullURLStr)
355+
}
356+
337357
resp, err := http.Get(string(fullURL))
338358
if err != nil {
339359
return "", err

sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/JavaUdfLoader.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,20 @@ public AggregateFn loadAggregateFunction(List<String> functionPath, String jarPa
125125
*/
126126
private File downloadFile(String inputPath, String mimeType) throws IOException {
127127
Preconditions.checkArgument(!inputPath.isEmpty(), "Path cannot be empty.");
128+
129+
// Issue warning when downloading from public repositories
130+
if (inputPath.startsWith("http://") || inputPath.startsWith("https://")) {
131+
if (inputPath.contains("repo.maven.apache.org")
132+
|| inputPath.contains("repo1.maven.org")
133+
|| inputPath.contains("maven.google.com")
134+
|| inputPath.contains("maven-central.storage-download.googleapis.com")) {
135+
LOG.warn(
136+
"WARNING: Downloading JAR file from public repository: {}. "
137+
+ "This may pose security risks or cause instability due to repository availability. Consider pre-staging dependencies or using private mirrors.",
138+
inputPath);
139+
}
140+
}
141+
128142
ResourceId inputResource = FileSystems.matchNewResource(inputPath, false /* is directory */);
129143
try (ReadableByteChannel inputChannel = FileSystems.open(inputResource)) {
130144
File outputFile = File.createTempFile("sql-udf-", inputResource.getFilename());

sdks/python/apache_beam/utils/subprocess_server.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,10 @@ def _really_stop_process(process_and_endpoint):
280280
class JavaJarServer(SubprocessServer):
281281

282282
MAVEN_CENTRAL_REPOSITORY = 'https://repo.maven.apache.org/maven2'
283-
MAVEN_STAGING_REPOSITORY = 'https://repository.apache.org/content/groups/staging' # pylint: disable=line-too-long
284-
GOOGLE_MAVEN_MIRROR = 'https://maven-central.storage-download.googleapis.com/maven2' # pylint: disable=line-too-long
283+
MAVEN_STAGING_REPOSITORY = (
284+
'https://repository.apache.org/content/groups/staging')
285+
GOOGLE_MAVEN_MIRROR = (
286+
'https://maven-central.storage-download.googleapis.com/maven2')
285287
BEAM_GROUP_ID = 'org.apache.beam'
286288
JAR_CACHE = os.path.expanduser("~/.apache_beam/cache/jars")
287289

@@ -431,6 +433,26 @@ def _download_jar_to_cache(
431433
cached_jar_path (str): The local path where the jar should be cached.
432434
user_agent (str): The user agent to use when downloading.
433435
"""
436+
# Issue warning when downloading from public repositories
437+
public_repos = [
438+
cls.MAVEN_CENTRAL_REPOSITORY,
439+
cls.GOOGLE_MAVEN_MIRROR,
440+
]
441+
442+
if any(download_url.startswith(repo) for repo in public_repos):
443+
_LOGGER.warning(
444+
" WARNING: Apache Beam is downloading dependencies from a "
445+
"public repository at runtime.\n"
446+
" This may pose security risks or cause instability due to "
447+
"repository availability.\n"
448+
" URL: %s\n"
449+
" Destination: %s\n"
450+
" Consider pre-staging dependencies or using a private repository "
451+
"mirror.\n"
452+
" For more information, see: "
453+
"https://beam.apache.org/documentation/sdks/python-dependencies/",
454+
download_url,
455+
cached_jar_path)
434456
try:
435457
url_read = FileSystems.open(download_url)
436458
except ValueError:

sdks/python/apache_beam/yaml/yaml_provider.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
from apache_beam.yaml import yaml_utils
6969
from apache_beam.yaml.yaml_errors import maybe_with_exception_handling_transform_fn
7070

71+
_LOGGER = logging.getLogger(__name__)
72+
7173

7274
class NotAvailableWithReason:
7375
"""A False value that provides additional content.
@@ -1322,6 +1324,18 @@ def _create_venv_from_scratch(
13221324
venv_python = os.path.join(venv, 'bin', 'python')
13231325
venv_pip = os.path.join(venv, 'bin', 'pip')
13241326
subprocess.run([venv_python, '-m', 'ensurepip'], check=True)
1327+
# Issue warning when installing packages from PyPI
1328+
_LOGGER.warning(
1329+
" WARNING: Apache Beam is installing Python packages "
1330+
"from PyPI at runtime.\n"
1331+
" This may pose security risks or cause instability due to "
1332+
"repository availability.\n"
1333+
" Packages: %s\n"
1334+
" Consider pre-staging dependencies or using a private "
1335+
"repository mirror.\n"
1336+
" For more information, see: "
1337+
"https://beam.apache.org/documentation/sdks/python-dependencies/",
1338+
', '.join(packages))
13251339
subprocess.run([venv_pip, 'install'] + packages, check=True)
13261340
with open(venv + '-requirements.txt', 'w') as fout:
13271341
fout.write('\n'.join(packages))
@@ -1342,6 +1356,18 @@ def _create_venv_from_clone(
13421356
clonable_venv = cls._create_venv_to_clone(base_python)
13431357
clonevirtualenv.clone_virtualenv(clonable_venv, venv)
13441358
venv_pip = os.path.join(venv, 'bin', 'pip')
1359+
# Issue warning when installing packages from PyPI
1360+
_LOGGER.warning(
1361+
" WARNING: Apache Beam is installing Python packages "
1362+
"from PyPI at runtime.\n"
1363+
" This may pose security risks or cause instability due to "
1364+
"repository availability.\n"
1365+
" Packages: %s\n"
1366+
" Consider pre-staging dependencies or using a private "
1367+
"repository mirror.\n"
1368+
" For more information, see: "
1369+
"https://beam.apache.org/documentation/sdks/python-dependencies/",
1370+
', '.join(packages))
13451371
subprocess.run([venv_pip, 'install'] + packages, check=True)
13461372
with open(venv + '-requirements.txt', 'w') as fout:
13471373
fout.write('\n'.join(packages))

0 commit comments

Comments
 (0)