fix: try/except in _scan_component, serialize_finding to prevent data injection, DRY LLM template, SUPPORTED_ECOSYSTEMS constant
This commit is contained in:
@@ -13,7 +13,7 @@ from ..constants import (
|
||||
)
|
||||
from ..db.engine import get_session
|
||||
from ..db.models import Finding
|
||||
from ..schemas import FindingsListResponse
|
||||
from ..schemas import FindingsListResponse, serialize_finding
|
||||
|
||||
router = APIRouter(prefix="/api/v1/findings", tags=["findings"])
|
||||
|
||||
@@ -42,14 +42,5 @@ async def list_findings(
|
||||
"total": total,
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"findings": [
|
||||
{
|
||||
"id": f.id,
|
||||
"scan_id": f.scan_id,
|
||||
**f.data,
|
||||
"report": f.report,
|
||||
"created_at": f.created_at.isoformat() if f.created_at else None,
|
||||
}
|
||||
for f in findings
|
||||
],
|
||||
"findings": [serialize_finding(f) for f in findings],
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ from ..core.nexus import parse_package_path
|
||||
from ..db.engine import get_session
|
||||
from ..db.models import Scan
|
||||
from ..db.queries import build_package_list_query
|
||||
from ..schemas import PackageDetailOut, PackageListResponse
|
||||
from ..schemas import PackageDetailOut, PackageListResponse, serialize_finding
|
||||
|
||||
router = APIRouter(prefix="/api/v1/packages", tags=["packages"])
|
||||
|
||||
@@ -145,7 +145,7 @@ async def get_package(
|
||||
all_findings: list[dict] = []
|
||||
for s in scans:
|
||||
for f in s.findings:
|
||||
all_findings.append({"id": f.id, **f.data, "report": f.report})
|
||||
all_findings.append(serialize_finding(f))
|
||||
|
||||
return {
|
||||
"name": scans[0].package_name,
|
||||
|
||||
@@ -19,7 +19,7 @@ from ..constants import (
|
||||
from ..db.engine import get_session
|
||||
from ..db.models import Scan
|
||||
from ..db.queries import build_scan_list_query, get_dashboard_stats
|
||||
from ..schemas import ScanDetailOut, ScanListResponse, StatsResponse
|
||||
from ..schemas import ScanDetailOut, ScanListResponse, StatsResponse, serialize_finding
|
||||
|
||||
router = APIRouter(prefix="/api/v1/scans", tags=["scans"])
|
||||
|
||||
@@ -171,5 +171,5 @@ async def get_scan(scan_id: int, session: AsyncSession = Depends(get_session)) -
|
||||
"error_message": scan.error_message,
|
||||
"initiator": scan.initiator,
|
||||
"source_ip": scan.source_ip,
|
||||
"findings": [{"id": f.id, **f.data, "report": f.report} for f in scan.findings],
|
||||
"findings": [serialize_finding(f) for f in scan.findings],
|
||||
}
|
||||
|
||||
@@ -159,40 +159,45 @@ async def nexus_webhook(
|
||||
|
||||
|
||||
async def _scan_component(repository: str, name: str, version: str, ecosystem: str):
|
||||
from ..core.nexus import nexus_get
|
||||
|
||||
params = urlencode(
|
||||
{
|
||||
"repository": repository,
|
||||
"name": name,
|
||||
"version": version,
|
||||
"format": ecosystem,
|
||||
}
|
||||
)
|
||||
api_path = f"/service/rest/v1/search?{params}"
|
||||
try:
|
||||
resp = await nexus_get(api_path)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
from ..core.nexus import nexus_get
|
||||
|
||||
params = urlencode(
|
||||
{
|
||||
"repository": repository,
|
||||
"name": name,
|
||||
"version": version,
|
||||
"format": ecosystem,
|
||||
}
|
||||
)
|
||||
api_path = f"/service/rest/v1/search?{params}"
|
||||
try:
|
||||
resp = await nexus_get(api_path)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
except Exception as e:
|
||||
log.warning("Component lookup error for %s==%s: %s", name, version, e)
|
||||
return
|
||||
|
||||
items = data.get("items", [])
|
||||
if not items:
|
||||
log.warning("No items found in search for %s==%s", name, version)
|
||||
return
|
||||
|
||||
for item in items:
|
||||
for asset in item.get("assets", []):
|
||||
asset_path = _extract_asset_path(asset)
|
||||
if not asset_path or not _is_package_asset(asset_path):
|
||||
continue
|
||||
download_url = asset.get("downloadUrl") or _build_download_url(
|
||||
repository, asset_path
|
||||
)
|
||||
log.info("Scanning component asset: %s", asset_path)
|
||||
async for session in get_session():
|
||||
await harvest(download_url, repository, ecosystem, asset_path, session)
|
||||
break
|
||||
except Exception as e:
|
||||
log.warning("Component lookup error for %s==%s: %s", name, version, e)
|
||||
return
|
||||
|
||||
items = data.get("items", [])
|
||||
if not items:
|
||||
log.warning("No items found in search for %s==%s", name, version)
|
||||
return
|
||||
|
||||
for item in items:
|
||||
for asset in item.get("assets", []):
|
||||
asset_path = _extract_asset_path(asset)
|
||||
if not asset_path or not _is_package_asset(asset_path):
|
||||
continue
|
||||
download_url = asset.get("downloadUrl") or _build_download_url(repository, asset_path)
|
||||
log.info("Scanning component asset: %s", asset_path)
|
||||
async for session in get_session():
|
||||
await harvest(download_url, repository, ecosystem, asset_path, session)
|
||||
break
|
||||
log.error("Component scan failed for %s==%s: %s", name, version, e)
|
||||
|
||||
|
||||
async def _scan_in_background(
|
||||
|
||||
Reference in New Issue
Block a user