diff --git a/docs/diagnostics/ExternalAppStarting.md b/docs/diagnostics/ExternalAppStarting.md new file mode 100644 index 00000000000..711d1403a18 --- /dev/null +++ b/docs/diagnostics/ExternalAppStarting.md @@ -0,0 +1,78 @@ +# Запуск внешних приложений (ExternalAppStarting) + + +## Описание диагностики + +Для повышения качества и безопасности решения на 1С необходимо контролировать запуск внешних приложений из кода 1С. + +Данное правило распространяется на все способы запуска внешних программ, в том числе: +- КомандаСистемы +- ЗапуститьСистему +- ЗапуститьПриложение +- НачатьЗапускПриложения +- ЗапуститьПриложениеАсинх +- ПерейтиПоНавигационнойСсылке или ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку +- ФайловаяСистемаКлиент.ЗапуститьПрограмму (в клиентском коде) и ФайловаяСистема.ЗапуститьПрограмму (в серверном коде) +- ФайловаяСистемаКлиент.ОткрытьПроводник +- ФайловаяСистемаКлиент.ОткрытьФайл + +## Примеры + +```bsl +Процедура Метод() + СтрокаКоманды = ""; + ТекущийКаталог = ""; + ДождатьсяЗавершения = Истина; + ОписаниеОповещения = Неопределено; + ПараметрыКоманды = Новый Структура; + + КомандаСистемы(СтрокаКоманды, ТекущийКаталог); // есть замечание + ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог); // есть замечание + ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог, Истина); // есть замечание + + НачатьЗапускПриложения(ОписаниеОповещения, СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание + + ПерейтиПоНавигационнойСсылке(СтрокаКоманды); // есть замечание + ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(СтрокаКоманды); // есть замечание + ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(СтрокаКоманды, ОписаниеОповещения); // есть замечание + + ФайловаяСистемаКлиент.ЗапуститьПрограмму("ping 127.0.0.1 -n 5", ПараметрыКоманды); // есть замечание + ФайловаяСистемаКлиент.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыКоманды); // есть замечание + ФайловаяСистема.ЗапуститьПрограмму(СтрокаКоманды); // есть замечание + ФайловаяСистема.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыКоманды); // есть замечание + + ФайловаяСистемаКлиент.ОткрытьПроводник("C:\Users"); // есть замечание + ФайловаяСистемаКлиент.ОткрытьФайл(СтрокаКоманды); // есть замечание + ФайловаяСистемаКлиент.ОткрытьФайл(СтрокаКоманды, ОписаниеОповещения); // есть замечание + +КонецПроцедуры + +&НаКлиенте +Асинх Процедура Подключить() + СтрокаКоманды = ""; + ТекущийКаталог = ""; + ДождатьсяЗавершения = Истина; + + Ждать ЗапуститьПриложениеАсинх(СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание +КонецПроцедуры + +&НаКлиенте +Процедура ПроверкаЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, КодВозврата) + ДождатьсяЗавершения = Истина; + + ЗапуститьСистему(); // есть замечание + ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки); // есть замечание + ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, ДождатьсяЗавершения); // есть замечание + ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, ДождатьсяЗавершения, КодВозврата); // есть замечание +КонецПроцедуры +``` + +## Источники + + +- [стандарт Безопасность запуска приложений](https://its.1c.ru/db/v8std/content/774/hdoc) +- [стандарт Ограничение на выполнение «внешнего» кода](https://its.1c.ru/db/v8std/content/669/hdoc ) diff --git a/docs/en/diagnostics/ExternalAppStarting.md b/docs/en/diagnostics/ExternalAppStarting.md new file mode 100644 index 00000000000..061fa651c09 --- /dev/null +++ b/docs/en/diagnostics/ExternalAppStarting.md @@ -0,0 +1,16 @@ +# External applications starting (ExternalAppStarting) + + +## Description + + +## Examples + + +## Sources + + diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic.java new file mode 100644 index 00000000000..d0255aae186 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic.java @@ -0,0 +1,80 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2023 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ +package com.github._1c_syntax.bsl.languageserver.diagnostics; + +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticParameter; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticScope; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag; +import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType; +import com.github._1c_syntax.utils.CaseInsensitivePattern; + +import java.util.Map; +import java.util.regex.Pattern; + +@DiagnosticMetadata( + type = DiagnosticType.VULNERABILITY, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 5, + tags = { + DiagnosticTag.SUSPICIOUS + }, + scope = DiagnosticScope.BSL + +) +public class ExternalAppStartingDiagnostic extends AbstractFindMethodDiagnostic { + private static final String DEFAULT_PATTERN_STRING = + "КомандаСистемы|System|ЗапуститьСистему|RunSystem|ЗапуститьПриложение|RunApp" + + "|НачатьЗапускПриложения|BeginRunningApplication" + + "|ЗапуститьПриложениеАсинх|RunAppAsync|ЗапуститьПрограмму|ОткрытьПроводник|ОткрытьФайл"; + private static final String PATTERN_STRING_FOR_NAVI = + "|ПерейтиПоНавигационнойСсылке|GotoURL|ОткрытьНавигационнуюСсылку"; + private static final Pattern DEFAULT_PATTERN = CaseInsensitivePattern.compile(DEFAULT_PATTERN_STRING); + private static final boolean CHECK_GOTO_URL = false; + + @DiagnosticParameter( + type = Boolean.class, + defaultValue = "" + CHECK_GOTO_URL + ) + private boolean checkGotoUrl = CHECK_GOTO_URL; + + @DiagnosticParameter( + type = String.class, + defaultValue = DEFAULT_PATTERN_STRING + ) + private String userPatternString = DEFAULT_PATTERN_STRING; + + public ExternalAppStartingDiagnostic() { + super(DEFAULT_PATTERN); + } + + @Override + public void configure(Map configuration) { + super.configure(configuration); + var pattern = userPatternString; + if (checkGotoUrl){ + pattern += PATTERN_STRING_FOR_NAVI; + } + setMethodPattern(CaseInsensitivePattern.compile(pattern)); + } +} diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json index f9da3ac01a4..2dc96f59925 100644 --- a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/configuration/parameters-schema.json @@ -658,6 +658,30 @@ "title": "Ban export global module variables", "$id": "#/definitions/ExportVariables" }, + "ExternalAppStarting": { + "description": "External applications starting", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "External applications starting", + "properties": { + "checkGotoUrl": { + "description": "Check navigation links", + "default": false, + "type": "boolean", + "title": "Check navigation links" + }, + "userPatternString": { + "description": "User regex pattern", + "default": "\u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0421\u0438\u0441\u0442\u0435\u043c\u044b|System|\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0421\u0438\u0441\u0442\u0435\u043c\u0443|RunSystem|\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435|RunApp|\u041d\u0430\u0447\u0430\u0442\u044c\u0417\u0430\u043f\u0443\u0441\u043a\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f|BeginRunningApplication|\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0410\u0441\u0438\u043d\u0445|RunAppAsync|\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443|\u041e\u0442\u043a\u0440\u044b\u0442\u044c\u041f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a|\u041e\u0442\u043a\u0440\u044b\u0442\u044c\u0424\u0430\u0439\u043b", + "type": "string", + "title": "User regex pattern" + } + }, + "$id": "#/definitions/ExternalAppStarting" + }, "ExtraCommas": { "description": "Commas without a parameter at the end of a method call", "default": true, diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic_en.properties new file mode 100644 index 00000000000..117f5638521 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic_en.properties @@ -0,0 +1,4 @@ +diagnosticMessage=Check the launch of an external application +diagnosticName=External applications starting +checkGotoUrl=Check navigation links +userPatternString=User regex pattern diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic_ru.properties new file mode 100644 index 00000000000..45d566bc4d6 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnostic_ru.properties @@ -0,0 +1,4 @@ +diagnosticMessage=Проверьте запуск внешнего приложения +diagnosticName=Запуск внешних приложений +checkGotoUrl=Проверять переход по навигационным ссылкам +userPatternString=Пользовательский шаблон (регулярное выражение) diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnosticTest.java new file mode 100644 index 00000000000..0c281f9fc7d --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ExternalAppStartingDiagnosticTest.java @@ -0,0 +1,132 @@ +/* + * This file is a part of BSL Language Server. + * + * Copyright (c) 2018-2023 + * Alexey Sosnoviy , Nikita Fedkin and contributors + * + * SPDX-License-Identifier: LGPL-3.0-or-later + * + * BSL Language Server is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * BSL Language Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with BSL Language Server. + */ +package com.github._1c_syntax.bsl.languageserver.diagnostics; + +import org.eclipse.lsp4j.Diagnostic; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; + +import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; + +class ExternalAppStartingDiagnosticTest extends AbstractDiagnosticTest { + ExternalAppStartingDiagnosticTest() { + super(ExternalAppStartingDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics, true) + .hasRange(8, 4, 18) + .hasRange(9, 4, 23) + .hasRange(10, 4, 23) + .hasRange(12, 4, 26) + + .hasRange(18, 26, 44) + .hasRange(19, 26, 44) + .hasRange(20, 20, 38) + .hasRange(21, 20, 38) + .hasRange(23, 26, 42) + .hasRange(24, 26, 37) + .hasRange(25, 26, 37) + .hasRange(35, 10, 34) + + .hasRange(53, 4, 20) + .hasRange(54, 4, 20) + .hasRange(55, 4, 20) + .hasRange(56, 4, 20) + .hasSize(16); + } + + @Test + void testConfigure_checkGotoUrl() { + + Map configuration = diagnosticInstance.info.getDefaultConfiguration(); + configuration.put("checkGotoUrl", true); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics, true) + .hasRange(8, 4, 18) + .hasRange(9, 4, 23) + .hasRange(10, 4, 23) + .hasRange(12, 4, 26) + + .hasRange(14, 4, 32) + .hasRange(15, 26, 52) + .hasRange(16, 26, 52) + + .hasRange(18, 26, 44) + .hasRange(19, 26, 44) + .hasRange(20, 20, 38) + .hasRange(21, 20, 38) + .hasRange(23, 26, 42) + .hasRange(24, 26, 37) + .hasRange(25, 26, 37) + .hasRange(35, 10, 34) + + .hasRange(53, 4, 20) + .hasRange(54, 4, 20) + .hasRange(55, 4, 20) + .hasRange(56, 4, 20) + .hasSize(19); + } + + @Test + void testConfigure_userPatternString() { + + Map configuration = diagnosticInstance.info.getDefaultConfiguration(); + configuration.put("userPatternString", "КомандаСистемы"); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics, true) + .hasRange(8, 4, 18) + .hasSize(1); + } + + @Test + void testConfigure_userPatternString_checkGotoUrl() { + + Map configuration = diagnosticInstance.info.getDefaultConfiguration(); + configuration.put("checkGotoUrl", true); + configuration.put("userPatternString", "КомандаСистемы"); + diagnosticInstance.configure(configuration); + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics, true) + .hasRange(8, 4, 18) + + .hasRange(14, 4, 32) + .hasRange(15, 26, 52) + .hasRange(16, 26, 52) + + .hasSize(4); + } +} diff --git a/src/test/resources/diagnostics/ExternalAppStartingDiagnostic.bsl b/src/test/resources/diagnostics/ExternalAppStartingDiagnostic.bsl new file mode 100644 index 00000000000..80924867e83 --- /dev/null +++ b/src/test/resources/diagnostics/ExternalAppStartingDiagnostic.bsl @@ -0,0 +1,58 @@ + +Процедура Метод() + СтрокаКоманды = ""; + ТекущийКаталог = ""; + ДождатьсяЗавершения = Истина; + ОписаниеОповещения = Неопределено; + ПараметрыКоманды = Новый Структура; + + КомандаСистемы(СтрокаКоманды, ТекущийКаталог); // есть замечание + ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог); // есть замечание + ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог, Истина); // есть замечание + + НачатьЗапускПриложения(ОписаниеОповещения, СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание + + ПерейтиПоНавигационнойСсылке(СтрокаКоманды); // есть замечание + ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(СтрокаКоманды); // есть замечание + ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(СтрокаКоманды, ОписаниеОповещения); // есть замечание + + ФайловаяСистемаКлиент.ЗапуститьПрограмму("ping 127.0.0.1 -n 5", ПараметрыКоманды); // есть замечание + ФайловаяСистемаКлиент.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыКоманды); // есть замечание + ФайловаяСистема.ЗапуститьПрограмму(СтрокаКоманды); // есть замечание + ФайловаяСистема.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыКоманды); // есть замечание + + ФайловаяСистемаКлиент.ОткрытьПроводник("C:\Users"); // есть замечание + ФайловаяСистемаКлиент.ОткрытьФайл(СтрокаКоманды); // есть замечание + ФайловаяСистемаКлиент.ОткрытьФайл(СтрокаКоманды, ОписаниеОповещения); // есть замечание + +КонецПроцедуры + +&НаКлиенте +Асинх Процедура Подключить() + СтрокаКоманды = ""; + ТекущийКаталог = ""; + ДождатьсяЗавершения = Истина; + + Ждать ЗапуститьПриложениеАсинх(СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание +КонецПроцедуры + +&НаСервере +Процедура ПараметрНаИмяВнешнегоПриложения() + СтрокаКоманды = ""; + ТекущийКаталог = ""; + ДождатьсяЗавершения = Истина; + + МойОбщийМодуль.ЗапуститьВнешнееПриложение(СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание +КонецПроцедуры + +&НаКлиенте +Процедура ПроверкаЗапуститьСистему() + ДополнительныеПараметрыКоманднойСтроки = ""; + ДождатьсяЗавершения = Истина; + КодВозврата = Неопределено; + + ЗапуститьСистему(); // есть замечание + ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки); // есть замечание + ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, ДождатьсяЗавершения); // есть замечание + ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, ДождатьсяЗавершения, КодВозврата); // есть замечание +КонецПроцедуры