ossf / scorecard

OpenSSF Scorecard - Security health metrics for Open Source
https://scorecard.dev
Apache License 2.0
4.52k stars 494 forks source link

BUG (?): JSON output omits checks' `"score": 0` #2432

Closed pnacht closed 1 year ago

pnacht commented 1 year ago

Describe the bug JSON output visibie in api.securityscorecards.dev/projects/[...] omits "score": 0 from checks.

Reproduction steps For example, see numpy's scores:

      {
        "name": "CII-Best-Practices",
        "reason": "no badge detected",
        "details": null,
        "documentation": { ... },
      },
      # ...
      {
        "name": "Pinned-Dependencies",
        "reason": "dependency not pinned by hash detected -- score normalized to 0",
        "details": [ ... ],
        "documentation": { ... },
      },
      {
        "name": "SAST",
        "reason": "SAST tool is not run on all commits -- score normalized to 0",
        "details": [ ... ],
        "documentation": { ... },
      },
      {
        "name": "Signed-Releases",
        "reason": "0 out of 5 artifacts are signed or have provenance",
        "details": [ ... ],
        "documentation": { ... },
      },

Some of these define the score within reason, but the actual score value is missing.

Similar behavior with pandas:

      {
        "name": "CII-Best-Practices",
        "reason": "no badge detected",
        "details": null,
        "documentation": { ... },
      },
      # ...
      {
        "name": "Dependency-Update-Tool",
        "reason": "no update tool detected",
        "details": [ ... ],
        "documentation": { ... },
      },
      # ...
      {
        "name": "Pinned-Dependencies",
        "reason": "dependency not pinned by hash detected -- score normalized to 0",
        "details": [ ... ],
        "documentation": { ... },
      },
      # ...
      {
        "name": "Signed-Releases",
        "reason": "0 out of 5 artifacts are signed or have provenance",
        "details": [ ... ],
        "documentation": { ... },
      },

CII-Best-Practices, Dependency-Update-Tool, Pinned-Dependencies, Signed-Releases and Token-Permissions checks.

Those two packages have the scorecard-action enabled, but others without it have the same behavior.

NixOS/nixpgs:

      {
        "name": "CII-Best-Practices",
        "reason": "no badge detected",
        "details": null,
        "documentation": { ... },
      },
      # ...
      {
        "name": "Dangerous-Workflow",
        "reason": "dangerous workflow patterns detected",
        "details": [ ... ],
        "documentation": { ... },
      },
      # ...
      {
        "name": "Fuzzing",
        "reason": "project is not fuzzed",
        "details": null,
        "documentation": { ... },
      },

ansible:

      {
        "name": "Security-Policy",
        "reason": "security policy file not detected",
        "details": null,
        "documentation": { ... },
      },
      # ...
      {
        "name": "SAST",
        "reason": "SAST tool is not run on all commits -- score normalized to 0",
        "details": [ ... ],
        "documentation": { ... },
      },
      {
        "name": "Dependency-Update-Tool",
        "reason": "no update tool detected",
        "details": [ ... ],
        "documentation": { ... },
      },

In all cases, the checks would have resulted in a 0-score. And the JSON includes no "score": 0 checks. Basically, if the score is zero, it's omitted.

Is this a feature, not a bug?

Expected behavior All checks to include a score value, even if it's zero, to improve legibility and possible automation.

spencerschrock commented 1 year ago

I believe this is a bug with the API code. The JSON output when run from the scorecard binary looks good to me.

I'm guessing it's this line https://github.com/ossf/scorecard-webapp/blob/d26d8e627ebe31052b2c1353fa19d62f52a43839/app/generated/models/scorecard_check.go#L40.

which is generated code, so the real culprit would be https://github.com/ossf/scorecard-webapp/blob/main/openapi.yaml#L203. And we can get rid of the omitempty with x-omitempty: "true|false: force the omitempty modifier in struct json and xml tags"