Skip to content

[DO NOT MERGE] SC-28409 Make sonar-security compatible with SLCORE #1408

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

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
- mvn -B -e -V -Pits dependency:go-offline # populate cache including ITs deps too
cleanup_before_cache_script: cleanup_maven_repository

test_linux_task:

Check warning on line 91 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L91

task "test_linux" depends on task "build", but their only_if conditions are different

Check warning on line 91 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L91

task "test_linux" depends on task "build", but their only_if conditions are different
# Run unit tests on Linux with Java 17 and SonarQube analysis on Next
depends_on:
- build
Expand All @@ -110,7 +110,7 @@
path: '**/target/surefire-reports/TEST-*.xml'
format: junit

test_windows_task:

Check warning on line 113 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L113

task "test_windows" depends on task "build", but their only_if conditions are different

Check warning on line 113 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L113

task "test_windows" depends on task "build", but their only_if conditions are different
# Run UTs on Windows (Java 17)
depends_on:
- build
Expand All @@ -131,7 +131,7 @@
path: '**/target/surefire-reports/TEST-*.xml'
format: junit

inspect_orchestrator_cache_task:

Check warning on line 134 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L134

task "inspect_orchestrator_cache" depends on task "build", but their only_if conditions are different

Check warning on line 134 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L134

task "inspect_orchestrator_cache" depends on task "build", but their only_if conditions are different
<<: *ONLY_IF_EXCEPT_NIGHTLY
depends_on: build
eks_container:
Expand Down Expand Up @@ -167,7 +167,7 @@
ws_artifacts:
path: "whitesource/**/*"

qa_task:

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different

Check warning on line 170 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L170

task "qa" depends on task "build", but their only_if conditions are different
# Run ITs
depends_on:
- build
Expand Down Expand Up @@ -230,14 +230,10 @@
log_artifacts:
path: "**/target/**/sonarqube*/logs/*.log"

promote_task:

Check warning on line 233 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L233

task "promote" depends on task "build", but their only_if conditions are different

Check warning on line 233 in .cirrus.yml

View check run for this annotation

Cirrus CI / Build Parsing Results

.cirrus.yml#L233

