Skip to content

Commit 5833f5a

Browse files
author
Orlando Barrera II
committed
Testing the sarif file parsing
1 parent 389a970 commit 5833f5a

File tree

1 file changed

+49
-54
lines changed

1 file changed

+49
-54
lines changed

socketsecurity/core/messages.py

Lines changed: 49 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,13 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
4141
Supports:
4242
1) JSON-based manifest files (package-lock.json, Pipfile.lock, composer.lock)
4343
- Locates a dictionary entry with the matching package & version
44-
- Does a rough line-based search (by matching the key) in the raw text
44+
- Searches the raw text for the key
4545
2) Text-based (requirements.txt, package.json, yarn.lock, etc.)
46-
- Uses compiled regex patterns to detect a match line by line
46+
- Uses regex patterns to detect a match line by line
4747
"""
4848
file_type = Path(manifest_file).name
4949
logging.debug("Processing file for line lookup: %s", manifest_file)
5050

51-
# ----------------------------------------------------
52-
# 1) JSON-based manifest files
53-
# ----------------------------------------------------
5451
if file_type in ["package-lock.json", "Pipfile.lock", "composer.lock"]:
5552
try:
5653
with open(manifest_file, "r", encoding="utf-8") as f:
@@ -67,21 +64,19 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
6764
found_key = None
6865
found_info = None
6966
for key, value in packages_dict.items():
70-
# For NPM package-lock, keys might look like "node_modules/axios"
7167
if key.endswith(packagename) and "version" in value:
7268
if value["version"] == packageversion:
7369
found_key = key
7470
found_info = value
7571
break
7672

7773
if found_key and found_info:
78-
# Only use the found key to locate the line
7974
needle_key = f'"{found_key}":'
8075
lines = raw_text.splitlines()
8176
logging.debug("Total lines in %s: %d", manifest_file, len(lines))
8277
for i, line in enumerate(lines, start=1):
8378
if needle_key in line:
84-
logging.debug("Match found at line %d in %s: %s", i, manifest_file, line.strip())
79+
logging.debug("Found match at line %d in %s: %s", i, manifest_file, line.strip())
8580
return i, line.strip()
8681
return 1, f'"{found_key}": {found_info}'
8782
else:
@@ -90,9 +85,7 @@ def find_line_in_file(packagename: str, packageversion: str, manifest_file: str)
9085
logging.error("Error reading %s: %s", manifest_file, e)
9186
return 1, f"Error reading {manifest_file}"
9287

93-
# ----------------------------------------------------
94-
# 2) Text-based / line-based manifests
95-
# ----------------------------------------------------
88+
# Text-based manifests
9689
search_patterns = {
9790
"package.json": rf'"{packagename}":\s*"[\^~]?{re.escape(packageversion)}"',
9891
"yarn.lock": rf'{packagename}@{packageversion}',
@@ -174,7 +167,8 @@ def create_security_comment_sarif(diff) -> dict:
174167
175168
This function now:
176169
- Accepts multiple manifest files from alert.introduced_by or alert.manifests.
177-
- Generates one SARIF location per manifest file.
170+
- Generates an individual SARIF result for each manifest file.
171+
- Appends the manifest file name to the alert name to make each result unique.
178172
- Does NOT fall back to 'requirements.txt' if no manifest file is provided.
179173
- Adds detailed logging to validate our assumptions.
180174
"""
@@ -204,11 +198,11 @@ def create_security_comment_sarif(diff) -> dict:
204198
for alert in diff.new_alerts:
205199
pkg_name = alert.pkg_name
206200
pkg_version = alert.pkg_version
207-
rule_id = f"{pkg_name}=={pkg_version}"
201+
base_rule_id = f"{pkg_name}=={pkg_version}"
208202
severity = alert.severity
209203

210204
# Log raw alert data for manifest extraction.
211-
logging.debug("Alert %s - introduced_by: %s, manifests: %s", rule_id, alert.introduced_by, getattr(alert, 'manifests', None))
205+
logging.debug("Alert %s - introduced_by: %s, manifests: %s", base_rule_id, alert.introduced_by, getattr(alert, 'manifests', None))
212206

213207
manifest_files = []
214208
if alert.introduced_by and isinstance(alert.introduced_by, list):
@@ -221,56 +215,57 @@ def create_security_comment_sarif(diff) -> dict:
221215
elif hasattr(alert, 'manifests') and alert.manifests:
222216
manifest_files = [mf.strip() for mf in alert.manifests.split(";") if mf.strip()]
223217

