Skip to content

Bug: dep-scan server mode doesn't work properly #444

@WantDead

Description

@WantDead

Expected Behavior

The dep-scan server mode should successfully process scans either from a GitHub repository URL (via cdxgen) or from an uploaded SBOM file (in CycloneDX format). A valid response with vulnerability findings or confirmation of no issues is expected

Actual Behavior

All attempts to scan either a remote GitHub repository or a local SBOM file return an error response:

{
  "error": "true",
  "message": "Unable to generate SBOM. Check your input path or url."
}

Even pre-generated and valid SBOMs (e.g., from the official CycloneDX examples) trigger the same error. The logs show the SBOM is processed, but the internal package list appears to be empty, causing the scan to fail with HTTP 500.

Steps to Reproduce

Environment:

dep-scan version: v6.0.0b3
Environment: Docker Compose
Host OS: Debian (VM) / MacOS (tried both)
Server exposed at: http://0.0.0.0:7070
cdxgen also running at http://cdxgen:9090

Scenario 1: Remote GitHub repo scan

Start the server:

docker-compose up -d

Submit repo for scanning:

curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan

Observe the server response:

{
  "error": "true",
  "message": "Unable to generate SBOM. Check your input path or url."
}

Logs show:

DEBUG    Invoking cdxgen server at http://cdxgen:9090/sbom
INFO     The cdxgen invocation was unsuccessful. Try generating the BOM separately.
DEBUG    Unable to generate SBOM via cdxgen server due to 500

Scenario 2: Scanning a local SBOM

Generate SBOM manually with cdxgen:

curl "http://127.0.0.1:9090/sbom?url=https://github.com/HooliCorp/vulnerable-aws-koa-app.git&multiProject=true&type=js" > sbom.json

Upload the SBOM to dep-scan:

curl -X POST -H 'Content-Type: multipart/form-data' -F 'file=@sbom.json' "http://0.0.0.0:7070/scan?type=js"

Server response is again:

{
  "error": "true",
  "message": "Unable to generate SBOM. Check your input path or url."
}

Logs show:

DEBUG    Processing uploaded file
DEBUG    Scanning 292 oss dependencies for issues
DEBUG    The package list was empty.

Scenario 3: SBOM from CycloneDX examples