task "promote" depends on task "build", but their only_if conditions are different
# Promotion
depends_on:
- build
- test_linux
- test_windows
- mend_scan
- qa
<<: *ONLY_IF_EXCEPT_NIGHTLY
eks_container:
<<: *CONTAINER_DEFINITION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.sonarsource.sonarlint.core.analysis.container.analysis.sensor.SonarLintSensorStorage;
import org.sonarsource.sonarlint.core.analysis.container.global.AnalysisExtensionInstaller;
import org.sonarsource.sonarlint.core.analysis.sonarapi.DefaultSensorContext;
import org.sonarsource.sonarlint.core.analysis.sonarapi.noop.NoOpAnalysisWarnings;
import org.sonarsource.sonarlint.core.analysis.sonarapi.noop.NoOpFileLinesContextFactory;
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
import org.sonarsource.sonarlint.core.commons.progress.ProgressIndicator;
Expand All @@ -65,6 +66,7 @@ protected void doBeforeStart() {

private void addCoreComponents() {
add(
new NoOpAnalysisWarnings(),
cancelMonitor,
SonarLintInputProject.class,
NoOpFileLinesContextFactory.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.SortedSet;
import java.util.stream.StreamSupport;
import org.sonar.api.batch.fs.FilePredicate;
Expand Down Expand Up @@ -140,7 +141,7 @@ public SortedSet<String> languages() {

@Override
public File resolvePath(String path) {
throw new UnsupportedOperationException("resolvePath");
return Paths.get(path).toFile();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* SonarLint Core - Analysis Engine
* Copyright (C) 2016-2025 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 org.sonarsource.sonarlint.core.analysis.sonarapi.noop;

import org.sonar.api.notifications.AnalysisWarnings;

public class NoOpAnalysisWarnings implements AnalysisWarnings {

@Override
public void addUnique(String s) {
// no-op
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ private static Set<String> additionalAllowedPlugins(Configuration configuration)
allowedPluginsIds.add("omnisharp");
allowedPluginsIds.add("iacenterprise");
allowedPluginsIds.add("goenterprise");
allowedPluginsIds.add("security");
allowedPluginsIds.add("securityjavafrontend");
allowedPluginsIds.addAll(maybeDbdAllowedPlugins(configuration.enableDataflowBugDetection));
return Collections.unmodifiableSet(allowedPluginsIds);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class PluginsSynchronizer {
public static final Version ENTERPRISE_GO_MIN_SQ_VERSION = Version.create("2025.2");
public static final String CSHARP_ENTERPRISE_PLUGIN_ID = "csharpenterprise";
private static final String GO_ENTERPRISE_PLUGIN_ID = "goenterprise";
private static final String SECURITY_PLUGIN_ID = "security";
private static final String SECURITY_JAVA_FRONTEND_PLUGIN_ID = "securityjavafrontend";
private static final SonarLintLogger LOG = SonarLintLogger.get();

private final Set<String> sonarSourceDisabledPluginKeys;
Expand All @@ -58,6 +60,10 @@ public PluginsSynchronizer(Set<SonarLanguage> enabledLanguages, ConnectionStorag
// SLCORE-1179 Force synchronize "C# Enterprise" after repackaging (SQS 10.8+)
this.notSonarLintSupportedPluginsToSynchronize.add(CSHARP_ENTERPRISE_PLUGIN_ID);
}
if (enabledLanguages.contains(SonarLanguage.JAVA)) {
this.notSonarLintSupportedPluginsToSynchronize.add(SECURITY_PLUGIN_ID);
this.notSonarLintSupportedPluginsToSynchronize.add(SECURITY_JAVA_FRONTEND_PLUGIN_ID);
}
this.storage = storage;
this.embeddedPluginKeys = embeddedPluginKeys;
}
Expand Down
12 changes: 12 additions & 0 deletions medium-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,18 @@
<version>1.36.1.13250</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>com.sonarsource.security</groupId>
<artifactId>sonar-security-plugin</artifactId>
<version>11.5.0.38524</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>com.sonarsource.security</groupId>
<artifactId>sonar-security-java-frontend-plugin</artifactId>
<version>11.5.0.38524</version>
<type>jar</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/plugins</outputDirectory>
<overWriteReleases>false</overWriteReleases>
Expand Down
73 changes: 73 additions & 0 deletions medium-tests/src/test/java/mediumtest/SecurityMediumTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* SonarLint Core - Medium Tests
* Copyright (C) 2016-2025 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 mediumtest;

import java.io.File;
import java.util.List;
import java.util.Map;
import org.sonarsource.sonarlint.core.rpc.protocol.backend.file.DidOpenFileParams;
import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.RaisedFindingDto;
import org.sonarsource.sonarlint.core.rpc.protocol.common.ClientFileDto;
import org.sonarsource.sonarlint.core.test.utils.junit5.SonarLintTest;
import org.sonarsource.sonarlint.core.test.utils.junit5.SonarLintTestHarness;
import utils.TestPlugin;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;

public class SecurityMediumTest {
private static final String CONFIG_SCOPE_ID = "CONFIG_SCOPE_ID";
private static final boolean COMMERCIAL_ENABLED = System.getProperty("commercial") != null;

@SonarLintTest
void it_should_find_taint_issues(SonarLintTestHarness harness) {
assumeTrue(COMMERCIAL_ENABLED);
var projectWithTaint = new File("src/test/projects/project-with-taint").getAbsoluteFile().toPath();
var srcFilePath = projectWithTaint.resolve("src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00008.java");
var fileUri = srcFilePath.toUri();
var fakeClient = harness.newFakeClient()
.withInitialFs(CONFIG_SCOPE_ID, projectWithTaint, List.of(new ClientFileDto(fileUri, projectWithTaint.relativize(srcFilePath), CONFIG_SCOPE_ID, false,
null, srcFilePath, null, null, true)))
.build();
var backend = harness.newBackend()
.withUnboundConfigScope(CONFIG_SCOPE_ID, "My Project 1")
.withStandaloneRuleConfig("javasecurity:S3649", true, Map.of())
.withStandaloneEmbeddedPlugin(TestPlugin.JAVA)
.withStandaloneEmbeddedPlugin(TestPlugin.SECURITY)
.withStandaloneEmbeddedPluginAndEnabledLanguage(TestPlugin.SECURITY_JAVA_FRONTEND)
.start(fakeClient);
fakeClient.setInferredAnalysisProperties(CONFIG_SCOPE_ID, Map.of("sonar.java.libraries",
"/home/damien.urruty/.m2/repository/javax/javaee-api/7.0/javaee-api-7.0.jar"));

backend.getFileService().didOpenFile(new DidOpenFileParams(CONFIG_SCOPE_ID, fileUri));

verify(fakeClient, timeout(4000).times(1)).raiseIssues(eq(CONFIG_SCOPE_ID), any(), eq(false), any());
var raisedIssuesForScopeId = fakeClient.getRaisedIssuesForScopeId(CONFIG_SCOPE_ID);
assertThat(raisedIssuesForScopeId)
.containsOnlyKeys(fileUri);
assertThat(raisedIssuesForScopeId.get(fileUri))
.extracting(RaisedFindingDto::getRuleKey)
.contains("javasecurity:S3649");
}
}
16 changes: 16 additions & 0 deletions medium-tests/src/test/java/utils/PluginLocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ public class PluginLocator {
public static final String SONAR_JAVA_SE_PLUGIN_JAR = "sonar-java-symbolic-execution-plugin-" + SONAR_JAVA_SE_PLUGIN_VERSION + ".jar";
public static final String SONAR_JAVA_SE_PLUGIN_JAR_HASH = "unused";

public static final String SONAR_SECURITY_PLUGIN_VERSION = "11.5.0.38524";
public static final String SONAR_SECURITY_PLUGIN_JAR = "sonar-security-plugin-" + SONAR_SECURITY_PLUGIN_VERSION + ".jar";
public static final String SONAR_SECURITY_PLUGIN_JAR_HASH = "osef";

public static final String SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_VERSION = "11.5.0.38524";
public static final String SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR = "sonar-security-java-frontend-plugin-" + SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_VERSION + ".jar";
public static final String SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR_HASH = "osef";

public static final String SONAR_DBD_PLUGIN_VERSION = "1.36.1.13250";
public static final String SONAR_DBD_PLUGIN_JAR = "sonar-dbd-plugin-" + SONAR_DBD_PLUGIN_VERSION + ".jar";
public static final String SONAR_DBD_PLUGIN_JAR_HASH = "unused";
Expand Down Expand Up @@ -64,6 +72,14 @@ public static Path getJavaPluginPath() {
return getValidPluginPath(SONAR_JAVA_PLUGIN_JAR);
}

public static Path getSecurityPluginPath() {
return getValidPluginPath(SONAR_SECURITY_PLUGIN_JAR);
}

public static Path getSecurityJavaFrontendPluginPath() {
return getValidPluginPath(SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR);
}

public static Path getJavaSePluginPath() {
return getPluginPath(SONAR_JAVA_SE_PLUGIN_JAR);
}
Expand Down
3 changes: 3 additions & 0 deletions medium-tests/src/test/java/utils/TestPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class TestPlugin {
public static final Plugin JAVA = new Plugin(Language.JAVA, PluginLocator.getJavaPluginPath(), PluginLocator.SONAR_JAVA_PLUGIN_VERSION, PluginLocator.SONAR_JAVA_PLUGIN_JAR_HASH);
public static final Plugin JAVA_SE = new Plugin("javasymbolicexecution", Language.JAVA, PluginLocator.getJavaSePluginPath(), PluginLocator.SONAR_JAVA_SE_PLUGIN_VERSION, PluginLocator.SONAR_JAVA_SE_PLUGIN_JAR_HASH);

public static final Plugin SECURITY = new Plugin(Language.JAVA, PluginLocator.getSecurityPluginPath(), PluginLocator.SONAR_SECURITY_PLUGIN_VERSION, PluginLocator.SONAR_SECURITY_PLUGIN_JAR_HASH);
public static final Plugin SECURITY_JAVA_FRONTEND = new Plugin(Language.JAVA, PluginLocator.getSecurityJavaFrontendPluginPath(), PluginLocator.SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_VERSION, PluginLocator.SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR_HASH);

public static final Plugin DBD = new Plugin("dbd", Language.JAVA, PluginLocator.getDbdPluginPath(), PluginLocator.SONAR_DBD_PLUGIN_VERSION, PluginLocator.SONAR_DBD_PLUGIN_JAR_HASH);
public static final Plugin DBD_JAVA = new Plugin("dbdjavafrontend", Language.JAVA, PluginLocator.getDbdJavaPluginPath(), PluginLocator.SONAR_DBD_JAVA_PLUGIN_VERSION, PluginLocator.SONAR_DBD_JAVA_PLUGIN_JAR_HASH);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* OWASP Benchmark v1.2
*
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project. For
* details, please see <a
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
*
* <p>The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation, version 2.
*
* <p>The OWASP Benchmark 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 General Public License for more details.
*
* @author Dave Wichers
* @created 2015
*/
package org.owasp.benchmark.testcode;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(value = "/sqli-00/BenchmarkTest00008")
public class BenchmarkTest00008 extends HttpServlet {

private static final long serialVersionUID = 1L;

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// some code
response.setContentType("text/html;charset=UTF-8");

String param = "";
if (request.getHeader("BenchmarkTest00008") != null) {
param = request.getHeader("BenchmarkTest00008");
}

// URL Decode the header value since req.getHeader() doesn't. Unlike req.getParameter().
param = java.net.URLDecoder.decode(param, "UTF-8");

String sql = "{call " + param + "}";

try {
java.sql.Connection connection = null;
java.sql.CallableStatement statement = connection.prepareCall(sql);
java.sql.ResultSet rs = statement.executeQuery();
rs.toString();

} catch (java.sql.SQLException e) {
response.getWriter().println("Error processing request.");
}
}
}
Loading