Welcome to Snyk for Eclipse
"
- + "
\n" + snykWarningText + "\n" + "");
- }
-
@Override
public void setFocus() {
treeViewer.getControl().setFocus();
@@ -190,34 +154,14 @@ public void addFileNode(ProductTreeNode parent, FileTreeNode toBeAdded) {
@Override
public void addInfoNode(ProductTreeNode parent, InfoTreeNode toBeAdded) {
- List list = new ArrayList<>();
- var children = parent.getChildren();
- if (children != null) {
- list = Arrays.stream(children).map(it -> (BaseTreeNode) it).collect(Collectors.toList());
- }
-
toBeAdded.setParent(parent);
- int insertIndex = GetLastInfoNodeIndex(list);
- list.add(insertIndex, toBeAdded);
- parent.setChildren(list.toArray(new BaseTreeNode[0]));
+ parent.addChild(toBeAdded);
Display.getDefault().asyncExec(() -> {
this.treeViewer.refresh(parent, true);
});
}
- private int GetLastInfoNodeIndex(List list) {
- int insertIndex = 0;
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i) instanceof InfoTreeNode) {
- insertIndex += 1;
- } else {
- break;
- }
- }
- return insertIndex;
- }
-
@Override
public ProductTreeNode getProductNode(String product, String folderPath) {
if (product == null || folderPath == null) {
@@ -327,4 +271,4 @@ private void addCommandIfNotPresent(IMenuManager menu, String commandId) {
}
}
-}
\ No newline at end of file
+}
diff --git a/plugin/src/main/java/io/snyk/languageserver/SnykIssueCache.java b/plugin/src/main/java/io/snyk/languageserver/SnykIssueCache.java
index 1658f75a..013dec62 100644
--- a/plugin/src/main/java/io/snyk/languageserver/SnykIssueCache.java
+++ b/plugin/src/main/java/io/snyk/languageserver/SnykIssueCache.java
@@ -4,11 +4,13 @@
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
+import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import io.snyk.eclipse.plugin.domain.ProductConstants;
import io.snyk.languageserver.protocolextension.messageObjects.scanResults.Issue;
+import io.snyk.languageserver.protocolextension.messageObjects.scanResults.IssueComparator;
public class SnykIssueCache {
private final Map> codeSecurityIssues = new ConcurrentHashMap<>();
@@ -75,8 +77,8 @@ public Collection getIssues(String path, String displayProduct) {
* @param issues The collection of issues to add
*/
public void addCodeIssues(String path, Collection issues) {
- var qualityIssues = new HashSet(issues.size());
- var securityIssues = new HashSet(issues.size());
+ var qualityIssues = new TreeSet(new IssueComparator(issues));
+ var securityIssues = new TreeSet(new IssueComparator(issues));
for (Issue issue : issues) {
if (issue.additionalData().isSecurityType()) {
securityIssues.add(issue);
@@ -138,7 +140,7 @@ public void removeCodeIssuesForPath(String path) {
*/
public void addOssIssues(String path, Collection issues) {
if (issues.size() > 0) {
- ossIssues.put(path, issues);
+ ossIssues.put(path, new TreeSet(new IssueComparator(issues)));
} else {
ossIssues.remove(path);
}
@@ -173,7 +175,7 @@ public void removeOssIssuesForPath(String path) {
*/
public void addIacIssues(String path, Collection issues) {
if (issues.size() > 0) {
- iacIssues.put(path, issues);
+ iacIssues.put(path, new TreeSet(new IssueComparator(issues)));
} else {
iacIssues.remove(path);
}
@@ -208,7 +210,7 @@ public long getTotalCount(String product) {
return getCacheByDisplayProduct(product).values().stream().flatMap(Collection::stream).count();
}
- private Map> getCacheByDisplayProduct(String displayProduct) {
+ public Map> getCacheByDisplayProduct(String displayProduct) {
switch (displayProduct) {
case ProductConstants.DISPLAYED_OSS:
return ossIssues;
diff --git a/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java b/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java
index 79ed4fab..dcf94a27 100644
--- a/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java
+++ b/plugin/src/main/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClient.java
@@ -27,7 +27,7 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -99,11 +99,9 @@
import io.snyk.languageserver.protocolextension.messageObjects.SnykScanParam;
import io.snyk.languageserver.protocolextension.messageObjects.SnykTrustedFoldersParams;
import io.snyk.languageserver.protocolextension.messageObjects.scanResults.Issue;
-import io.snyk.languageserver.protocolextension.messageObjects.scanResults.IssueSorter;
@SuppressWarnings("restriction")
public class SnykExtendedLanguageClient extends LanguageClientImpl {
- private static final String SNYK_CODE_CONSISTENT_IGNORES = "snykCodeConsistentIgnores";
private ProgressManager progressManager = new ProgressManager(this);
private final ObjectMapper om = new ObjectMapper();
private TaskProcessor taskProcessor;
@@ -133,19 +131,17 @@ private void registerRefreshFeatureFlagsTask() {
public void refreshFeatureFlags() {
boolean enableConsistentIgnores = getFeatureFlagStatus(FeatureFlagConstants.SNYK_CODE_CONSISTENT_IGNORES);
- Preferences.getInstance().store(Preferences.IS_GLOBAL_IGNORES_FEATURE_ENABLED,
- Boolean.valueOf(enableConsistentIgnores).toString());
-
- updateIgnoresButtons();
+ toggleIgnores(enableConsistentIgnores);
}
- private void updateIgnoresButtons() {
+ private void toggleIgnores(Boolean enableConsistentIgnores) {
+ Preferences.getInstance().store(Preferences.IS_GLOBAL_IGNORES_FEATURE_ENABLED,
+ Boolean.valueOf(enableConsistentIgnores).toString());
PlatformUI.getWorkbench().getDisplay().asyncExec(() -> {
var snykToolView = SnykStartup.getView();
if (snykToolView != null)
snykToolView.toggleIgnoresButtons();
});
-
}
private void createIssueCaches() {
@@ -323,12 +319,12 @@ public void hasAuthenticated(HasAuthenticatedParam param) {
if (differentToken) {
prefs.store(Preferences.AUTH_TOKEN_KEY, newToken);
}
-
+
if (!Preferences.getInstance().isTest()) {
configurationUpdater.configurationChanged();
refreshFeatureFlags();
}
-
+
if (!newToken.isBlank() && PlatformUI.isWorkbenchRunning()) {
enableSnykViewRunActions();
}
@@ -379,7 +375,9 @@ public void snykScan(SnykScanParam param) {
case SCAN_STATE_SUCCESS:
scanState.setScanInProgress(inProgressKey, false);
for (ProductTreeNode productTreeNode : affectedProductTreeNodes) {
+ productTreeNode.reset();
addInfoNodes(productTreeNode, param.getFolderPath(), issueCache);
+ populateFileAndIssueNodes(productTreeNode, param.getFolderPath(), issueCache);
}
break;
case SCAN_STATE_ERROR:
@@ -502,7 +500,7 @@ private void addInfoNodes(ProductTreeNode productNode, String folderPath, SnykIs
}
if (totalCount > 0 && ignoredCount == totalCount
- && pref.getBooleanPref(Preferences.IS_GLOBAL_IGNORES_FEATURE_ENABLED)
+ && pref.getBooleanPref(Preferences.IS_GLOBAL_IGNORES_FEATURE_ENABLED)
&& pref.getBooleanPref(FILTER_IGNORES_SHOW_OPEN_ISSUES)) {
toolView.addInfoNode(productNode,
new InfoTreeNode(ISnykToolView.IGNORED_ISSUES_FILTERED_BUT_AVAILABLE));
@@ -529,20 +527,19 @@ public CompletableFuture publishDiagnostics316(PublishDiagnostics316Param
return;
}
- var productTreeNodes = populateIssueCache(param, filePath);
- populateFileAndIssueNodes(filePath, productTreeNodes);
+ populateIssueCache(param, filePath);
});
}
- private void populateFileAndIssueNodes(String filePath, Set nodes) {
- for (ProductTreeNode productTreeNode : nodes) {
- var issueCache = IssueCacheHolder.getInstance().getCacheInstance(filePath);
- var issues = issueCache.getIssues(filePath, productTreeNode.getProduct());
- issues = IssueSorter.sortIssuesBySeverity(issues);
- issues = filterIgnoredIssues(issues);
- if (issues.isEmpty())
+ private void populateFileAndIssueNodes(ProductTreeNode productTreeNode, String folderPath, SnykIssueCache issueCache) {
+ var cacheHashMap = Collections.unmodifiableMap(issueCache.getCacheByDisplayProduct(productTreeNode.getProduct()));
+ for (var kv : cacheHashMap.entrySet()) {
+ var fileName = kv.getKey();
+ var issues = new ArrayList<>(kv.getValue());
+ issues = filterIgnoredIssues(issues);
+ if(issues.isEmpty())
continue;
- FileTreeNode fileNode = new FileTreeNode(filePath);
+ FileTreeNode fileNode = new FileTreeNode(fileName);
toolView.addFileNode(productTreeNode, fileNode);
for (Issue issue : issues) {
toolView.addIssueNode(fileNode, new IssueTreeNode(issue));
@@ -550,8 +547,7 @@ private void populateFileAndIssueNodes(String filePath, Set nod
}
}
- private Collection filterIgnoredIssues(Collection issueList)
- {
+ private ArrayList filterIgnoredIssues(ArrayList issueList) {
final boolean includeIgnoredIssues;
final boolean includeOpenedIssues;
@@ -565,28 +561,31 @@ private Collection filterIgnoredIssues(Collection issueList)
return issueList.stream()
.filter(it -> it.isVisible(includeIgnoredIssues, includeOpenedIssues))
- .toList();
-
+ .collect(Collectors.toCollection(ArrayList::new));
}
-
- private Set populateIssueCache(PublishDiagnostics316Param param, String filePath) {
+
+ private void populateIssueCache(PublishDiagnostics316Param param, String filePath) {
var issueCache = getIssueCache(filePath);
Diagnostic316[] diagnostics = param.getDiagnostics();
if (diagnostics.length == 0) {
issueCache.removeAllIssuesForPath(filePath);
- return Set.of();
+ return;
}
var source = diagnostics[0].getSource();
if (StringUtils.isEmpty(source)) {
- return Set.of();
+ return;
}
var snykProduct = LSP_SOURCE_TO_SCAN_PARAMS.get(source);
List issueList = new ArrayList<>();
-
+ var isIgnoresEnabled = Preferences.getInstance().getBooleanPref(Preferences.IS_GLOBAL_IGNORES_FEATURE_ENABLED);
for (var diagnostic : diagnostics) {
if (diagnostic.getData() == null) {
continue;
}
+ if(!isIgnoresEnabled && diagnostic.getData().isIgnored()) {
+ toggleIgnores(true);
+ isIgnoresEnabled = true;
+ }
issueList.add(diagnostic.getData());
}
@@ -601,7 +600,6 @@ private Set populateIssueCache(PublishDiagnostics316Param param
issueCache.addIacIssues(filePath, issueList);
break;
}
- return getAffectedProductNodes(snykProduct, filePath);
}
public void reportAnalytics(AbstractTask event) {
diff --git a/plugin/src/main/java/io/snyk/languageserver/protocolextension/messageObjects/scanResults/IssueComparator.java b/plugin/src/main/java/io/snyk/languageserver/protocolextension/messageObjects/scanResults/IssueComparator.java
new file mode 100644
index 00000000..7bac6392
--- /dev/null
+++ b/plugin/src/main/java/io/snyk/languageserver/protocolextension/messageObjects/scanResults/IssueComparator.java
@@ -0,0 +1,77 @@
+package io.snyk.languageserver.protocolextension.messageObjects.scanResults;
+
+import java.util.*;
+import io.snyk.eclipse.plugin.domain.ProductConstants;
+
+public class IssueComparator implements Comparator {
+
+ private final Map> issuesGrouped;
+
+ public IssueComparator() {
+ this.issuesGrouped = new HashMap<>();
+ }
+
+ public IssueComparator(Collection issues) {
+ this.issuesGrouped = new HashMap<>();
+ for (Issue issue : issues) {
+ this.issuesGrouped.computeIfAbsent(issue, k -> new ArrayList<>()).add(issue);
+ }
+ }
+
+ @Override
+ public int compare(Issue o1, Issue o2) {
+ Map severityOrder = getSeverityOrderHashMap();
+
+ // Get ranks for the severities of the two issues
+ int rank1 = severityOrder.getOrDefault(o1.severity().toLowerCase(), Integer.MAX_VALUE);
+ int rank2 = severityOrder.getOrDefault(o2.severity().toLowerCase(), Integer.MAX_VALUE);
+
+ // Compare based on severity rank (lower rank = higher severity)
+ int severityComparison = Integer.compare(rank1, rank2);
+ if (severityComparison != 0) {
+ return severityComparison;
+ }
+
+ // Fallback: Compare by issue counts grouped by severity (cascading)
+ int o1Criticals = getCount(o1, ProductConstants.SEVERITY_CRITICAL);
+ int o2Criticals = getCount(o2, ProductConstants.SEVERITY_CRITICAL);
+
+ int o1Highs = getCount(o1, ProductConstants.SEVERITY_HIGH);
+ int o2Highs = getCount(o2, ProductConstants.SEVERITY_HIGH);
+
+ int o1Mediums = getCount(o1, ProductConstants.SEVERITY_MEDIUM);
+ int o2Mediums = getCount(o2, ProductConstants.SEVERITY_MEDIUM);
+
+ int o1Lows = getCount(o1, ProductConstants.SEVERITY_LOW);
+ int o2Lows = getCount(o2, ProductConstants.SEVERITY_LOW);
+
+ if (o1Criticals != o2Criticals) {
+ return Integer.compare(o2Criticals, o1Criticals);
+ } else if (o1Highs != o2Highs) {
+ return Integer.compare(o2Highs, o1Highs);
+ } else if (o1Mediums != o2Mediums) {
+ return Integer.compare(o2Mediums, o1Mediums);
+ } else if (o1Lows != o2Lows) {
+ return Integer.compare(o2Lows, o1Lows);
+ }
+
+ // Fallback to comparing by hash codes if everything else is equal
+ return Integer.compare(o1.hashCode(), o2.hashCode());
+ }
+
+ private int getCount(Issue issue, String severity) {
+ List issuesForType = issuesGrouped.getOrDefault(issue, Collections.emptyList());
+ return (int) issuesForType.stream()
+ .filter(i -> severity.equalsIgnoreCase(i.severity()))
+ .count();
+ }
+
+ private static Map getSeverityOrderHashMap() {
+ Map severityOrder = new HashMap<>();
+ severityOrder.put(ProductConstants.SEVERITY_CRITICAL.toLowerCase(), 1);
+ severityOrder.put(ProductConstants.SEVERITY_HIGH.toLowerCase(), 2);
+ severityOrder.put(ProductConstants.SEVERITY_MEDIUM.toLowerCase(), 3);
+ severityOrder.put(ProductConstants.SEVERITY_LOW.toLowerCase(), 4);
+ return severityOrder;
+ }
+}
diff --git a/plugin/src/main/java/io/snyk/languageserver/protocolextension/messageObjects/scanResults/IssueSorter.java b/plugin/src/main/java/io/snyk/languageserver/protocolextension/messageObjects/scanResults/IssueSorter.java
deleted file mode 100644
index 511d0153..00000000
--- a/plugin/src/main/java/io/snyk/languageserver/protocolextension/messageObjects/scanResults/IssueSorter.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.snyk.languageserver.protocolextension.messageObjects.scanResults;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import io.snyk.eclipse.plugin.domain.ProductConstants;
-
-public class IssueSorter {
- public static List sortIssuesBySeverity(Collection issues) {
- List result = new ArrayList<>(issues);
- Map severityOrder = getSeverityOrderHashMap();
- result.sort((i1, i2) -> {
- Integer rank1 = severityOrder.getOrDefault(i1.severity().toLowerCase(), Integer.MAX_VALUE);
- Integer rank2 = severityOrder.getOrDefault(i2.severity().toLowerCase(), Integer.MAX_VALUE);
- return rank1.compareTo(rank2);
- });
- return result;
- }
-
- private static Map getSeverityOrderHashMap() {
- Map severityOrder = new HashMap<>();
- severityOrder.put(ProductConstants.SEVERITY_CRITICAL, 1);
- severityOrder.put(ProductConstants.SEVERITY_HIGH, 2);
- severityOrder.put(ProductConstants.SEVERITY_MEDIUM, 3);
- severityOrder.put(ProductConstants.SEVERITY_LOW, 4);
- return severityOrder;
- }
-}
diff --git a/tests/src/test/java/io/snyk/eclipse/plugin/html/HtmlProviderFactoryTest.java b/tests/src/test/java/io/snyk/eclipse/plugin/html/HtmlProviderFactoryTest.java
new file mode 100644
index 00000000..5880503c
--- /dev/null
+++ b/tests/src/test/java/io/snyk/eclipse/plugin/html/HtmlProviderFactoryTest.java
@@ -0,0 +1,54 @@
+package io.snyk.eclipse.plugin.html;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+
+import io.snyk.eclipse.plugin.domain.ProductConstants;
+import io.snyk.languageserver.LsBaseTest;
+
+public class HtmlProviderFactoryTest extends LsBaseTest {
+ @Test
+ void htmlProviderFactoryReturnsCorrectType() throws Exception {
+ var cut = HtmlProviderFactory.GetHtmlProvider(ProductConstants.DISPLAYED_CODE_SECURITY);
+ assertTrue(cut instanceof CodeHtmlProvider);
+ cut = HtmlProviderFactory.GetHtmlProvider(ProductConstants.DISPLAYED_CODE_QUALITY);
+ assertTrue(cut instanceof CodeHtmlProvider);
+ cut = HtmlProviderFactory.GetHtmlProvider(ProductConstants.DISPLAYED_OSS);
+ assertTrue(cut instanceof OssHtmlProvider);
+ cut = HtmlProviderFactory.GetHtmlProvider(ProductConstants.DISPLAYED_IAC);
+ assertTrue(cut instanceof IacHtmlProvider);
+ }
+
+ @Test
+ void testHtmlProviderReplacesPlaceholders() throws Exception {
+ var htmlContent = Files.readString(Path.of("src/test/resources/code_issue_description.html"));
+
+ var cut = HtmlProviderFactory.GetHtmlProvider(ProductConstants.DISPLAYED_CODE_SECURITY);
+ htmlContent = cut.replaceCssVariables(htmlContent);
+ assertTrue(!htmlContent.contains("${headerEnd})"));
+ assertTrue(!htmlContent.contains("${nonce})"));
+ assertTrue(!htmlContent.contains("${ideScript})"));
+ assertTrue(!htmlContent.contains("ideNonce"));
+ assertTrue(!htmlContent.contains("var(--text-color)"));
+ assertTrue(!htmlContent.contains("var(----background-color)"));
+ assertTrue(!htmlContent.contains("var(--border-color)"));
+ assertTrue(!htmlContent.contains("var(--link-color)"));
+ assertTrue(!htmlContent.contains("var(--text-color)"));
+ assertTrue(!htmlContent.contains("var(--horizontal-border-color)"));
+ assertTrue(!htmlContent.contains("var(--code-background-color)"));
+ assertTrue(!htmlContent.contains("var(--example-line-removed-color)"));
+ assertTrue(!htmlContent.contains("var(--example-line-added-color)"));
+ }
+
+ @Test
+ void testHtmlProviderGeneratesInitScript() throws Exception {
+ var cut = HtmlProviderFactory.GetHtmlProvider(ProductConstants.DISPLAYED_CODE_SECURITY);
+ var initScript = cut.getInitScript();
+ assertTrue(initScript.contains("window.openInEditor"));
+ assertTrue(initScript.contains("document.body.classList.add(isHighContrast"));
+ }
+}
diff --git a/tests/src/test/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClientTest.java b/tests/src/test/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClientTest.java
index c3cb5efe..bc6ab3e6 100644
--- a/tests/src/test/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClientTest.java
+++ b/tests/src/test/java/io/snyk/languageserver/protocolextension/SnykExtendedLanguageClientTest.java
@@ -11,14 +11,11 @@
import static io.snyk.eclipse.plugin.views.snyktoolview.ISnykToolView.CONGRATS_NO_ISSUES_FOUND;
import static io.snyk.eclipse.plugin.views.snyktoolview.ISnykToolView.getPlural;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
@@ -29,7 +26,6 @@
import java.nio.file.Paths;
import java.util.Collection;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@@ -51,12 +47,8 @@
import org.mockito.MockedStatic;
import org.mockito.Mockito;
-import io.snyk.eclipse.plugin.analytics.AbstractTask;
-import io.snyk.eclipse.plugin.analytics.AnalyticsEventTask;
import io.snyk.eclipse.plugin.analytics.TaskProcessor;
-import io.snyk.eclipse.plugin.properties.preferences.InMemoryPreferenceStore;
import io.snyk.eclipse.plugin.properties.preferences.Preferences;
-import io.snyk.eclipse.plugin.properties.preferences.PreferencesUtils;
import io.snyk.eclipse.plugin.views.snyktoolview.ISnykToolView;
import io.snyk.eclipse.plugin.views.snyktoolview.InfoTreeNode;
import io.snyk.eclipse.plugin.views.snyktoolview.ProductTreeNode;
diff --git a/tests/src/test/resources/code_issue_description.html b/tests/src/test/resources/code_issue_description.html
new file mode 100644
index 00000000..24d1d321
--- /dev/null
+++ b/tests/src/test/resources/code_issue_description.html
@@ -0,0 +1,1411 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ ${ideStyle}
+
+
+
+
+
+
+
+
+
+
+
+
+ Ignore Details
+
+
+
+ Fix Analysis
+
+
+
+ Issue Overview
+
+
+
+
+
+
+
+
+
+
+
+
+
Category
+
Ignored temporarily
+
+
+
+
+
+
Ignored On
+
November 14, 2024
+
+
+
+
Ignored By
+
Abdelrahman Shawki
+
+
+
+
Reason
+
test test test
+
+
+
+ Ignores are currently managed in the Snyk web app.
+ To edit or remove the ignore please go to:
+
https://app.snyk.io .
+
+
+
+
+
+
+
+
+
+ Unsanitized input from the HTTP request body flows into find, where it is used in an NoSQL query. This may result in an NoSQL Injection vulnerability.
+
+
+
+
+
+
+
+
+
+ ⚡ Fix this issue by generating a solution using Snyk DeepCode AI
+
+
+
✨ Generate AI fix
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
1/4 Code Reduction...
+
Reduces the given files to a smaller and relevant code snippet.
+
+
+
+
2/4 Parsing...
+
Analyzing symbols and generating the graph representation.
+
+
+
3/4 Static Analysis...
+
Examining the vulnerability code without having to execute the
+ program.
+
+
+
4/4 Inferencing...
+
Feeding the reduced code to our neural network to obtain the
+ prediction.
+
+
+
+
+
+
+
+
+
+ There are no fix diffs for this issue.
+
+
+
⚡️ Here are AI-generated solutions
+
+
+
+
+
+
+
+
+
+
+
+ AI solution 1 /
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Apply fix
+
+
+
+
+
+ ⚠️ Failed to generate the fix. Please try again.
+
+
+ ✨ Retry AI fix
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+ line:39
+
+ |
+
+ User.find({ username: req.body.username, password: req.body.password }, function (err, users) {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This type of vulnerability was fixed in 30 open source projects.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Example 1 /3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ const user = await User.findOne({ slug: req.params.user }).populate('likes')
+
+
+
+
+ const user = await User.findOne({ _id: req.user._id }).populate('likes')
+
+
+
+
+
+
+
+
+
+
+ Workspace.findOne({ _id: req.params.workspaceId }, function( err, doc ){
+
+
+
+
+ workspaces.findOne({ _id: ObjectId(req.params.workspaceId) }, function( err, doc ){
+
+
+
+
+ resUtils.checkFindOneResponse( err, doc, next, function(){
+
+
+
+
+
+
+
+
+
+ perms.checkPermissions( req, next, 'workspaceConfig/get', req.body, doc, function(){
+
+
+
+
+ sendResponse( res, doc.settings );
+
+
+
+
+ });
+
+
+
+
+ });
+
+
+
+
+ });
+
+
+
+
+
+
+
+
+
+
+ const token = req.query.t
+
+
+
+
+ const token = req.query.t.toString()
+
+
+
+
+ const user = await User.findOne({ token })
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Details
+
+
In an NoSQL injection attack, the user can submit an NoSQL query directly to the database, gaining access without providing appropriate credentials. Attackers can then view, export, modify, and delete confidential information; change passwords and other authentication information; and possibly gain access to other systems within the network. This is one of the most commonly exploited categories of vulnerability, but can largely be avoided through good coding practices.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${ideScript}
+
+
+