Skip to content

Commit

Permalink
Merge pull request #3117 from artbear/file-system-access
Browse files Browse the repository at this point in the history
Правило Доступ к файловой системе - FileSystemAccess - ГОТОВО
  • Loading branch information
theshadowco authored Oct 17, 2023
2 parents 93484a3 + be17b03 commit 460e427
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 0 deletions.
39 changes: 39 additions & 0 deletions docs/diagnostics/FileSystemAccess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Доступ к файловой системе (FileSystemAccess)

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

По найденным замечаниям рекомендуется выполнить ручной аудит кода на предмет его правильности и безопасности.

## Примеры
<!-- В данном разделе приводятся примеры, на которые диагностика срабатывает, а также можно привести пример, как можно исправить ситуацию -->
```bsl
Текст = Новый ЧтениеТекста(ПутьФайла, КодировкаТекста.ANSI); // есть замечание
Текст = Новый ЗаписьТекста(ПутьФайла, КодировкаТекста.ANSI); // есть замечание
ЗначениеВФайл(ПутьФайла, ЛичныеДанные); // есть замечание
КопироватьФайл(ПутьФайла, ДругойПутьФайла); // есть замечание
МассивИмен = Новый Массив();
МассивИмен.Добавить(ПутьФайла);
ОбъединитьФайлы(МассивИмен, ДругойПутьФайла); // есть замечание
ПереместитьФайл(ПутьФайла, ДругойПутьФайла); // есть замечание
РазделитьФайл(ПутьФайла, 1024 * 1024 ); // есть замечание
СоздатьКаталог(ИмяКаталога); // есть замечание
УдалитьФайлы(ПутьФайла); // есть замечание
```

