Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #9972 (Add support for SARIF output format) #6863

Merged
merged 10 commits into from
Oct 10, 2024

Conversation

danmar
Copy link
Owner

@danmar danmar commented Oct 5, 2024

No description provided.

@danmar
Copy link
Owner Author

danmar commented Oct 5, 2024

There is no testing yet. I will see if I can integrate it into github.

@danmar
Copy link
Owner Author

danmar commented Oct 5, 2024

@mario-campos would you be interested to test/review this Cppcheck SARIF output?

cli/cmdlineparser.cpp Outdated Show resolved Hide resolved
@firewave
Copy link
Collaborator

firewave commented Oct 5, 2024

See #4651 and #3365.

cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
@danmar
Copy link
Owner Author

danmar commented Oct 5, 2024

See 4651 and 3365.

4651: very related but this is a simpler approach.

3365: I don't think this is related to the uniq/append output.

@danmar
Copy link
Owner Author

danmar commented Oct 5, 2024

I believe that we can output findings directly btw. We don't have to construct the complete report at the end. However I am not sure if that will be very useful anyway, the report is so verbose I don't think anybody would like to read the sarif output "live".

I believe a minimal SARIF header would be:

{
  "runs": [
    {
      "results": [

@danmar danmar force-pushed the fix-9972-2 branch 2 times, most recently from a9065ff to a798d28 Compare October 6, 2024 14:36
@github-advanced-security
Copy link

This pull request sets up GitHub code scanning for this repository. Once the scans have completed and the checks have passed, the analysis results for this pull request branch will appear on this overview. Once you merge this pull request, the 'Security' tab will show more code scanning analysis results (for example, for the default branch). Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results. For more information about GitHub code scanning, check out the documentation.

@@ -0,0 +1,6 @@

void foo(int x) {
if (x >= 0 || x <= 10) {}

Check warning

Code scanning / Cppcheck

Logical disjunction always evaluates to true: x >= 0 || x <= 10.

Logical disjunction always evaluates to true: x >= 0 || x <= 10.
@danmar
Copy link
Owner Author

danmar commented Oct 6, 2024

There is an experimental SARIF upload here:
#6866

@mario-campos
Copy link
Contributor

@danmar, sure. I can take a look at it later today.

Copy link
Contributor

@mario-campos mario-campos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!! Can't wait to see this merged!

I left a few comments about some missing SARIF properties, which GitHub requires. I think it would be a good idea to implement them, because I think someone will eventually try to upload the SARIF file to GitHub expecting it to work.

Comment on lines 81 to 115
picojson::array serializeRules() const {
picojson::array ret;
std::set<std::string> ruleIds;
for (const auto& finding : mFindings) {
if (ruleIds.insert(finding.id).second) {
picojson::object rule;
rule["id"] = picojson::value(finding.id);
picojson::object shortDescription;
shortDescription["text"] = picojson::value(finding.shortMessage());
rule["shortDescription"] = picojson::value(shortDescription);
ret.emplace_back(rule);
}
}
return ret;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serializeRules() does not serialize the rule's fullDescription.text nor its help.text, which are both required*. See reportingDescriptor object specification.

Also, while not required, it would be nice to see the severity (properties.problem.severity) implemented as well.

* These properties are required by GitHub's Code scanning platform, not necessarily the SARIF specification.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Comment on lines 115 to 157
picojson::array serializeResults() const {
picojson::array results;
for (const auto& finding : mFindings) {
picojson::object res;
res["level"] = picojson::value(sarifLevel(finding.severity));
if (!finding.callStack.empty())
res["locations"] = picojson::value(serializeLocations(finding));
picojson::object message;
message["text"] = picojson::value(finding.shortMessage());
res["message"] = picojson::value(message);
res["ruleId"] = picojson::value(finding.id);
results.emplace_back(res);
}
return results;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does not implement the required* partialFingerprints property, which is used to prevent creating duplicate alerts for the same vulnerability/finding. See result object specification.

* These properties are required by GitHub's Code scanning platform, not necessarily the SARIF specification.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the locations property is required (by GitHub), so maybe consider hoisting up the if (!finding.callStack.empty()) condition to the for loop, so that if there are no locations, the alert is not serialized.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Comment on lines 104 to 129
picojson::object region;
region["startLine"] = picojson::value(static_cast<int64_t>(location.line));
region["startColumn"] = picojson::value(static_cast<int64_t>(location.column));
physicalLocation["region"] = picojson::value(region);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing required* properties region.endLine and region.endColumn. See physicalLocation object specification.

* These properties are required by GitHub's Code scanning platform, not necessarily the SARIF specification.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
@danmar
Copy link
Owner Author

danmar commented Oct 9, 2024

@mario-campos thanks for the comments. Can you please check again?

Example output:

{
  "$schema": "https:\/\/docs.oasis-open.org\/sarif\/sarif\/v2.1.0\/errata01\/os\/schemas\/sarif-schema-2.1.0.json",
  "runs": [
    {
      "results": [
        {
          "level": "warning",
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "1.c"
                },
                "region": {
                  "endColumn": 4,
                  "endLine": 1,
                  "startColumn": 4,
                  "startLine": 1
                }
              }
            }
          ],
          "message": {
            "text": "Division by zero."
          },
          "partialFingerprints": {
            "hash": "4df90040e1961f0f"
          },
          "ruleId": "zerodiv"
        }
      ],
      "tool": {
        "driver": {
          "informationUri": "https:\/\/cppcheck.sourceforge.io",
          "name": "Cppcheck Premium",
          "rules": [
            {
              "fullDescription": {
                "text": "Division by zero."
              },
              "help": {
                "text": "Division by zero."
              },
              "id": "zerodiv",
              "properties": {
                "precision": "high",
                "problem": {
                  "severity": "warning"
                }
              },
              "shortDescription": {
                "text": "Division by zero."
              }
            }
          ],
          "version": "24.9.0"
        }
      }
    }
  ],
  "version": "2.1.0"
}

@danmar
Copy link
Owner Author

danmar commented Oct 9, 2024

@mario-campos please take an extra careful look on the partialFingerprints , I am very unsure what that should be.

Copy link
Contributor

@mario-campos mario-campos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job! A few more finishing touches.

Also, you can validate the SARIF file at https://sarifweb.azurewebsites.net/. I've already submitted it and there's a few "issues" but I wouldn't worry about them. According to the docs, they're not required.

cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
cli/cppcheckexecutor.cpp Show resolved Hide resolved
cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
cli/cppcheckexecutor.cpp Outdated Show resolved Hide resolved
@danmar danmar merged commit c49b941 into danmar:main Oct 10, 2024
63 checks passed
@danmar
Copy link
Owner Author

danmar commented Oct 10, 2024

@mario-campos I merged it now. but please feel free to provide additional advice if there is something we can fix..

@danmar danmar deleted the fix-9972-2 branch October 10, 2024 20:12
ludviggunne pushed a commit to ludviggunne/cppcheck that referenced this pull request Oct 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants