OPENIDE #24 Restrict IDE access to untrusted sources

This commit is contained in:
Nikita Iarychenko
2024-11-15 10:34:02 +00:00
parent db0186db76
commit bc289aaf9e
20 changed files with 132 additions and 75 deletions

View File

@@ -1,7 +1,7 @@
<idea-plugin package="com.intellij.idea.customization.base">
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceInterface="com.intellij.platform.ide.customization.ExternalProductResourceUrls"
serviceImplementation="com.intellij.idea.customization.base.IntelliJIdeaExternalResourceUrls"
serviceImplementation="com.intellij.idea.customization.base.OpenIdeExternalResourceUrls"
overrides="true"/>
</extensions>
</idea-plugin>

View File

@@ -0,0 +1,31 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.idea.customization.base
import com.intellij.openapi.util.BuildNumber
import com.intellij.platform.ide.customization.ExternalProductResourceUrls
import com.intellij.util.Url
import com.intellij.util.Urls
// TODO [OpenIDE]: replaces urls
class OpenIdeExternalResourceUrls : ExternalProductResourceUrls {
override val helpPageUrl: ((topicId: String) -> Url)? = null
override val gettingStartedPageUrl = null
override val youTubeChannelUrl = null
override val updateMetadataUrl = Urls.newFromEncoded("https://www.openide.com")
override fun computePatchUrl(from: BuildNumber, to: BuildNumber): Url = Urls.newFromEncoded("https://www.openide.com")
override val bugReportUrl: ((String) -> Url)? = null
override val technicalSupportUrl: ((description: String) -> Url) ? = null
override val feedbackReporter = null
override val downloadPageUrl = null
override val whatIsNewPageUrl = null
}

View File