224-
logging.debug("Alert %s - extracted manifest_files: %s", rule_id, manifest_files)
225-
218+
logging.debug("Alert %s - extracted manifest_files: %s", base_rule_id, manifest_files)
226219
if not manifest_files:
227-
logging.error("Alert %s: No manifest file found; cannot determine file location.", rule_id)
220+
logging.error("Alert %s: No manifest file found; cannot determine file location.", base_rule_id)
228221
continue
229222

230-
logging.debug("Alert %s - using manifest_files for processing: %s", rule_id, manifest_files)
231-
# Use the first manifest for URL generation.
232-
logging.debug("Alert %s - Using file for URL generation: %s", rule_id, manifest_files[0])
233-
socket_url = Messages.get_manifest_type_url(manifest_files[0], pkg_name, pkg_version)
234-
short_desc = (f"{alert.props.get('note', '')}<br/><br/>Suggested Action:<br/>{alert.suggestion}"
235-
f"<br/><a href=\"{socket_url}\">{socket_url}</a>")
236-
full_desc = "{} - {}".format(alert.title, alert.description.replace('\r\n', '<br/>'))
237-
238-
if rule_id not in rules_map:
239-
rules_map[rule_id] = {
240-
"id": rule_id,
241-
"name": f"{pkg_name}=={pkg_version}",
242-
"shortDescription": {"text": f"Alert generated for {rule_id} by Socket Security"},
243-
"fullDescription": {"text": full_desc},
244-
"helpUri": socket_url,
245-
"defaultConfiguration": {
246-
"level": Messages.map_severity_to_sarif(severity)
247-
},
248-
}
223+
logging.debug("Alert %s - using manifest_files for processing: %s", base_rule_id, manifest_files)
249224

250-
# Create a SARIF location for each manifest file.
251-
locations = []
225+
# For each manifest file, create an individual SARIF result.
252226
for mf in manifest_files:
253-
logging.debug("Alert %s - Processing manifest file: %s", rule_id, mf)
227+
logging.debug("Alert %s - Processing manifest file: %s", base_rule_id, mf)
228+
socket_url = Messages.get_manifest_type_url(mf, pkg_name, pkg_version)
254229
line_number, line_content = Messages.find_line_in_file(pkg_name, pkg_version, mf)
255230
if line_number < 1:
256231
line_number = 1
257-
logging.debug("Alert %s: Manifest %s, line %d: %s", rule_id, mf, line_number, line_content)
258-
locations.append({
259-
"physicalLocation": {
260-
"artifactLocation": {"uri": mf},
261-
"region": {
262-
"startLine": line_number,
263-
"snippet": {"text": line_content},
232+
logging.debug("Alert %s: Manifest %s, line %d: %s", base_rule_id, mf, line_number, line_content)
233+
234+
# Create a unique rule id and name by appending the file prefix.
235+
unique_rule_id = f"{base_rule_id} ({mf})"
236+
rule_name = unique_rule_id
237+
238+
short_desc = (f"{alert.props.get('note', '')}<br/><br/>Suggested Action:<br/>{alert.suggestion}"
239+
f"<br/><a href=\"{socket_url}\">{socket_url}</a>")
240+
full_desc = "{} - {}".format(alert.title, alert.description.replace('\r\n', '<br/>'))
241+
242+
# Add the rule if not already defined.
243+
if unique_rule_id not in rules_map:
244+
rules_map[unique_rule_id] = {
245+
"id": unique_rule_id,
246+
"name": rule_name,
247+
"shortDescription": {"text": f"Alert generated for {unique_rule_id} by Socket Security"},
248+
"fullDescription": {"text": full_desc},
249+
"helpUri": socket_url,
250+
"defaultConfiguration": {
251+
"level": Messages.map_severity_to_sarif(severity)
264252
},
265253
}
266-
})
267-
268-
result_obj = {
269-
"ruleId": rule_id,
270-
"message": {"text": short_desc},
271-
"locations": locations,
272-
}
273-
results_list.append(result_obj)
254+
255+
result_obj = {
256+
"ruleId": unique_rule_id,
257+
"message": {"text": short_desc},
258+
"locations": [{
259+
"physicalLocation": {
260+
"artifactLocation": {"uri": mf},
261+
"region": {
262+
"startLine": line_number,
263+
"snippet": {"text": line_content},
264+
},
265+
}
266+
}]
267+
}
268+
results_list.append(result_obj)
274269

275270
sarif_data["runs"][0]["tool"]["driver"]["rules"] = list(rules_map.values())
276271
sarif_data["runs"][0]["results"] = results_list

0 commit comments

Comments
 (0)