Skip to content

Commit

Permalink
Merge pull request #3115 from artbear/ExternalAppStarting
Browse files Browse the repository at this point in the history
Правило "Запуск внешних приложений" - ExternalAppStarting
  • Loading branch information
theshadowco authored Dec 26, 2023
2 parents 33eb49d + f378e30 commit 29390f1
Show file tree
Hide file tree
Showing 8 changed files with 396 additions and 0 deletions.
78 changes: 78 additions & 0 deletions docs/diagnostics/ExternalAppStarting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Запуск внешних приложений (ExternalAppStarting)

<!-- Блоки выше заполняются автоматически, не трогать -->
## Описание диагностики
<!-- Описание диагностики заполняется вручную. Необходимо понятным языком описать смысл и схему работу -->
Для повышения качества и безопасности решения на 1С необходимо контролировать запуск внешних приложений из кода 1С.

Данное правило распространяется на все способы запуска внешних программ, в том числе:
- КомандаСистемы
- ЗапуститьСистему
- ЗапуститьПриложение
- НачатьЗапускПриложения
- ЗапуститьПриложениеАсинх
- ПерейтиПоНавигационнойСсылке или ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку
- ФайловаяСистемаКлиент.ЗапуститьПрограмму (в клиентском коде) и ФайловаяСистема.ЗапуститьПрограмму (в серверном коде)
- ФайловаяСистемаКлиент.ОткрытьПроводник
- ФайловаяСистемаКлиент.ОткрытьФайл

## Примеры
<!-- В данном разделе приводятся примеры, на которые диагностика срабатывает, а также можно привести пример, как можно исправить ситуацию -->
```bsl
Процедура Метод()
СтрокаКоманды = "";
ТекущийКаталог = "";
ДождатьсяЗавершения = Истина;
ОписаниеОповещения = Неопределено;
ПараметрыКоманды = Новый Структура;
КомандаСистемы(СтрокаКоманды, ТекущийКаталог); // есть замечание
ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог); // есть замечание
ЗапуститьПриложение(СтрокаКоманды, ТекущийКаталог, Истина); // есть замечание
НачатьЗапускПриложения(ОписаниеОповещения, СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание
ПерейтиПоНавигационнойСсылке(СтрокаКоманды); // есть замечание
ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(СтрокаКоманды); // есть замечание
ФайловаяСистемаКлиент.ОткрытьНавигационнуюСсылку(СтрокаКоманды, ОписаниеОповещения); // есть замечание
ФайловаяСистемаКлиент.ЗапуститьПрограмму("ping 127.0.0.1 -n 5", ПараметрыКоманды); // есть замечание
ФайловаяСистемаКлиент.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыКоманды); // есть замечание
ФайловаяСистема.ЗапуститьПрограмму(СтрокаКоманды); // есть замечание
ФайловаяСистема.ЗапуститьПрограмму(СтрокаКоманды, ПараметрыКоманды); // есть замечание
ФайловаяСистемаКлиент.ОткрытьПроводник("C:\Users"); // есть замечание
ФайловаяСистемаКлиент.ОткрытьФайл(СтрокаКоманды); // есть замечание
ФайловаяСистемаКлиент.ОткрытьФайл(СтрокаКоманды, ОписаниеОповещения); // есть замечание
КонецПроцедуры
&НаКлиенте
Асинх Процедура Подключить()
СтрокаКоманды = "";
ТекущийКаталог = "";
ДождатьсяЗавершения = Истина;
Ждать ЗапуститьПриложениеАсинх(СтрокаКоманды, ТекущийКаталог, ДождатьсяЗавершения); // есть замечание
КонецПроцедуры
&НаКлиенте
Процедура ПроверкаЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, КодВозврата)
ДождатьсяЗавершения = Истина;
ЗапуститьСистему(); // есть замечание
ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки); // есть замечание
ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, ДождатьсяЗавершения); // есть замечание
ЗапуститьСистему(ДополнительныеПараметрыКоманднойСтроки, ДождатьсяЗавершения, КодВозврата); // есть замечание
КонецПроцедуры
```