@@ -33,7 +33,7 @@ import java.util.stream.Collectors;
@InternalIgnoreDependencyViolation
public final class IntellijTestDiscoveryProducer implements TestDiscoveryProducer {
private static final String INTELLIJ_TEST_DISCOVERY_HOST = "https://intellij-test-discovery.labs.intellij.net";
private static final String INTELLIJ_TEST_DISCOVERY_HOST = "";
private static final NotNullLazyValue<ObjectReader> JSON_READER = NotNullLazyValue.createValue(() -> new ObjectMapper().readerFor(TestsSearchResult.class));

View File

@@ -1106,7 +1106,7 @@
<codeInsight.externalLibraryResolver implementation="com.intellij.codeInspection.concurrencyAnnotations.JCiPExternalLibraryResolver"/>
<codeInsight.externalLibraryResolver
implementation="com.intellij.codeInsight.daemon.impl.quickfix.JetBrainsAnnotationsExternalLibraryResolver"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.jarFinder.FindJarQuickFixProvider"/>
<!--<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.jarFinder.FindJarQuickFixProvider"/>-->
<generation.toStringClassFilter implementation="org.jetbrains.generate.tostring.GenerateToStringInterfaceFilter" order="last"/>
<gotoDeclarationHandler implementation="com.intellij.codeInsight.navigation.actions.GotoVarTypeHandler"/>
<annotator language="SPI" implementationClass="com.intellij.spi.SPIAnnotator"/>
@@ -2823,7 +2823,7 @@
<statistics.counterUsagesCollector implementationClass="com.intellij.ide.projectWizard.JdkComboBoxCollector"/>
<registryKey key="starters.dependency.update.host"
defaultValue="https://frameworks.jetbrains.com"
defaultValue=""
description="The host is used to download dependency config updates for framework starters"/>
<dependencyCollector kind="java" implementation="com.intellij.ide.JavaDependencyCollector"/>

View File

@@ -106,17 +106,17 @@ fun submitFeedback(feedbackData: FeedbackRequestDataHolder,
onDone: () -> Unit,
onError: () -> Unit,
feedbackRequestType: FeedbackRequestType = FeedbackRequestType.TEST_REQUEST) {
ApplicationManager.getApplication().executeOnPooledThread {
val feedbackUrl = when (feedbackRequestType) {
FeedbackRequestType.NO_REQUEST -> return@executeOnPooledThread
FeedbackRequestType.TEST_REQUEST -> TEST_FEEDBACK_URL
FeedbackRequestType.PRODUCTION_REQUEST -> PRODUCTION_FEEDBACK_URL
}
val regionalFeedbackUrl = RegionUrlMapper.tryMapUrlBlocking(feedbackUrl)
LOG.info("Feedback sent to $regionalFeedbackUrl")
sendFeedback(regionalFeedbackUrl, feedbackData, onDone, onError)
}
//ApplicationManager.getApplication().executeOnPooledThread {
// val feedbackUrl = when (feedbackRequestType) {
// FeedbackRequestType.NO_REQUEST -> return@executeOnPooledThread
// FeedbackRequestType.TEST_REQUEST -> TEST_FEEDBACK_URL
// FeedbackRequestType.PRODUCTION_REQUEST -> PRODUCTION_FEEDBACK_URL
// }
//
// val regionalFeedbackUrl = RegionUrlMapper.tryMapUrlBlocking(feedbackUrl)
// LOG.info("Feedback sent to $regionalFeedbackUrl")
// sendFeedback(regionalFeedbackUrl, feedbackData, onDone, onError)
//}
}
private fun sendFeedback(feedbackUrl: String,

View File

@@ -3,8 +3,8 @@ package com.intellij.facet.frameworks;
public final class LibrariesDownloadConnectionService extends SettingsConnectionService {
private static final String SETTINGS_URL = "https://www.jetbrains.com/idea/download-assistant.xml";
private static final String SERVICE_URL = "https://frameworks.jetbrains.com";
private static final String SETTINGS_URL = null;
private static final String SERVICE_URL = null;
private static final LibrariesDownloadConnectionService ourInstance = new LibrariesDownloadConnectionService();

View File

@@ -549,6 +549,12 @@ public final class HttpRequests {
request.myUrl = "https:" + request.myUrl.substring(5);
}
if (!WhiteListUrls.isAvailableUrl(request.myUrl)) {
LOG.info("Not available url: " + request.myUrl);
URL url = new URL(request.myUrl);
return new StubUrlConnection(url);
}
for (int i = 0; i < builder.myRedirectLimit; i++) {
final String url = request.myUrl;

View File

@@ -0,0 +1,34 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.util.io
import java.net.URL
import java.net.URLConnection
object WhiteListUrls {
private val urls = listOf(
"https://github.com",
"https://search.maven.org",
"https://repo.jfrog.org",
"https://oss.sonatype.org",
"https://repository.jboss.org",
"https://repo.maven.apache.org",
"https://plugins.gradle.org/plugin/org.jetbrains.intellij",
"https://api.github.com/repos",
"https://pypi.python.org",
"http://localhost",
"https://services.gradle.org",
"https://plugins.jetbrains.com", // TODO [OpenIDE]: replace url
"https://downloads.marketplace.jetbrains.com/files", // TODO [OpenIDE]: replace url
"https://repo1.maven.org/maven2/net/sourceforge/plantuml/plantuml/1.2023.10/plantuml-1.2023.10.jar",
)
@JvmStatic
fun isAvailableUrl(url: String): Boolean {
return urls.any { url.startsWith(it, true) }
}
}
class StubUrlConnection(url: URL): URLConnection(url) {
override fun connect() {
}
}

View File

@@ -476,7 +476,7 @@ class JdkListDownloader : JdkListDownloaderBase() {
return registry
}
}
return "https://download.jetbrains.com/jdk/feed/v1/jdks.json.xz"
return "" // TODO [OpenIDE]: replace url
}
}

View File

@@ -40,7 +40,8 @@ private class RuntimeChooserJbrListDownloader : JdkListDownloaderBase() {
val majorVersion = runCatching { Registry.get("runtime.chooser.pretend.major").asInteger() }.getOrNull()
?: ApplicationInfo.getInstance().build.components.firstOrNull()
return "https://download.jetbrains.com/jdk/feed/v1/jbr-choose-runtime-${majorVersion}.json.xz"
return ""; // TODO [OpenIDE]: replace url
//return "https://download.jetbrains.com/jdk/feed/v1/jbr-choose-runtime-${majorVersion}.json.xz"
}
}

View File

