diff --git a/docs/diagnostics/DisableSafeMode.md b/docs/diagnostics/DisableSafeMode.md new file mode 100644 index 00000000000..31a74a35a8e --- /dev/null +++ b/docs/diagnostics/DisableSafeMode.md @@ -0,0 +1,45 @@ +# Отключение безопасного режима (DisableSafeMode) + + +## Описание диагностики + +Помимо программного кода конфигурации, в прикладном решении может исполняться сторонний программный код, который может быть подключен с помощью внешних отчетов, внешних обработок, расширений конфигурации, внешних компонент или другими способами, например, с помощью стороннего (по отношению к конфигурации) программного кода, надежность которого разработчик гарантировать не может (далее – внешний код). При этом злоумышленник может предусмотреть в нем различные деструктивные действия (как в самом внешнем коде, так и опосредовано, через запуск внешних приложений, внешних компонент, COM-объектов), которые могут нанести вред компьютерам пользователей, серверным компьютерам, а также данным в программе. + +Перечисленные проблемы безопасности особенно критичны при работе конфигураций в модели сервиса. Например, получив доступ к сервису, вредоносный код может получить доступ сразу ко всем приложениям всех пользователей сервиса. + +Поэтому важно контролировать выполнение подобного внешнего кода в безопасном режиме, в исключительных случаях точечно разрешая выполнять код в небезопасном режиме после верификации кода. + +Правило диагностирует вызовы методов ` УстановитьБезопасныйРежим` и `УстановитьОтключениеБезопасногоРежима` в режиме отключения контроля безопасного режима +- вызов `УстановитьБезопасныйРежим (Истина)` игнорируется +- вызов `УстановитьОтключениеБезопасногоРежима(Ложь)` игнорируется + +## Примеры + +``` + УстановитьБезопасныйРежим (Ложь); // есть замечание + + Значение = Ложь; + УстановитьБезопасныйРежим (Значение); // есть замечание + + УстановитьБезопасныйРежим (Истина); // нет замечания + + УстановитьОтключениеБезопасногоРежима(Истина); // есть замечание + + Значение = Истина; + УстановитьОтключениеБезопасногоРежима(Значение); // есть замечание + + УстановитьОтключениеБезопасногоРежима(Ложь); // нет замечания +``` + +## Источники + + +- [Статья "Безопасный режим работы" - руководство разработчика 1С 8.3.22](https://its.1c.ru/db/v8322doc#bookmark:dev:TI000000186@ee788d9) +- [Стандарт "Ограничение на выполнение «внешнего» кода"](https://its.1c.ru/db/v8std/content/669/hdoc) +- [Стандарт "Безопасность прикладного программного интерфейса сервера"](https://its.1c.ru/db/v8std/content/678/hdoc) +- [Стандарт "Ограничения на использование Выполнить и Вычислить на сервере"](https://its.1c.ru/db/v8std#content:770:hdoc) +- [Стандарт Использование привилегированного режима](https://its.1c.ru/db/v8std/content/485/hdoc) diff --git a/docs/en/diagnostics/DisableSafeMode.md b/docs/en/diagnostics/DisableSafeMode.md new file mode 100644 index 00000000000..83a36958b30 --- /dev/null +++ b/docs/en/diagnostics/DisableSafeMode.md @@ -0,0 +1,16 @@ +# Disable safe mode (DisableSafeMode) + + +## Description + + +## Examples + + +## Sources + + diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic.java new file mode 100644 index 00000000000..7e2f529aee2 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic.java @@ -0,0 +1,83 @@ +/* + * 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.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.bsl.parser.BSLParser; +import com.github._1c_syntax.utils.CaseInsensitivePattern; + +import java.util.Optional; +import java.util.regex.Pattern; + +@DiagnosticMetadata( + type = DiagnosticType.VULNERABILITY, + severity = DiagnosticSeverity.MAJOR, + minutesToFix = 15, + tags = { + DiagnosticTag.SUSPICIOUS + }, + scope = DiagnosticScope.BSL +) +public class DisableSafeModeDiagnostic extends AbstractFindMethodDiagnostic { + private static final Pattern methodPattern = CaseInsensitivePattern.compile( + "УстановитьБезопасныйРежим|SetSafeMode|УстановитьОтключениеБезопасногоРежима|SetSafeModeDisabled"); + private static final Pattern safeModePattern = CaseInsensitivePattern.compile( + "УстановитьБезопасныйРежим|SetSafeMode"); + + public DisableSafeModeDiagnostic() { + super(methodPattern); + } + + @Override + protected boolean checkGlobalMethodCall(BSLParser.GlobalMethodCallContext ctx) { + final var result = super.checkGlobalMethodCall(ctx); + if (!result) { + return false; + } + final int enabledValue; + if(safeModePattern.matcher(ctx.methodName().getText()).matches()){ + enabledValue = BSLParser.TRUE; + } else { + enabledValue = BSLParser.FALSE; + } + return !enabledCall(ctx, enabledValue); + } + + private static boolean enabledCall(BSLParser.GlobalMethodCallContext ctx, int enabledValue) { + return Optional.of(ctx) + .map(BSLParser.GlobalMethodCallContext::doCall) + .map(BSLParser.DoCallContext::callParamList) + .map(BSLParser.CallParamListContext::callParam) + .filter(callParamContexts -> callParamContexts.size() == 1) + .map(callParamContexts -> callParamContexts.get(0)) + .map(BSLParser.CallParamContext::expression) + .map(BSLParser.ExpressionContext::member) + .map(memberContexts -> memberContexts.get(0)) + .map(BSLParser.MemberContext::constValue) + .filter(constValueContext -> constValueContext.getToken(enabledValue, 0) != null) + .isPresent(); + } +} 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 9310767b6eb..f3d9d2356cd 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 @@ -500,6 +500,16 @@ "title": "Deprecated ManagedForm type", "$id": "#/definitions/DeprecatedTypeManagedForm" }, + "DisableSafeMode": { + "description": "Disable safe mode", + "default": true, + "type": [ + "boolean", + "object" + ], + "title": "Disable safe mode", + "$id": "#/definitions/DisableSafeMode" + }, "DuplicateRegion": { "description": "Duplicate regions", "default": true, diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic_en.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic_en.properties new file mode 100644 index 00000000000..7270e9aafaa --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic_en.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Check the safe mode setting +diagnosticName=Disable safe mode diff --git a/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic_ru.properties b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic_ru.properties new file mode 100644 index 00000000000..186180f5a86 --- /dev/null +++ b/src/main/resources/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnostic_ru.properties @@ -0,0 +1,2 @@ +diagnosticMessage=Проверьте отключение безопасного режима +diagnosticName=Отключение безопасного режима diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnosticTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnosticTest.java new file mode 100644 index 00000000000..f54eb5579aa --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DisableSafeModeDiagnosticTest.java @@ -0,0 +1,49 @@ +/* + * 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 static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat; + +class DisableSafeModeDiagnosticTest extends AbstractDiagnosticTest { + DisableSafeModeDiagnosticTest() { + super(DisableSafeModeDiagnostic.class); + } + + @Test + void test() { + + List diagnostics = getDiagnostics(); + + assertThat(diagnostics, true) + .hasRange(2, 4, 29) + .hasRange(5, 4, 29) + .hasRange(9, 4, 41) + .hasRange(12, 4, 41) + .hasSize(4); + + } +} diff --git a/src/test/resources/diagnostics/DisableSafeModeDiagnostic.bsl b/src/test/resources/diagnostics/DisableSafeModeDiagnostic.bsl new file mode 100644 index 00000000000..e51acd2d709 --- /dev/null +++ b/src/test/resources/diagnostics/DisableSafeModeDiagnostic.bsl @@ -0,0 +1,16 @@ +&НаСервере +Процедура Метод() + УстановитьБезопасныйРежим(Ложь); // есть замечание + + Значение = Ложь; + УстановитьБезопасныйРежим(Значение); // есть замечание + + УстановитьБезопасныйРежим(Истина); // нет замечания + + УстановитьОтключениеБезопасногоРежима(Истина); // есть замечание + + Значение = Истина; + УстановитьОтключениеБезопасногоРежима(Значение); // есть замечание + + УстановитьОтключениеБезопасногоРежима(Ложь); // нет замечания +КонецПроцедуры