Skip to content

Commit 27acf1f

Browse files
SC-28409 Make sonar-security compatible with SLCORE
1 parent 3154bd8 commit 27acf1f

File tree

10 files changed

+210
-1
lines changed

10 files changed

+210
-1
lines changed

backend/analysis-engine/src/main/java/org/sonarsource/sonarlint/core/analysis/container/analysis/AnalysisContainer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.sonarsource.sonarlint.core.analysis.container.analysis.sensor.SonarLintSensorStorage;
4343
import org.sonarsource.sonarlint.core.analysis.container.global.AnalysisExtensionInstaller;
4444
import org.sonarsource.sonarlint.core.analysis.sonarapi.DefaultSensorContext;
45+
import org.sonarsource.sonarlint.core.analysis.sonarapi.noop.NoOpAnalysisWarnings;
4546
import org.sonarsource.sonarlint.core.analysis.sonarapi.noop.NoOpFileLinesContextFactory;
4647
import org.sonarsource.sonarlint.core.commons.log.SonarLintLogger;
4748
import org.sonarsource.sonarlint.core.commons.progress.ProgressIndicator;
@@ -65,6 +66,7 @@ protected void doBeforeStart() {
6566

6667
private void addCoreComponents() {
6768
add(
69+
new NoOpAnalysisWarnings(),
6870
cancelMonitor,
6971
SonarLintInputProject.class,
7072
NoOpFileLinesContextFactory.class,

backend/analysis-engine/src/main/java/org/sonarsource/sonarlint/core/analysis/container/analysis/filesystem/SonarLintFileSystem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.File;
2323
import java.nio.charset.Charset;
2424
import java.nio.file.Path;
25+
import java.nio.file.Paths;
2526
import java.util.SortedSet;
2627
import java.util.stream.StreamSupport;
2728
import org.sonar.api.batch.fs.FilePredicate;
@@ -140,7 +141,7 @@ public SortedSet<String> languages() {
140141

141142
@Override
142143
public File resolvePath(String path) {
143-
throw new UnsupportedOperationException("resolvePath");
144+
return Paths.get(path).toFile();
144145
}
145146

146147
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* SonarLint Core - Analysis Engine
3+
* Copyright (C) 2016-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonarsource.sonarlint.core.analysis.sonarapi.noop;
21+
22+
import org.sonar.api.notifications.AnalysisWarnings;
23+
24+
public class NoOpAnalysisWarnings implements AnalysisWarnings {
25+
26+
@Override
27+
public void addUnique(String s) {
28+
// no-op
29+
}
30+
}

backend/plugin-commons/src/main/java/org/sonarsource/sonarlint/core/plugin/commons/PluginsLoader.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ private static Set<String> additionalAllowedPlugins(Configuration configuration)
8181
allowedPluginsIds.add("omnisharp");
8282
allowedPluginsIds.add("iacenterprise");
8383
allowedPluginsIds.add("goenterprise");
84+
allowedPluginsIds.add("security");
85+
allowedPluginsIds.add("securityjavafrontend");
8486
allowedPluginsIds.addAll(maybeDbdAllowedPlugins(configuration.enableDataflowBugDetection));
8587
return Collections.unmodifiableSet(allowedPluginsIds);
8688
}

backend/server-connection/src/main/java/org/sonarsource/sonarlint/core/serverconnection/PluginsSynchronizer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public class PluginsSynchronizer {
4141
public static final Version ENTERPRISE_GO_MIN_SQ_VERSION = Version.create("2025.2");
4242
public static final String CSHARP_ENTERPRISE_PLUGIN_ID = "csharpenterprise";
4343
private static final String GO_ENTERPRISE_PLUGIN_ID = "goenterprise";
44+
private static final String SECURITY_PLUGIN_ID = "security";
45+
private static final String SECURITY_JAVA_FRONTEND_PLUGIN_ID = "securityjavafrontend";
4446
private static final SonarLintLogger LOG = SonarLintLogger.get();
4547

4648
private final Set<String> sonarSourceDisabledPluginKeys;
@@ -58,6 +60,10 @@ public PluginsSynchronizer(Set<SonarLanguage> enabledLanguages, ConnectionStorag
5860
// SLCORE-1179 Force synchronize "C# Enterprise" after repackaging (SQS 10.8+)
5961
this.notSonarLintSupportedPluginsToSynchronize.add(CSHARP_ENTERPRISE_PLUGIN_ID);
6062
}
63+
if (enabledLanguages.contains(SonarLanguage.JAVA)) {
64+
this.notSonarLintSupportedPluginsToSynchronize.add(SECURITY_PLUGIN_ID);
65+
this.notSonarLintSupportedPluginsToSynchronize.add(SECURITY_JAVA_FRONTEND_PLUGIN_ID);
66+
}
6167
this.storage = storage;
6268
this.embeddedPluginKeys = embeddedPluginKeys;
6369
}

medium-tests/pom.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,18 @@
219219
<version>1.36.1.13250</version>
220220
<type>jar</type>
221221
</artifactItem>
222+
<artifactItem>
223+
<groupId>com.sonarsource.security</groupId>
224+
<artifactId>sonar-security-plugin</artifactId>
225+
<version>11.5.0.38524</version>
226+
<type>jar</type>
227+
</artifactItem>
228+
<artifactItem>
229+
<groupId>com.sonarsource.security</groupId>
230+
<artifactId>sonar-security-java-frontend-plugin</artifactId>
231+
<version>11.5.0.38524</version>
232+
<type>jar</type>
233+
</artifactItem>
222234
</artifactItems>
223235
<outputDirectory>${project.build.directory}/plugins</outputDirectory>
224236
<overWriteReleases>false</overWriteReleases>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* SonarLint Core - Medium Tests
3+
* Copyright (C) 2016-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package mediumtest;
21+
22+
import java.io.File;
23+
import java.util.List;
24+
import java.util.Map;
25+
import org.sonarsource.sonarlint.core.rpc.protocol.backend.file.DidOpenFileParams;
26+
import org.sonarsource.sonarlint.core.rpc.protocol.client.issue.RaisedFindingDto;
27+
import org.sonarsource.sonarlint.core.rpc.protocol.common.ClientFileDto;
28+
import org.sonarsource.sonarlint.core.test.utils.junit5.SonarLintTest;
29+
import org.sonarsource.sonarlint.core.test.utils.junit5.SonarLintTestHarness;
30+
import utils.TestPlugin;
31+
32+
import static org.assertj.core.api.Assertions.assertThat;
33+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
34+
import static org.mockito.ArgumentMatchers.any;
35+
import static org.mockito.ArgumentMatchers.eq;
36+
import static org.mockito.Mockito.timeout;
37+
import static org.mockito.Mockito.verify;
38+
39+
public class SecurityMediumTest {
40+
private static final String CONFIG_SCOPE_ID = "CONFIG_SCOPE_ID";
41+
private static final boolean COMMERCIAL_ENABLED = System.getProperty("commercial") != null;
42+
43+
@SonarLintTest
44+
void it_should_find_taint_issues(SonarLintTestHarness harness) {
45+
assumeTrue(COMMERCIAL_ENABLED);
46+
var projectWithTaint = new File("src/test/projects/project-with-taint").getAbsoluteFile().toPath();
47+
var srcFilePath = projectWithTaint.resolve("src/main/java/org/owasp/benchmark/testcode/BenchmarkTest00008.java");
48+
var fileUri = srcFilePath.toUri();
49+
var fakeClient = harness.newFakeClient()
50+
.withInitialFs(CONFIG_SCOPE_ID, projectWithTaint, List.of(new ClientFileDto(fileUri, projectWithTaint.relativize(srcFilePath), CONFIG_SCOPE_ID, false,
51+
null, srcFilePath, null, null, true)))
52+
.build();
53+
var backend = harness.newBackend()
54+
.withUnboundConfigScope(CONFIG_SCOPE_ID, "My Project 1")
55+
.withStandaloneRuleConfig("javasecurity:S3649", true, Map.of())
56+
.withStandaloneEmbeddedPlugin(TestPlugin.JAVA)
57+
.withStandaloneEmbeddedPlugin(TestPlugin.SECURITY)
58+
.withStandaloneEmbeddedPluginAndEnabledLanguage(TestPlugin.SECURITY_JAVA_FRONTEND)
59+
.start(fakeClient);
60+
fakeClient.setInferredAnalysisProperties(CONFIG_SCOPE_ID, Map.of("sonar.java.libraries",
61+
"/home/damien.urruty/.m2/repository/javax/javaee-api/7.0/javaee-api-7.0.jar"));
62+
63+
backend.getFileService().didOpenFile(new DidOpenFileParams(CONFIG_SCOPE_ID, fileUri));
64+
65+
verify(fakeClient, timeout(4000).times(1)).raiseIssues(eq(CONFIG_SCOPE_ID), any(), eq(false), any());
66+
var raisedIssuesForScopeId = fakeClient.getRaisedIssuesForScopeId(CONFIG_SCOPE_ID);
67+
assertThat(raisedIssuesForScopeId)
68+
.containsOnlyKeys(fileUri);
69+
assertThat(raisedIssuesForScopeId.get(fileUri))
70+
.extracting(RaisedFindingDto::getRuleKey)
71+
.contains("javasecurity:S3649");
72+
}
73+
}

medium-tests/src/test/java/utils/PluginLocator.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ public class PluginLocator {
3131
public static final String SONAR_JAVA_SE_PLUGIN_JAR = "sonar-java-symbolic-execution-plugin-" + SONAR_JAVA_SE_PLUGIN_VERSION + ".jar";
3232
public static final String SONAR_JAVA_SE_PLUGIN_JAR_HASH = "unused";
3333

34+
public static final String SONAR_SECURITY_PLUGIN_VERSION = "11.5.0.38524";
35+
public static final String SONAR_SECURITY_PLUGIN_JAR = "sonar-security-plugin-" + SONAR_SECURITY_PLUGIN_VERSION + ".jar";
36+
public static final String SONAR_SECURITY_PLUGIN_JAR_HASH = "osef";
37+
38+
public static final String SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_VERSION = "11.5.0.38524";
39+
public static final String SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR = "sonar-security-java-frontend-plugin-" + SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_VERSION + ".jar";
40+
public static final String SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR_HASH = "osef";
41+
3442
public static final String SONAR_DBD_PLUGIN_VERSION = "1.36.1.13250";
3543
public static final String SONAR_DBD_PLUGIN_JAR = "sonar-dbd-plugin-" + SONAR_DBD_PLUGIN_VERSION + ".jar";
3644
public static final String SONAR_DBD_PLUGIN_JAR_HASH = "unused";
@@ -64,6 +72,14 @@ public static Path getJavaPluginPath() {
6472
return getValidPluginPath(SONAR_JAVA_PLUGIN_JAR);
6573
}
6674

75+
public static Path getSecurityPluginPath() {
76+
return getValidPluginPath(SONAR_SECURITY_PLUGIN_JAR);
77+
}
78+
79+
public static Path getSecurityJavaFrontendPluginPath() {
80+
return getValidPluginPath(SONAR_SECURITY_JAVA_FRONTEND_PLUGIN_JAR);
81+
}
82+
6783
public static Path getJavaSePluginPath() {
6884
return getPluginPath(SONAR_JAVA_SE_PLUGIN_JAR);
6985
}

medium-tests/src/test/java/utils/TestPlugin.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public class TestPlugin {
2929
public static final Plugin JAVA = new Plugin(Language.JAVA, PluginLocator.getJavaPluginPath(), PluginLocator.SONAR_JAVA_PLUGIN_VERSION, PluginLocator.SONAR_JAVA_PLUGIN_JAR_HASH);
3030
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);
3131

32+
public static final Plugin SECURITY = new Plugin(Language.JAVA, PluginLocator.getSecurityPluginPath(), PluginLocator.SONAR_SECURITY_PLUGIN_VERSION, PluginLocator.SONAR_SECURITY_PLUGIN_JAR_HASH);
33+
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);
34+
3235
public static final Plugin DBD = new Plugin("dbd", Language.JAVA, PluginLocator.getDbdPluginPath(), PluginLocator.SONAR_DBD_PLUGIN_VERSION, PluginLocator.SONAR_DBD_PLUGIN_JAR_HASH);
3336
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);
3437

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* OWASP Benchmark v1.2
3+
*
4+
* <p>This file is part of the Open Web Application Security Project (OWASP) Benchmark Project. For
5+
* details, please see <a
6+
* href="https://owasp.org/www-project-benchmark/">https://owasp.org/www-project-benchmark/</a>.
7+
*
8+
* <p>The OWASP Benchmark is free software: you can redistribute it and/or modify it under the terms
9+
* of the GNU General Public License as published by the Free Software Foundation, version 2.
10+
*
11+
* <p>The OWASP Benchmark is distributed in the hope that it will be useful, but WITHOUT ANY
12+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13+
* PURPOSE. See the GNU General Public License for more details.
14+
*
15+
* @author Dave Wichers
16+
* @created 2015
17+
*/
18+
package org.owasp.benchmark.testcode;
19+
20+
import java.io.IOException;
21+
import javax.servlet.ServletException;
22+
import javax.servlet.annotation.WebServlet;
23+
import javax.servlet.http.HttpServlet;
24+
import javax.servlet.http.HttpServletRequest;
25+
import javax.servlet.http.HttpServletResponse;
26+
27+
@WebServlet(value = "/sqli-00/BenchmarkTest00008")
28+
public class BenchmarkTest00008 extends HttpServlet {
29+
30+
private static final long serialVersionUID = 1L;
31+
32+
@Override
33+
public void doGet(HttpServletRequest request, HttpServletResponse response)
34+
throws ServletException, IOException {
35+
doPost(request, response);
36+
}
37+
38+
@Override
39+
public void doPost(HttpServletRequest request, HttpServletResponse response)
40+
throws ServletException, IOException {
41+
// some code
42+
response.setContentType("text/html;charset=UTF-8");
43+
44+
String param = "";
45+
if (request.getHeader("BenchmarkTest00008") != null) {
46+
param = request.getHeader("BenchmarkTest00008");
47+
}
48+
49+
// URL Decode the header value since req.getHeader() doesn't. Unlike req.getParameter().
50+
param = java.net.URLDecoder.decode(param, "UTF-8");
51+
52+
String sql = "{call " + param + "}";
53+
54+
try {
55+
java.sql.Connection connection = null;
56+
java.sql.CallableStatement statement = connection.prepareCall(sql);
57+
java.sql.ResultSet rs = statement.executeQuery();
58+
rs.toString();
59+
60+
} catch (java.sql.SQLException e) {
61+
response.getWriter().println("Error processing request.");
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)