@@ -35,7 +35,7 @@ import java.awt.Component
* Third-party plugins need to provide their own implementations of [ErrorReportSubmitter].
*/
@InternalIgnoreDependencyViolation
open class ITNReporter(private val postUrl: String = "https://ea-report.jetbrains.com/trackerRpc/idea/createScr") : ErrorReportSubmitter() {
open class ITNReporter(private val postUrl: String = "") : ErrorReportSubmitter() {
private val INTERVAL = 10 * 60 * 1000L // an interval between exceptions to form a chain, ms
@Volatile private var previousReport: Pair<Long, Int>? = null // (timestamp, threadID) of last reported exception

View File

@@ -31,11 +31,6 @@ public final class RegionUrlMapper {
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.RegionUrlMapper");
private static final int CACHE_DATA_EXPIRATION_MIN = 2;
private static final String CONFIG_URL_DEFAULT = "https://www.jetbrains.com/config/JetBrainsResourceMapping.json";
private static final Map<Region, String> CONFIG_URL_TABLE = Map.of(
// augment the table with other regions if needed
Region.CHINA, "https://www.jetbrains.com.cn/config/JetBrainsResourceMapping.json"
);
private static final Map<Region, String> OVERRIDE_CONFIG_URL_TABLE = new HashMap<>(); // for testing
static {
@@ -163,8 +158,7 @@ public final class RegionUrlMapper {
}
private static @NotNull String getConfigUrl(@NotNull Region reg) {
String overridden = OVERRIDE_CONFIG_URL_TABLE.get(reg);
return overridden != null ? overridden : CONFIG_URL_TABLE.getOrDefault(reg, CONFIG_URL_DEFAULT);
return "";
}
/**

View File

@@ -23,7 +23,7 @@ private val gson by lazy { Gson() }
@ApiStatus.Internal
object StatsSender {
private const val infoUrl = "https://www.jetbrains.com/config/features-service-status.json"
private const val infoUrl = ""
private val LOG = Logger.getInstance(StatsSender::class.java)
private fun requestServerUrl(): StatsServerInfo? {

View File

@@ -16,7 +16,8 @@ import static com.intellij.internal.statistic.eventLog.StatisticsEventLogProvide
public class EventLogInternalApplicationInfo implements EventLogApplicationInfo {
private static final DataCollectorDebugLogger LOG =
new InternalDataCollectorDebugLogger(Logger.getInstance(EventLogStatisticsService.class));
public static final String EVENT_LOG_SETTINGS_URL_TEMPLATE = "https://resources.jetbrains.com/storage/fus/config/v4/%s/%s.json";
// TODO [OpenIDE]: replace url
public static final String EVENT_LOG_SETTINGS_URL_TEMPLATE = "";
private final boolean myIsTestSendEndpoint;
private final boolean myIsTestConfig;

View File

@@ -844,8 +844,8 @@
restartRequired="true"
description="Amount of time in minutes to check new Git version after IDE inactivity.\n
-1 to disable check."/>
<postStartupActivity os="windows" implementation="git4idea.config.GitNewVersionChecker$Starter"/>
<settingsEntryPointActionProvider os="windows" implementation="git4idea.config.GitVersionUpdateSettingsEntryProvider"/>
<!--<postStartupActivity os="windows" implementation="git4idea.config.GitNewVersionChecker$Starter"/>-->
<!--<settingsEntryPointActionProvider os="windows" implementation="git4idea.config.GitVersionUpdateSettingsEntryProvider"/>-->
<history.activityPresentationProvider implementation="git4idea.GitActivityPresentationProvider"/>

View File

@@ -190,7 +190,7 @@
<registryKey key="gradle.phased.sync.enabled" defaultValue="true"
description="Enable the phased Gradle sync execution"/>
<registryKey defaultValue="https://download.jetbrains.com/resources/intellij/plugins/gradle/v1/compatibility.json"
<registryKey defaultValue=""
description="URL to get updates for gradle/jvm compatibility matrix" key="gradle.compatibility.config.url"/>
<registryKey defaultValue="86400"
description="Time to check in seconds for gradle compatibility update. Set to 0 to disable updates"

View File

@@ -33,18 +33,7 @@ internal object LangDownloader {
}
private fun runDownload(language: Lang, project: Project?): Path? {
try {
val presentableName = msg("grazie.settings.proofreading.languages.download.name", language.nativeName)
return ProgressManager.getInstance().runProcessWithProgressSynchronously<Path, Exception>(
{ performDownload(language, presentableName) },
presentableName,
false,
project
)
} catch (exception: Throwable) {
thisLogger().warn(exception)
return promptToSelectLanguageBundleManually(project, language)
}
return promptToSelectLanguageBundleManually(project, language)
}
@Throws(IllegalStateException::class)

View File

@@ -1323,7 +1323,7 @@
implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
<debugger.nodeRenderer implementation="org.jetbrains.plugins.groovy.debugger.GroovyRefRenderer"/>
<codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
<!--<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>-->
<lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
implementationClass="org.jetbrains.plugins.groovy.refactoring.classMembers.GroovyClassMembersRefactoringSupport"/>
<refactoring.pullUpHelperFactory language="Groovy"

View File

@@ -110,35 +110,36 @@ public final class SceneBuilderEditor extends UserDataHolderBase implements File
e instanceof NoClassDefFoundError &&
!SceneBuilderUtil.getSceneBuilder11Path().toFile().isFile()) {
myErrorNotification.setText(JavaFXBundle.message("javafx.scene.builder.editor.failed.to.open.file.error"));
myErrorNotification.createActionLabel(
JavaFXBundle.message("javafx.scene.builder.editor.download.scene.builder.kit"),
() -> {
DownloadableFileService service = DownloadableFileService.getInstance();
var description = service.createFileDescription("https://cache-redirector.jetbrains.com/" +
"intellij-dependencies/org/jetbrains/intellij/deps/scenebuilderkit/" +
SceneBuilderUtil.SCENE_BUILDER_VERSION + "/" + SceneBuilderUtil.SCENE_BUILDER_KIT_FULL_NAME, SceneBuilderUtil.SCENE_BUILDER_KIT_FULL_NAME);
FileDownloader downloader = service.createDownloader(Collections.singletonList(description), "Scene Builder Kit");
try {
Path tempDir = Files.createTempDirectory("");
final var list = downloader.downloadWithProgress(tempDir.toString(), myProject, myErrorPanel);
if (list == null || list.isEmpty()) {
myErrorNotification.clear();
myErrorNotification.setText(JavaFXBundle.message("javafx.scene.builder.editor.failed.to.download.kit.error"));
return;
}
FileUtil.copy(VfsUtilCore.virtualToIoFile(list.get(0).first), SceneBuilderUtil.getSceneBuilder11Path().toFile());
FileUtil.delete(tempDir.toFile());
SceneBuilderUtil.updateLoader();
updateState();
}
catch (IOException e2) {
LOG.warn("Can't download SceneBuilderKit", e2);
}
}
);
// TODO [OpenIDE]: https://git.haulmont.com/platform/open-ide/idea/-/issues/29
//myErrorNotification.createActionLabel(
// JavaFXBundle.message("javafx.scene.builder.editor.download.scene.builder.kit"),
// () -> {
// DownloadableFileService service = DownloadableFileService.getInstance();
// var description = service.createFileDescription("https://cache-redirector.jetbrains.com/" +
// "intellij-dependencies/org/jetbrains/intellij/deps/scenebuilderkit/" +
// SceneBuilderUtil.SCENE_BUILDER_VERSION + "/" + SceneBuilderUtil.SCENE_BUILDER_KIT_FULL_NAME, SceneBuilderUtil.SCENE_BUILDER_KIT_FULL_NAME);
// FileDownloader downloader = service.createDownloader(Collections.singletonList(description), "Scene Builder Kit");
// try {
// Path tempDir = Files.createTempDirectory("");
//
// final var list = downloader.downloadWithProgress(tempDir.toString(), myProject, myErrorPanel);
// if (list == null || list.isEmpty()) {
// myErrorNotification.clear();
// myErrorNotification.setText(JavaFXBundle.message("javafx.scene.builder.editor.failed.to.download.kit.error"));
// return;
// }
//
// FileUtil.copy(VfsUtilCore.virtualToIoFile(list.get(0).first), SceneBuilderUtil.getSceneBuilder11Path().toFile());
// FileUtil.delete(tempDir.toFile());
//
// SceneBuilderUtil.updateLoader();
// updateState();
// }
// catch (IOException e2) {
// LOG.warn("Can't download SceneBuilderKit", e2);
// }
// }
//);
myLayout.show(myPanel, ERROR_CARD);
return;
}

View File

@@ -320,7 +320,7 @@
defaultValue="600000"
description="Interval in milliseconds defining how often Markdown plugin caches (e.g. PlantUML diagrams) should be cleared"/>
<registryKey key="markdown.plantuml.download.link"
defaultValue="https://download.jetbrains.com/grazie/markdown/extensions/plantuml/plantuml-1.2023.10-15.jar"
defaultValue="https://repo1.maven.org/maven2/net/sourceforge/plantuml/plantuml/1.2023.10/plantuml-1.2023.10.jar"
description="Link which Markdown plugin will use to download PlantUML JAR"/>
<registryKey key="markdown.open.link.in.external.browser"
defaultValue="true"