Skip to content

Commit

Permalink
SLVS-1590 Add SLCore rpc contracts for taint issues (#5808)
Browse files Browse the repository at this point in the history
  • Loading branch information
georgii-borovinskikh-sonarsource authored Nov 7, 2024
1 parent eb24cf2 commit ff36cfa
Show file tree
Hide file tree
Showing 13 changed files with 975 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-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.
*/

using SonarLint.VisualStudio.SLCore.Core;
using SonarLint.VisualStudio.SLCore.Listener.Taint;

namespace SonarLint.VisualStudio.SLCore.Listeners.UnitTests.Implementation;

[TestClass]
public class TaintVulnerabilityListenerTests
{
[TestMethod]
public void MefCtor_CheckIsExported() => MefTestHelpers.CheckTypeCanBeImported<TaintVulnerabilityListener, ISLCoreListener>();

[TestMethod]
public void MefCtor_CheckIsSingleton() => MefTestHelpers.CheckIsSingletonMefComponent<TaintVulnerabilityListener>();
}
43 changes: 43 additions & 0 deletions src/SLCore.Listeners/Implementation/TaintVulnerabilityListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-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.
*/

using System.ComponentModel.Composition;
using Newtonsoft.Json;
using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.SLCore.Core;
using SonarLint.VisualStudio.SLCore.Listener.Taint;

namespace SonarLint.VisualStudio.SLCore.Listeners.Implementation;

[Export(typeof(ISLCoreListener))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class TaintVulnerabilityListener : ITaintVulnerabilityListener
{

[ImportingConstructor]
public TaintVulnerabilityListener()
{
}

public void DidChangeTaintVulnerabilities(DidChangeTaintVulnerabilitiesParams parameters)
{
// todo https://sonarsource.atlassian.net/browse/SLVS-1592
}
}
119 changes: 119 additions & 0 deletions src/SLCore.UnitTests/Common/Models/TaintVulnerabilityDtoTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-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.
*/

using Newtonsoft.Json;
using SonarLint.VisualStudio.SLCore.Common.Models;
using SonarLint.VisualStudio.SLCore.Service.Rules.Models;

namespace SonarLint.VisualStudio.SLCore.UnitTests.Common.Models;

[TestClass]
public class TaintVulnerabilityDtoTests
{
[TestMethod]
public void Deserialized_AsExpected()
{
var expected = new TaintVulnerabilityDto(
Guid.Parse("f1276bb9-54a4-4cbd-b4ac-41d2541302ee"),
"AXgSTUZl007Zyo8hMhT-",
false,
"roslyn.sonaranalyzer.security.cs:S5135",
"Change this code to not deserialize user-controlled data.",
"sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XmlSerializerInjectionController.cs",
DateTimeOffset.FromUnixTimeMilliseconds(1615214736000),
new MQRModeDetails(CleanCodeAttribute.COMPLETE, [new ImpactDto(SoftwareQuality.SECURITY, ImpactSeverity.HIGH)]),
[
new TaintFlowDto([
new TaintLocationDto(new TextRangeWithHashDto(20, 32, 20, 58, "f677236678ac4b2ab451d66d4b251e8f"),
"Sink: this invocation is not safe; a malicious value can be injected into the caller",
"sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XmlSerializerInjectionController.cs")
])
],
new TextRangeWithHashDto(20, 32, 20, 58, "f677236678ac4b2ab451d66d4b251e8f"),
null,
false);

const string serialized =
"""
{
"id": "f1276bb9-54a4-4cbd-b4ac-41d2541302ee",
"sonarServerKey": "AXgSTUZl007Zyo8hMhT-",
"resolved": false,
"ruleKey": "roslyn.sonaranalyzer.security.cs:S5135",
"message": "Change this code to not deserialize user-controlled data.",
"ideFilePath": "sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XmlSerializerInjectionController.cs",
"introductionDate": 1615214736000,
"severityMode": {
"cleanCodeAttribute": "COMPLETE",
"impacts": [
{
"softwareQuality": "SECURITY",
"impactSeverity": "HIGH"
}
]
},
"severity": "BLOCKER",
"type": "VULNERABILITY",
"flows": [
{
"locations": [
{
"textRange": {
"startLine": 20,
"startLineOffset": 32,
"endLine": 20,
"endLineOffset": 58,
"hash": "f677236678ac4b2ab451d66d4b251e8f"
},
"message": "Sink: this invocation is not safe; a malicious value can be injected into the caller",
"filePath": "sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XmlSerializerInjectionController.cs"
}
]
}
],
"textRange": {
"startLine": 20,
"startLineOffset": 32,
"endLine": 20,
"endLineOffset": 58,
"hash": "f677236678ac4b2ab451d66d4b251e8f"
},
"ruleDescriptionContextKey": null,
"cleanCodeAttribute": "COMPLETE",
"impacts": {
"SECURITY": "HIGH"
},
"isOnNewCode": false
}
""";

var actual = JsonConvert.DeserializeObject<TaintVulnerabilityDto>(serialized);

actual
.Should()
.BeEquivalentTo(expected,
options =>
options
.ComparingByMembers<TaintVulnerabilityDto>()
.ComparingByMembers<MQRModeDetails>()
.ComparingByMembers<TaintFlowDto>()
.ComparingByMembers<TextRangeWithHashDto>());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-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.
*/

using Newtonsoft.Json;
using SonarLint.VisualStudio.SLCore.Listener.Taint;

namespace SonarLint.VisualStudio.SLCore.UnitTests.Listener.Taint;

[TestClass]
public class DidChangeTaintVulnerabilitiesParamsTests
{
[TestMethod]
public void Deserialized_AsExpected_SmokeTest()
{
const string serialized =
"""
{
"configurationScopeId": "SLVS_Bound_VS2019",
"closedTaintVulnerabilityIds": [ "62294585-d219-4d07-8e40-6d28d2f2f90e", "62294585-d219-4d07-8e40-6d28d2f2f90e", "62294585-d219-4d07-8e40-6d28d2f2f90e" ],
"addedTaintVulnerabilities": [
{
"id": "62294585-d219-4d07-8e40-6d28d2f2f90e",
"sonarServerKey": "AXgSTUbU007Zyo8hMhUK",
"resolved": false,
"ruleKey": "roslyn.sonaranalyzer.security.cs:S2091",
"message": "Change this code to not construct this XPath expression from user-controlled data.",
"ideFilePath": "sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XPathInjectionController.cs",
"introductionDate": 1615214736000,
"severityMode": {
"cleanCodeAttribute": "COMPLETE",
"impacts": [
{
"softwareQuality": "SECURITY",
"impactSeverity": "HIGH"
}
]
},
"severity": "BLOCKER",
"type": "VULNERABILITY",
"flows": [
{
"locations": []
},
{
"locations": []
}
],
"textRange": {
"startLine": 23,
"startLineOffset": 27,
"endLine": 23,
"endLineOffset": 59,
"hash": "4fdeebd4a19fd4b1c4c5b9b43ea9f71e"
},
"ruleDescriptionContextKey": null,
"cleanCodeAttribute": "COMPLETE",
"impacts": {
"SECURITY": "HIGH"
},
"isOnNewCode": false
},
{
"id": "62294585-d219-4d07-8e40-6d28d2f2f90e",
"sonarServerKey": "AXgSTUbU007Zyo8hMhUK",
"resolved": false,
"ruleKey": "roslyn.sonaranalyzer.security.cs:S2091",
"message": "Change this code to not construct this XPath expression from user-controlled data.",
"ideFilePath": "sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XPathInjectionController.cs",
"introductionDate": 1615214736000,
"severityMode": {
"cleanCodeAttribute": "COMPLETE",
"impacts": [
{
"softwareQuality": "SECURITY",
"impactSeverity": "HIGH"
}
]
},
"severity": "BLOCKER",
"type": "VULNERABILITY",
"flows": [
{
"locations": []
},
{
"locations": []
}
],
"textRange": {
"startLine": 23,
"startLineOffset": 27,
"endLine": 23,
"endLineOffset": 59,
"hash": "4fdeebd4a19fd4b1c4c5b9b43ea9f71e"
},
"ruleDescriptionContextKey": null,
"cleanCodeAttribute": "COMPLETE",
"impacts": {
"SECURITY": "HIGH"
},
"isOnNewCode": false
}
],
"updatedTaintVulnerabilities": [
{
"id": "62294585-d219-4d07-8e40-6d28d2f2f90e",
"sonarServerKey": "AXgSTUbU007Zyo8hMhUK",
"resolved": false,
"ruleKey": "roslyn.sonaranalyzer.security.cs:S2091",
"message": "Change this code to not construct this XPath expression from user-controlled data.",
"ideFilePath": "sonarlint-visualstudio-sampleprojects\\bound\\sonarcloud\\SLVS_Samples_Bound_VS2019\\Taint_CSharp_NetCore_WebAppReact\\Taint\\XPathInjectionController.cs",
"introductionDate": 1615214736000,
"severityMode": {
"cleanCodeAttribute": "COMPLETE",
"impacts": [
{
"softwareQuality": "SECURITY",
"impactSeverity": "HIGH"
}
]
},
"severity": "BLOCKER",
"type": "VULNERABILITY",
"flows": [
{
"locations": []
},
{
"locations": []
}
],
"textRange": {
"startLine": 23,
"startLineOffset": 27,
"endLine": 23,
"endLineOffset": 59,
"hash": "4fdeebd4a19fd4b1c4c5b9b43ea9f71e"
},
"ruleDescriptionContextKey": null,
"cleanCodeAttribute": "COMPLETE",
"impacts": {
"SECURITY": "HIGH"
},
"isOnNewCode": false
}
]
}
""";

var actual = JsonConvert.DeserializeObject<DidChangeTaintVulnerabilitiesParams>(serialized);

actual.configurationScopeId.Should().Be("SLVS_Bound_VS2019");
actual.closedTaintVulnerabilityIds.Should().HaveCount(3);
actual.closedTaintVulnerabilityIds.Should().NotContain(Guid.Empty);
actual.addedTaintVulnerabilities.Should().HaveCount(2);
actual.addedTaintVulnerabilities.Should().NotContainNulls();
actual.updatedTaintVulnerabilities.Should().HaveCount(1);
actual.updatedTaintVulnerabilities.Should().NotContainNulls();
}
}
Loading

0 comments on commit ff36cfa

Please sign in to comment.