55
66import './media/extensionsViewlet.css' ;
77import { localize , localize2 } from '../../../../nls.js' ;
8- import { Delayer } from '../../../../base/common/async.js' ;
8+ import { timeout , Delayer , Promises } from '../../../../base/common/async.js' ;
99import { isCancellationError } from '../../../../base/common/errors.js' ;
1010import { createErrorWithActions } from '../../../../base/common/errorMessage.js' ;
1111import { IWorkbenchContribution } from '../../../common/contributions.js' ;
@@ -18,6 +18,7 @@ import { IInstantiationService, ServicesAccessor } from '../../../../platform/in
1818import { IExtensionService } from '../../../services/extensions/common/extensions.js' ;
1919import { IExtensionsWorkbenchService , IExtensionsViewPaneContainer , VIEWLET_ID , CloseExtensionDetailsOnViewChangeKey , INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID , WORKSPACE_RECOMMENDATIONS_VIEW_ID , AutoCheckUpdatesConfigurationKey , OUTDATED_EXTENSIONS_VIEW_ID , CONTEXT_HAS_GALLERY , extensionsSearchActionsMenu , AutoRestartConfigurationKey } from '../common/extensions.js' ;
2020import { InstallLocalExtensionsInRemoteAction , InstallRemoteExtensionsInLocalAction } from './extensionsActions.js' ;
21+ import { IExtensionManagementService } from '../../../../platform/extensionManagement/common/extensionManagement.js' ;
2122import { IWorkbenchExtensionEnablementService , IExtensionManagementServerService , IExtensionManagementServer } from '../../../services/extensionManagement/common/extensionManagement.js' ;
2223import { ExtensionsInput } from '../common/extensionsInput.js' ;
2324import { ExtensionsListView , EnabledExtensionsView , DisabledExtensionsView , RecommendedExtensionsView , WorkspaceRecommendedExtensionsView , ServerInstalledExtensionsView , DefaultRecommendedExtensionsView , UntrustedWorkspaceUnsupportedExtensionsView , UntrustedWorkspacePartiallySupportedExtensionsView , VirtualWorkspaceUnsupportedExtensionsView , VirtualWorkspacePartiallySupportedExtensionsView , DefaultPopularExtensionsView , DeprecatedExtensionsView , SearchMarketplaceExtensionsView , RecentlyUpdatedExtensionsView , OutdatedExtensionsView , StaticQueryExtensionsView , NONE_CATEGORY } from './extensionsViews.js' ;
@@ -33,20 +34,22 @@ import { IWorkspaceContextService } from '../../../../platform/workspace/common/
3334import { IContextKeyService , ContextKeyExpr , RawContextKey , IContextKey } from '../../../../platform/contextkey/common/contextkey.js' ;
3435import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js' ;
3536import { ILogService } from '../../../../platform/log/common/log.js' ;
36- import { INotificationService } from '../../../../platform/notification/common/notification.js' ;
37+ import { INotificationService , NotificationPriority } from '../../../../platform/notification/common/notification.js' ;
38+ import { IHostService } from '../../../services/host/browser/host.js' ;
3739import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js' ;
3840import { ViewPaneContainer } from '../../../browser/parts/views/viewPaneContainer.js' ;
3941import { ViewPane } from '../../../browser/parts/views/viewPane.js' ;
4042import { Query } from '../common/extensionQuery.js' ;
4143import { SuggestEnabledInput } from '../../codeEditor/browser/suggestEnabledInput/suggestEnabledInput.js' ;
4244import { alert } from '../../../../base/browser/ui/aria/aria.js' ;
43- import { EXTENSION_CATEGORIES } from '../../../../platform/extensions/common/extensions.js' ;
45+ import { EXTENSION_CATEGORIES , ExtensionType } from '../../../../platform/extensions/common/extensions.js' ;
4446import { Registry } from '../../../../platform/registry/common/platform.js' ;
4547import { ILabelService } from '../../../../platform/label/common/label.js' ;
4648import { MementoObject } from '../../../common/memento.js' ;
4749import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js' ;
4850import { IPreferencesService } from '../../../services/preferences/common/preferences.js' ;
4951import { SIDE_BAR_DRAG_AND_DROP_BACKGROUND } from '../../../common/theme.js' ;
52+ import { IWorkbenchEnvironmentService } from '../../../services/environment/common/environmentService.js' ;
5053import { VirtualWorkspaceContext , WorkbenchStateContext } from '../../../common/contextkeys.js' ;
5154import { ICommandService } from '../../../../platform/commands/common/commands.js' ;
5255import { installLocalInRemoteIcon } from './extensionsIcons.js' ;
@@ -56,6 +59,7 @@ import { IPaneCompositePartService } from '../../../services/panecomposite/brows
5659import { coalesce } from '../../../../base/common/arrays.js' ;
5760import { extractEditorsAndFilesDropData } from '../../../../platform/dnd/browser/dnd.js' ;
5861import { extname } from '../../../../base/common/resources.js' ;
62+ import { isMalicious } from '../../../../platform/extensionManagement/common/extensionManagementUtil.js' ;
5963import { ILocalizedString } from '../../../../platform/action/common/action.js' ;
6064import { registerNavigableContainer } from '../../../browser/actions/widgetNavigationCommands.js' ;
6165import { MenuWorkbenchToolBar } from '../../../../platform/actions/browser/toolbar.js' ;
@@ -963,3 +967,52 @@ export class StatusUpdater extends Disposable implements IWorkbenchContribution
963967 }
964968 }
965969}
970+
971+ export class MaliciousExtensionChecker implements IWorkbenchContribution {
972+
973+ constructor (
974+ @IExtensionManagementService private readonly extensionsManagementService : IExtensionManagementService ,
975+ @IHostService private readonly hostService : IHostService ,
976+ @ILogService private readonly logService : ILogService ,
977+ @INotificationService private readonly notificationService : INotificationService ,
978+ @IWorkbenchEnvironmentService private readonly environmentService : IWorkbenchEnvironmentService
979+ ) {
980+ if ( ! this . environmentService . disableExtensions ) {
981+ this . loopCheckForMaliciousExtensions ( ) ;
982+ }
983+ }
984+
985+ private loopCheckForMaliciousExtensions ( ) : void {
986+ this . checkForMaliciousExtensions ( )
987+ . then ( ( ) => timeout ( 1000 * 60 * 5 ) ) // every five minutes
988+ . then ( ( ) => this . loopCheckForMaliciousExtensions ( ) ) ;
989+ }
990+
991+ private checkForMaliciousExtensions ( ) : Promise < void > {
992+ return this . extensionsManagementService . getExtensionsControlManifest ( ) . then ( extensionsControlManifest => {
993+
994+ return this . extensionsManagementService . getInstalled ( ExtensionType . User ) . then ( installed => {
995+ const maliciousExtensions = installed . filter ( e => isMalicious ( e . identifier , extensionsControlManifest ) ) ;
996+
997+ if ( maliciousExtensions . length ) {
998+ return Promises . settled ( maliciousExtensions . map ( e => this . extensionsManagementService . uninstall ( e ) . then ( ( ) => {
999+ this . notificationService . prompt (
1000+ Severity . Warning ,
1001+ localize ( 'malicious warning' , "We have uninstalled '{0}' which was reported to be problematic." , e . identifier . id ) ,
1002+ [ {
1003+ label : localize ( 'reloadNow' , "Reload Now" ) ,
1004+ run : ( ) => this . hostService . reload ( )
1005+ } ] ,
1006+ {
1007+ sticky : true ,
1008+ priority : NotificationPriority . URGENT
1009+ }
1010+ ) ;
1011+ } ) ) ) ;
1012+ } else {
1013+ return Promise . resolve ( undefined ) ;
1014+ }
1015+ } ) . then ( ( ) => undefined ) ;
1016+ } , err => this . logService . error ( err ) ) ;
1017+ }
1018+ }
0 commit comments