Upload a known-valid SBOM (e.g. keycloak-10.0.2/bom.json from https://github.com/CycloneDX/bom-examples).
Same error and server log:

DEBUG    Scanning 903 oss dependencies for issues
DEBUG    The package list was empty.

Additional Information

The issue occurs consistently across both repo-based and file-based scan workflows.
The SBOMs being submitted are structurally valid JSON documents.

Might be a regression or configuration issue in how SBOM parsing is handled in server mode, or how it is transmitted to the cdxgen side.

I added additional logging to the dep-scan code for testing

cdxgen.py

class CdxgenServerGenerator(CdxgenGenerator):
    """
    cdxgen generator that uses a local cdxgen server for execution.
    """

    def generate(self) -> 'BOMResult':
        """
        Generate the BOM with the cdxgen server.
        """
        options = self.options
        cdxgen_server = self.options.get("cdxgen_server")
        if not cdxgen_server:
            return BOMResult(
                success=False,
                command_output="Pass the `--cdxgen-server` argument to use the cdxgen server for BOM generation.",
            )

        project_type_list = self.options.get("project_type", [])
        src_dir = self.source_dir or self.options.get("path")

        # Prepare the request details
        sbom_path = "/sbom"
        payload = {
            **options,
            "url": options.get("url", ""),
            "path": src_dir,
            "type": ",".join(project_type_list),
            "multiProject": options.get("multiProject", ""),
        }

        with httpx.Client(http2=True, base_url=cdxgen_server, timeout=180) as client:
            if self.logger:
                # 🪵 Log what is being sent to the server
                self.logger.debug("--- cdxgen server request ---")
                self.logger.debug("POST: %s%s", cdxgen_server, sbom_path)
                # Use json.dumps for pretty-printing the request details
                self.logger.debug("Headers: %s", json.dumps(cdxgen_server_headers, indent=2))
                self.logger.debug("Payload: %s", json.dumps(payload, indent=2))
                self.logger.debug("-----------------------------")

            try:
                r = client.post(sbom_path, json=payload, headers=cdxgen_server_headers)

                if self.logger:
                    # 🪵 Log the full response from the server, regardless of status code
                    self.logger.debug("--- cdxgen server response ---")
                    self.logger.debug("Status Code: %d", r.status_code)
                    # Log the first 500 characters of the response to avoid flooding logs
                    self.logger.debug("Response Body: %s", r.text[:500])
                    self.logger.debug("------------------------------")

                if r.status_code == httpx.codes.OK:
                    try:
                        json_response = r.json()
                        if json_response:
                            with open(self.bom_file, "w", encoding="utf-8") as fp:
                                json.dump(json_response, fp, indent=2)
                            self.logger.debug("✅ Successfully generated SBOM via server and saved to %s", self.bom_file)
                            return BOMResult(success=os.path.exists(self.bom_file))
                        else:
                            return BOMResult(
                                success=False,
                                command_output="cdxgen server returned a successful but empty response.",
                            )
                    except json.JSONDecodeError as je:
                        # 🪵 Log specific JSON parsing errors
                        if self.logger:
                            self.logger.error("🚨 Failed to decode JSON response from cdxgen server.")
                            self.logger.error("JSONDecodeError: %s", str(je))
                            self.logger.error("Raw response that caused error:\n%s", r.text)
                        return BOMResult(
                            success=False,
                            command_output=f"Unable to parse SBOM JSON from cdxgen server: {str(je)}",
                        )
                else:
                    # 🪵 Log the detailed error from the response body for non-200 responses
                    error_message = f"cdxgen server failed with status code {r.status_code}. Response: {r.text}"
                    if self.logger:
                        self.logger.error("🚨 %s", error_message)
                    return BOMResult(success=False, command_output=error_message)

            except Exception as e:
                if self.logger:
                    # 🪵 Log the full exception traceback for connection errors, timeouts, etc.
                    self.logger.error("🚨 An unexpected exception occurred while contacting the cdxgen server.")
                    self.logger.error(traceback.format_exc())

        # This is the final fallback return, the logs will now contain the specific error
        return BOMResult(
            success=False,
            command_output="Unable to generate SBOM with cdxgen server. Check logs for details. Trying to generate one locally.",
        )

and then tried to send the repository for scanning as before

curl --json '{"url": "https://github.com/HooliCorp/vulnerable-aws-koa-app", "type": "js"}' http://0.0.0.0:7070/scan

dep-scan server logs:

│ [17:27:11] DEBUG    --- cdxgen server request ---                                                                                                                                                │
│            DEBUG    POST: http://cdxgen:9090/sbom                                                                                                                                    │
│            DEBUG    Headers: {                                                                                                                                                                   │
│                       "Content-Type": "application/json",                                                                                                                                        │
│                       "Accept-Encoding": "gzip"                                                                                                                                                  │
│                     }                                                                                                                                                                            │
│            DEBUG    Payload: {                                                                                                                                                                   │
│                       "url":                                                                                                                                                                     │
│                     "https://github.com/HooliCorp/vulnerable-aws-koa-app",                                                                                                                       │
│                       "path": null,                                                                                                                                                              │
│                       "project_type": [                                                                                                                                                          │
│                         "'js'"                                                                                                                                                                   │
│                       [],                                                                                                                                                                        │
│                       "multiProject": null,                                                                                                                                                      │
│                       "cdxgen_server": "http://cdxgen:9090",                                                                                                                         │
│                       "profile": "generic",                                                                                                                                                      │
│                       "deep": false,                                                                                                                                                             │
│                       "type": "'js'"                                                                                                                                                             │
│                     }                                                                                                                                                                            │
│            DEBUG    -----------------------------                                                                                                                                                │
│            DEBUG    --- cdxgen server response ---                                                                                                                                               │
│            DEBUG    Status Code: 500                                                                                                                                                             │
│            DEBUG    Response Body: {"error":"TypeError: Invalid value type:                                                                                                                      │
│                     object.","details":"Options can only be of string, number,                                                                                                                   │
│                     and array type. No object values are allowed."}                                                                                                                              │
│            DEBUG    ------------------------------                                                                                                                                               │
│            ERROR    🚨 cdxgen server failed with status code 500. Response:                                                                                                                      │
│                     {"error":"TypeError: Invalid value type:                                                                                                                                     │
│                     object.","details":"Options can only be of string, number,                                                                                                                   │
│                     and array type. No object values are allowed."}                                                                                                                              │
│            INFO     The cdxgen invocation was unsuccessful. Try generating the                                                                                                                   │
│                     BOM separately.                                                                                                                                                              │
│            DEBUG    cdxgen server failed with status code 500. Response:                                                                                                                         │
│                     {"error":"TypeError: Invalid value type:                                                                                                                                     │
│                     object.","details":"Options can only be of string, number,                                                                                                                   │
│                     and array type. No object values are allowed."} 

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions