Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable ucfg rule for JS embedded in HTML files #4074

Merged
merged 3 commits into from Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -0,0 +1,103 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2012-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program 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 of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sonar.javascript.it.plugin;

import static com.sonar.javascript.it.plugin.OrchestratorStarter.JAVASCRIPT_PLUGIN_LOCATION;
import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
import static org.assertj.core.api.Assertions.assertThat;

import com.sonar.javascript.it.plugin.assertj.BuildResultAssert;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
import com.sonar.orchestrator.container.Edition;
import com.sonar.orchestrator.junit5.OrchestratorExtension;
import com.sonar.orchestrator.locator.FileLocation;
import com.sonar.orchestrator.locator.MavenLocation;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Map;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

class HtmlSecurityTest {

private static Orchestrator orchestrator;

@Test
void should_not_generate_ucfgs_for_html() throws IOException {
var projectKey = "html-project";
var projectPath = TestUtils.projectDir(projectKey);

OrchestratorStarter.setProfiles(
orchestrator,
projectKey,
Map.of("html-security-profile", "js")
);

var result = orchestrator.executeBuild(getScanner(projectPath, projectKey));
assertThat(result.isSuccess()).isTrue();

var stream = Files.find(
projectPath.toPath().resolve(".scannerwork"),
3,
BuildResultAssert::isUcfgFile
);
assertThat(stream.toList()).isEmpty();
}

@BeforeAll
public static void startOrchestrator() {
var builder = OrchestratorExtension
.builderEnv()
.useDefaultAdminCredentialsForBuilds(true)
.setSonarVersion(System.getProperty("sonar.runtimeVersion", "LATEST_RELEASE"))
.addPlugin(JAVASCRIPT_PLUGIN_LOCATION)
.setEdition(Edition.DEVELOPER)
.activateLicense()
.addPlugin(MavenLocation.of("com.sonarsource.security", "sonar-security-plugin", "DEV"))
.addPlugin(
MavenLocation.of("com.sonarsource.security", "sonar-security-js-frontend-plugin", "DEV")
)
.addPlugin(MavenLocation.of("org.sonarsource.html", "sonar-html-plugin", "LATEST_RELEASE"))
.restoreProfileAtStartup(FileLocation.ofClasspath("/html-security-profile.xml"));

orchestrator = builder.build();
// Installation of SQ server in orchestrator is not thread-safe, so we need to synchronize
synchronized (OrchestratorStarter.class) {
orchestrator.start();
}
}

@AfterAll
public static void stopOrchestrator() {
orchestrator.stop();
}

private static SonarScanner getScanner(File projectDir, String projectKey) {
return getSonarScanner()
.setProjectKey(projectKey)
.setSourceEncoding("UTF-8")
.setDebugLogs(true)
.setSourceDirs(".")
.setProjectDir(projectDir);
}
}
@@ -0,0 +1,105 @@
/*
* SonarQube JavaScript Plugin
* Copyright (C) 2012-2024 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program 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 of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sonar.javascript.it.plugin;

import static com.sonar.javascript.it.plugin.OrchestratorStarter.JAVASCRIPT_PLUGIN_LOCATION;
import static com.sonar.javascript.it.plugin.OrchestratorStarter.getSonarScanner;
import static org.assertj.core.api.Assertions.assertThat;

import com.sonar.javascript.it.plugin.assertj.BuildResultAssert;
import com.sonar.orchestrator.Orchestrator;
import com.sonar.orchestrator.build.SonarScanner;
import com.sonar.orchestrator.container.Edition;
import com.sonar.orchestrator.junit5.OrchestratorExtension;
import com.sonar.orchestrator.locator.FileLocation;
import com.sonar.orchestrator.locator.MavenLocation;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Map;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

class YamlSecurityTest {

private static Orchestrator orchestrator;

@Test
void should_generate_ucfgs_for_yaml() throws IOException {
var projectKey = "yaml-aws-lambda-analyzed";
var projectPath = TestUtils.projectDir(projectKey);

OrchestratorStarter.setProfiles(
orchestrator,
projectKey,
Map.of("yaml-security-profile", "js")
);

var result = orchestrator.executeBuild(getScanner(projectPath, projectKey));
assertThat(result.isSuccess()).isTrue();

var stream = Files.find(
projectPath.toPath().resolve(".scannerwork"),
3,
BuildResultAssert::isUcfgFile
);
assertThat(stream.toList()).hasSize(1);
}

@BeforeAll
public static void startOrchestrator() {
var builder = OrchestratorExtension
.builderEnv()
.useDefaultAdminCredentialsForBuilds(true)
.setSonarVersion(System.getProperty("sonar.runtimeVersion", "LATEST_RELEASE"))
.addPlugin(JAVASCRIPT_PLUGIN_LOCATION)
.setEdition(Edition.DEVELOPER)
.activateLicense()
.addPlugin(MavenLocation.of("com.sonarsource.security", "sonar-security-plugin", "DEV"))
.addPlugin(
MavenLocation.of("com.sonarsource.security", "sonar-security-js-frontend-plugin", "DEV")
)
.addPlugin(
MavenLocation.of("org.sonarsource.config", "sonar-config-plugin", "LATEST_RELEASE")
)
.restoreProfileAtStartup(FileLocation.ofClasspath("/yaml-security-profile.xml"));

orchestrator = builder.build();
// Installation of SQ server in orchestrator is not thread-safe, so we need to synchronize
synchronized (OrchestratorStarter.class) {
orchestrator.start();
}
}

@AfterAll
public static void stopOrchestrator() {
orchestrator.stop();
}

private static SonarScanner getScanner(File projectDir, String projectKey) {
return getSonarScanner()
.setProjectKey(projectKey)
.setSourceEncoding("UTF-8")
.setDebugLogs(true)
.setSourceDirs(".")
.setProjectDir(projectDir);
}
}
Expand Up @@ -82,7 +82,7 @@ private static List<Path> findUcfgFilesIn(Path projectPath) throws IOException {
}
}

private static boolean isUcfgFile(Path path, BasicFileAttributes attrs) {
public static boolean isUcfgFile(Path path, BasicFileAttributes attrs) {
return attrs.isRegularFile() && path.getFileName().toString().endsWith(".ucfgs");
}

Expand Down
17 changes: 17 additions & 0 deletions its/plugin/tests/src/test/resources/html-security-profile.xml
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<name>html-security-profile</name>
<language>js</language>
<rules>
<rule>
<repositoryKey>javascript</repositoryKey>
<key>S1116</key> <!-- empty statement -->
<priority>INFO</priority>
</rule>
<rule>
<repositoryKey>jssecurity</repositoryKey>
<key>S2076</key> <!-- OSCommandInjectionCheck -->
<priority>INFO</priority>
</rule>
</rules>
</profile>
17 changes: 17 additions & 0 deletions its/plugin/tests/src/test/resources/yaml-security-profile.xml
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<name>yaml-security-profile</name>
<language>js</language>
<rules>
<rule>
<repositoryKey>javascript</repositoryKey>
<key>S1116</key> <!-- empty statement -->
<priority>INFO</priority>
</rule>
<rule>
<repositoryKey>jssecurity</repositoryKey>
<key>S2076</key> <!-- OSCommandInjectionCheck -->
<priority>INFO</priority>
</rule>
</rules>
</profile>
Expand Up @@ -84,6 +84,7 @@ static List<EslintRule> getUnchangedFileRules(List<EslintRule> rules) {
static List<EslintRule> getHtmlFileRules(List<EslintRule> rules) {
var blackListRuleKeys = new HashSet<String>();
blackListRuleKeys.add("no-var");
blackListRuleKeys.add("ucfg");
return EslintRule.findAllBut(rules, blackListRuleKeys);
}

Expand Down
Expand Up @@ -135,9 +135,9 @@ void should_filter_out_rules_for_html() {
var rules = rules("key1", "key2", "ucfg", "no-var");
var filteredRules = AnalysisMode.getHtmlFileRules(rules);
assertThat(filteredRules)
.hasSize(3)
.hasSize(2)
.extracting(EslintRule::getKey)
.containsExactlyInAnyOrder("key1", "key2", "ucfg");
.containsExactlyInAnyOrder("key1", "key2");
}

private static List<EslintRule> rules(String... keys) {
Expand Down