## Источники
<!-- Необходимо указывать ссылки на все источники, из которых почерпнута информация для создания диагностики -->
<!-- Примеры источников
* Источник: [Стандарт: Тексты модулей](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:542:hdoc)
* [Стандарт Безопасность запуска приложений](https://its.1c.ru/db/v8std#content:774:hdoc)
* [Безопасный режим работы - руководство разработчика](https://its.1c.ru/db/v8323doc#bookmark:dev:TI000000186)
16 changes: 16 additions & 0 deletions docs/en/diagnostics/FileSystemAccess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# FileSystemAccess (FileSystemAccess)

<!-- Блоки выше заполняются автоматически, не трогать -->
## 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,121 @@
/*
* 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.bsl.languageserver.utils.bsl.Constructors;
import com.github._1c_syntax.bsl.parser.BSLParser;
import com.github._1c_syntax.utils.CaseInsensitivePattern;
import org.antlr.v4.runtime.tree.ParseTree;

import java.util.Map;
import java.util.regex.Pattern;

@DiagnosticMetadata(
type = DiagnosticType.VULNERABILITY,
severity = DiagnosticSeverity.MAJOR,
minutesToFix = 3,
tags = {
DiagnosticTag.SUSPICIOUS
},
scope = DiagnosticScope.BSL,
activatedByDefault = false
)
public class FileSystemAccessDiagnostic extends AbstractFindMethodDiagnostic {
public static final String NEW_EXPRESSION = "File|Файл|xBase|HTMLWriter|ЗаписьHTML|HTMLReader|ЧтениеHTML" +
"|FastInfosetReader|ЧтениеFastInfoset|FastInfosetWriter|ЗаписьFastInfoset|XSLTransform|ПреобразованиеXSL" +
"|ZipFileWriter|ЗаписьZipФайла|ZipFileReader|ЧтениеZipФайла|TextReader|ЧтениеТекста|TextWriter|ЗаписьТекста" +
"|TextExtraction|ИзвлечениеТекста|BinaryData|ДвоичныеДанные|FileStream|ФайловыйПоток" +
"|FileStreamsManager|МенеджерФайловыхПотоков|DataWriter|ЗаписьДанных|DataReader|ЧтениеДанных";

public static final String GLOBAL_METHODS = "ЗначениеВФайл|ValueToFile|КопироватьФайл|FileCopy" +
"|ОбъединитьФайлы|MergeFiles|ПереместитьФайл|MoveFile|РазделитьФайл|SplitFile|СоздатьКаталог|CreateDirectory|" +
"УдалитьФайлы|DeleteFiles|КаталогПрограммы|BinDir|КаталогВременныхФайлов|TempFilesDir" +
"|КаталогДокументов|DocumentsDir|РабочийКаталогДанныхПользователя|UserDataWorkDir" +
"|НачатьПодключениеРасширенияРаботыСФайлами|BeginAttachingFileSystemExtension" +
"|НачатьУстановкуРасширенияРаботыСФайлами|BeginInstallFileSystemExtension" +
"|УстановитьРасширениеРаботыСФайлами|InstallFileSystemExtension" +
"|УстановитьРасширениеРаботыСФайламиАсинх|InstallFileSystemExtensionAsync" +
"|ПодключитьРасширениеРаботыСФайламиАсинх|AttachFileSystemExtensionAsync|" +
"КаталогВременныхФайловАсинх|TempFilesDirAsync|КаталогДокументовАсинх|DocumentsDirAsync" +
"|НачатьПолучениеКаталогаВременныхФайлов|BeginGettingTempFilesDir" +
"|НачатьПолучениеКаталогаДокументов|BeginGettingDocumentsDir" +
"|НачатьПолучениеРабочегоКаталогаДанныхПользователя|BeginGettingUserDataWorkDir" +
"|РабочийКаталогДанныхПользователяАсинх|UserDataWorkDirAsync" +
"|КопироватьФайлАсинх|CopyFileAsync|НайтиФайлыАсинх|FindFilesAsync|НачатьКопированиеФайла|BeginCopyingFile" +
"|НачатьПеремещениеФайла|BeginMovingFile|НачатьПоискФайлов|BeginFindingFiles" +
"|НачатьСозданиеДвоичныхДанныхИзФайла|BeginCreateBinaryDataFromFile" +
"|НачатьСозданиеКаталога|BeginCreatingDirectory" +
"|НачатьУдалениеФайлов|BeginDeletingFiles|ПереместитьФайлАсинх|MoveFileAsync" +
"|СоздатьДвоичныеДанныеИзФайлаАсинх|CreateBinaryDataFromFileAsync|СоздатьКаталогАсинх|CreateDirectoryAsync" +
"|УдалитьФайлыАсинх|DeleteFilesAsync";
private static final Pattern GLOBAL_METHODS_PATTERN = getPattern(GLOBAL_METHODS);

@DiagnosticParameter(
type = String.class,
defaultValue = GLOBAL_METHODS
)
private String globalMethods = GLOBAL_METHODS;

@DiagnosticParameter(
type = String.class,
defaultValue = NEW_EXPRESSION
)
private String newExpression = NEW_EXPRESSION;
private Pattern newExpressionPattern = getPattern(newExpression);

public FileSystemAccessDiagnostic() {
super(GLOBAL_METHODS_PATTERN);
}

private static Pattern getPattern(String newExpression) {
return CaseInsensitivePattern.compile(newExpression);
}

@Override
public void configure(Map<String, Object> configuration) {
super.configure(configuration);
setMethodPattern(getPattern(globalMethods));
newExpressionPattern = getPattern(newExpression);
}

@Override
protected boolean checkMethodCall(BSLParser.MethodCallContext ctx) {
return false;
}

@Override
public ParseTree visitNewExpression(BSLParser.NewExpressionContext ctx) {
Constructors.typeName(ctx).ifPresent((String typeName) -> {
var matcherTypeName = newExpressionPattern.matcher(typeName);
if (matcherTypeName.matches()) {
diagnosticStorage.addDiagnostic(ctx);
}
});
return super.visitNewExpression(ctx);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,16 @@
"title": "No NULL checks for fields from joined tables",
"$id": "#/definitions/FieldsFromJoinsWithoutIsNull"
},
"FileSystemAccess": {
"description": "FileSystemAccess",
"default": true,
"type": [
"boolean",
"object"
],
"title": "FileSystemAccess",
"$id": "#/definitions/FileSystemAccess"
},
"ForbiddenMetadataName": {
"description": "Metadata object has a forbidden name",
"default": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
diagnosticMessage=Check access to the file system
diagnosticName=FileSystemAccess
globalMethods=Global methods pattern (regex)
newExpression=Class names pattern (regex)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
diagnosticMessage=Проверьте обращение к файловой системе
diagnosticName=Доступ к файловой системе
globalMethods=Шаблон глобальных методов (регулярное выражение)
newExpression=Шаблон классов (регулярное выражение)
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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 FileSystemAccessDiagnosticTest extends AbstractDiagnosticTest<FileSystemAccessDiagnostic> {
FileSystemAccessDiagnosticTest() {
super(FileSystemAccessDiagnostic.class);
}

@Test
void test() {

List<Diagnostic> diagnostics = getDiagnostics();

assertThat(diagnostics, true)
.hasRange(1, 15, 35)
.hasRange(2, 15, 41)
.hasRange(3, 15, 31)
.hasRange(4, 15, 31)
.hasRange(5, 15, 38)
.hasRange(6, 15, 38)
.hasRange(7, 15, 33)
.hasRange(8, 15, 44)
.hasRange(9, 15, 44)
.hasRange(10, 15, 41)
.hasRange(11, 15, 41)
.hasRange(12, 15, 45)
.hasRange(13, 15, 41)
.hasRange(14, 15, 56)
.hasRange(19, 15, 41)
.hasRange(24, 15, 26)

.hasRange(29, 4, 17)
.hasRange(30, 4, 18)
.hasRange(34, 4, 19)
.hasRange(36, 4, 19)
.hasRange(37, 4, 17)
.hasRange(38, 4, 18)
.hasRange(39, 4, 16)
.hasSize(23)
;
}

@Test
void testConfigure() {

Map<String, Object> configuration = diagnosticInstance.info.getDefaultConfiguration();
configuration.put("globalMethods", "ЗначениеВФайл");
configuration.put("newExpression", "File");
diagnosticInstance.configure(configuration);

List<Diagnostic> diagnostics = getDiagnostics();

assertThat(diagnostics, true)
.hasRange(1, 15, 35)
.hasRange(29, 4, 17)
.hasSize(2);
}

}
41 changes: 41 additions & 0 deletions src/test/resources/diagnostics/FileSystemAccessDiagnostic.bsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Процедура Метод1()
Значение = Новый File(ИмяФайла); // есть ошибка
Значение = Новый xBase("C:\temp.dbf"); // есть ошибка
Значение = Новый HTMLWriter; // есть ошибка
Значение = Новый HTMLReader; // есть ошибка
Значение = Новый FastInfosetReader; // есть ошибка
Значение = Новый FastInfosetWriter; // есть ошибка
Значение = Новый XSLTransform; // есть ошибка
Значение = Новый ZipFileWriter(ИмяФайла); // есть ошибка
Значение = Новый ZipFileReader(ИмяФайла); // есть ошибка
Значение = Новый TextReader(ИмяФайла); // есть ошибка
Значение = Новый TextWriter(ИмяФайла); // есть ошибка
Значение = Новый TextExtraction(ИмяФайла); // есть ошибка
Значение = Новый BinaryData(ИмяФайла); // есть ошибка
Значение = Новый FileStream(ИмяФайла, РежимОткрытия); // есть ошибка
КонецПроцедуры

&НаСервере
Процедура Метод2()
Значение = Новый xBase("C:\temp.dbf"); // есть ошибка
КонецПроцедуры

&НаСервереБезКонтекста
Процедура Метод3()
Значение = Новый xBase; // есть ошибка
КонецПроцедуры

&НаКлиенте
Процедура Метод4()
ЗначениеВФайл("C:\Temp\PersonalData.txt", ЛичныеДанные); // есть ошибка
КопироватьФайл("C:\Temp\Order.htm", "C:\My Documents\Order.htm"); // есть ошибка

МассивИмен = Новый Массив();
МассивИмен.Добавить("C:\Windows\Temp\Presentation.ppt.1");
ОбъединитьФайлы(МассивИмен, "C:\Windows\Temp\Presentation.ppt"); // есть ошибка

ПереместитьФайл("C:\Temp\Order.htm", "C:\My Documents\Order.htm"); // есть ошибка
РазделитьФайл("C:\Windows\Temp\Presentation.ppt", 1024 * 1024 ); // есть ошибка
СоздатьКаталог("C:\Temp"); // есть ошибка
УдалитьФайлы("C:\temp\Works"); // есть ошибка
КонецПроцедуры

0 comments on commit 460e427

Please sign in to comment.