## Источники
<!-- Необходимо указывать ссылки на все источники, из которых почерпнута информация для создания диагностики -->
<!-- Примеры источников
* Источник: [Стандарт: Тексты модулей](https://its.1c.ru/db/v8std#content:456:hdoc)
* Полезная информация: [Отказ от использования модальных окон](https://its.1c.ru/db/metod8dev#content:5272:hdoc)
* Источник: [Cognitive complexity, ver. 1.4](https://www.sonarsource.com/docs/CognitiveComplexity.pdf) -->
- [стандарт Безопасность запуска приложений](https://its.1c.ru/db/v8std/content/774/hdoc)
- [стандарт Ограничение на выполнение «внешнего» кода](https://its.1c.ru/db/v8std/content/669/hdoc )
16 changes: 16 additions & 0 deletions docs/en/diagnostics/ExternalAppStarting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# External applications starting (ExternalAppStarting)

<!-- Блоки выше заполняются автоматически, не трогать -->
## Description
<!-- Описание диагностики заполняется вручную. Необходимо понятным языком описать смысл и схему работу -->

## Examples
<!-- В данном разделе приводятся примеры, на которые диагностика срабатывает, а также можно привести пример, как можно исправить ситуацию -->

## Sources
<!-- Необходимо указывать ссылки на все источники, из которых почерпнута информация для создания диагностики -->
<!-- Примеры источников
* Источник: [Стандарт: Тексты модулей](https://its.1c.ru/db/v8std#content:456:hdoc)
* Полезная информация: [Отказ от использования модальных окон](https://its.1c.ru/db/metod8dev#content:5272:hdoc)
* Источник: [Cognitive complexity, ver. 1.4](https://www.sonarsource.com/docs/CognitiveComplexity.pdf) -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2023
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> 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<String, Object> configuration) {
super.configure(configuration);
var pattern = userPatternString;
if (checkGotoUrl){
pattern += PATTERN_STRING_FOR_NAVI;
}
setMethodPattern(CaseInsensitivePattern.compile(pattern));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
diagnosticMessage=Check the launch of an external application
diagnosticName=External applications starting
checkGotoUrl=Check navigation links
userPatternString=User regex pattern
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
diagnosticMessage=Проверьте запуск внешнего приложения
diagnosticName=Запуск внешних приложений
checkGotoUrl=Проверять переход по навигационным ссылкам
userPatternString=Пользовательский шаблон (регулярное выражение)
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2023
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> 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<ExternalAppStartingDiagnostic> {
ExternalAppStartingDiagnosticTest() {
super(ExternalAppStartingDiagnostic.class);
}

@Test
void test() {

List<Diagnostic> 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<String, Object> configuration = diagnosticInstance.info.getDefaultConfiguration();
configuration.put("checkGotoUrl", true);
diagnosticInstance.configure(configuration);

List<Diagnostic> 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<String, Object> configuration = diagnosticInstance.info.getDefaultConfiguration();
configuration.put("userPatternString", "КомандаСистемы");
diagnosticInstance.configure(configuration);

List<Diagnostic> diagnostics = getDiagnostics();

assertThat(diagnostics, true)
.hasRange(8, 4, 18)
.hasSize(1);
}

@Test
void testConfigure_userPatternString_checkGotoUrl() {

Map<String, Object> configuration = diagnosticInstance.info.getDefaultConfiguration();
configuration.put("checkGotoUrl", true);
configuration.put("userPatternString", "КомандаСистемы");
diagnosticInstance.configure(configuration);

List<Diagnostic> diagnostics = getDiagnostics();

assertThat(diagnostics, true)
.hasRange(8, 4, 18)

.hasRange(14, 4, 32)
.hasRange(15, 26, 52)
.hasRange(16, 26, 52)

.hasSize(4);
}
}
Loading

0 comments on commit 29390f1

Please sign in to comment.