SARIF Tools

repository·main·Indexed 41 days ago

https://github.com/microsoft/sarif-tools

A set of command line tools and a Python library (version 3.0.5) for working with Static Analysis Results Interchange Format (SARIF) files. It provides capabilities to load, analyze, filter, and consolidate SARIF data, as well as augment files with git blame information and enforce quality gates in CI pipelines using the --check flag.

Tokens
5.5K
Snippets
25
Records
29
Agent score
50%

What's inside SARIF Tools

  1. Understand the three levels of SARIF data abstraction

    main

    When working with SarifFileSet, SarifFile, or SarifRun, data is presented at three levels of aggregation:

    1. Results: Raw dicts deserialized directly from the SARIF JSON Result objects (per SARIF standard section 3.27).
    2. Records: Flat dicts containing sarif_file.BASIC_RECORD_ATTRIBUTES. This is ideal for machine-readable formats like CSV. Attributes include:
      • Tool: Tool name.
      • Severity: error, warning (default), note, or none.
      • Code: Issue code.
      • Description: Issue name.
      • Location: File location.
      • Line: Line number (string, defaults to "1").
    3. Reports: IssuesReport objects. These group and sort records to provide structured, human-readable data (e.g., for Word or HTML).
  2. Understand SARIF format expectations in SARIF Tools

    main

    SARIF Tools processes SARIF files by looking at specific key components. While the tool applies some 'fudging' to handle mildly divergent implementations, it expects the following standard elements:

    • Severity: Should be one of error, warning, note, or none.
    • Code and Message: Issue types should have a short code and a short name (referred to as message in the SARIF standard, but often called description within SARIF Tools).
    • Location: A specific location for the issue, typically a file path and line number.

    If the tool produces incorrect results for a specific static analysis tool, it may be due to non-standard representations (e.g., putting real severity in custom properties or embedding location info inside the message). In such cases, you may need to pre-process the SARIF output before passing it to SARIF Tools.

  3. Install SARIF Tools via pip

    main

    SARIF Tools can be installed using pip. Ensure you have Python 3.8 or later installed. The installation creates a sarif (or sarif.exe on Windows) executable in your Python Scripts directory.

    Windows Installation

    Open a user command prompt and run:

    pip install sarif-tools

    If you see a warning that the script is not on PATH, add the Python Scripts directory to your environment variables via Windows Settings.

    Linux or Mac Installation

    Run:

    pip install sarif-tools

    If you see a warning that the script is not on PATH, add the installation directory (e.g., ~/.local/bin) to your PATH by editing ~/.profile and running source ~/.profile.

    Note: Installing system-wide using sudo pip install (Linux) or an Administrator command prompt (Windows) is possible but discouraged for security reasons.

  4. Filter SARIF results using a YAML filter-list

    main

    Various commands in sarif-tools support the --filter option, which allows you to include or exclude specific SARIF result objects based on patterns and substrings.

    To use filtering, create a YAML file containing include and/or exclude rules and pass its path to the --filter flag.

    Filtering Logic

    • If no include patterns are provided: All issues are included by default, except those matching the exclude patterns.
    • If include patterns are provided: Only issues matching the inclusion patterns are included.
    • Exclusion priority: If an issue matches an inclusion pattern but also matches an exclusion pattern, it is excluded.
    • Rule Logic:
      • Items in the include list are treated with an OR operator (matching any rule includes the result).
      • A single item can be a list of rules; if so, those rules are treated with an AND operator (all rules in that list must match).

    Configuration Options

    You can define a configuration section to override defaults:

    • default-include (boolean): Controls whether to include results where a property to check is missing. Default is true.
    • check-line-number (boolean): If true, filter criteria are only applied if the line number is present and not equal to 1. This is useful for avoiding false positives in blame filtering where tools set line 1 for whole-file issues. Default is true.
    # Example command usage
    sarif-tool-command --filter my-filter.yaml input.sarif
  5. Use sarif-tools as a Python library

    main

    You can use sarif-tools within Python scripts to load and analyze SARIF data. Use sarif.loader to load files into SarifFile or SarifFileSet objects, which provide methods to explore results, records, and reports.

    Common workflow:

    1. Load data using loader.load_sarif_file(path).
    2. Access raw results via .get_results().
    3. Access flattened records (useful for CSV) via .get_records().
    4. Access structured reports via .get_report().
    from sarif import loader
    
    # Load a SARIF file
    sarif_data = loader.load_sarif_file('path_to_sarif_file')
    
    # Get a report object for human-readable analysis
    report = sarif_data.get_report()
    
    # Get a histogram of issue types for a specific severity
    error_histogram = report.get_issue_type_histogram_for_severity("error")
  6. Fail CI pipelines using sarif --check

    main

    To use sarif-tools in a Continuous Integration (CI) pipeline to enforce quality gates, use the --check flag with the summary or diff commands. This causes the tool to exit with a non-zero exit code if issues are found at or above the specified level.

    Valid severity levels for --check: error, warning, note.

    Examples:

    • Fail if there are any errors or warnings: sarif --check warning summary c:\temp\sarif_files
    • Fail if there are any new issues at the error level compared to a baseline: sarif --check error diff c:\temp\old_sarif_files c:\temp\sarif_files
    sarif --check warning summary c:\temp\sarif_files
  7. Generate reports in various formats (HTML, CSV, Word, Emacs)

    main

    The sarif tool supports multiple output formats for human-readable or machine-readable reports:

    CommandFormatDescription
    html.htmlWeb browser view. Supports --image for a logo and --no-autotrim to prevent path stripping.
    csv.csvList of issues. Supports --autotrim and --trim for path management.
    word.docxMS Word summaries. Supports --image and --no-autotrim.
    emacs.txtRepresentation for viewing in Emacs (compile format).
    summary.txtText summary with issue counts.
    codeclimate.jsonCode Climate format for GitLab.
    # Generate an HTML report
    sarif html input.sarif -o report.html
    
    # Generate a CSV report with path trimming
    sarif csv input.sarif -o report.csv --trim /home/user/project
  8. Troubleshoot 'sarif' command not found

    main

    If the sarif command is not recognized after installation, it is likely because the Python Scripts directory is not in your PATH environment variable.

    Solutions:

    1. Add to PATH: Locate the Scripts directory (where sarif or sarif.exe was installed) and add it to your system's PATH variable.
    2. Use Python module syntax: If you cannot modify your PATH, you can run the tool directly using Python:
      python -m sarif

    Debugging Path Conflicts:

    • Windows: Use where python and where pip in both normal and Administrator command prompts to verify which installations are being used.
    • Linux: Use which python and which pip (with and without sudo) to check for installation mismatches.
    python -m sarif
  9. Augment and consolidate SARIF files via CLI

    main

    You can use the CLI to enrich SARIF data with blame information and combine multiple tool outputs into a single consolidated file.

    Workflow Example:

    1. Blame: Augment a SARIF file with blame information: sarif blame -o <output_file>.sarif <input_file>.sarif
    2. Copy/Consolidate: Combine multiple files into one, adding a timestamp to the output filename: sarif copy --timestamp -o artifacts/combined.sarif
    # Augment with blame
    sarif blame -o with_blame/myapp_mytool_with_blame.sarif myapp_mytool.sarif
    
    # Combine all tools into one file with a timestamp
    sarif copy --timestamp -o artifacts/myapp_alltools_with_blame.sarif
  10. Use IssuesReport to group and analyze issues

    main

    The IssuesReport object (obtained via .get_report()) allows you to navigate issues by Severity (error, warning, note, none), then by Issue Type (a combination of code and description), and finally by individual Records (sorted by location).

    Key Methods:

    • get_severities(): Returns an ordered list of severities from worst to least bad.
    • any_none_severities(): Returns True if any records have severity none.
    • get_issue_count_for_severity(severity): Total count of results at a specific severity.
    • get_issue_type_count_for_severity(severity): Total count of unique issue types at a specific severity.
    • get_issues_grouped_by_type_for_severity(severity): Returns a dict[issue_type_key, list[results]].
    • get_issue_type_histogram_for_severity(severity): Returns a dict[issue_type_key, count].
    • get_issues_for_severity(severity): Returns a flattened list of all results at a given severity.
  11. Filter and trim paths in SARIF data

    main

    You can manipulate how file paths are represented in your SARIF objects using the following APIs:

    Path Shortening Use init_path_prefix_stripping(autotrim, path_prefixes) on a SarifFileSet, SarifFile, or SarifRun to:

    • Set autotrim=True to automatically remove the longest common prefix.
    • Set autotrim=False and provide a list of path_prefixes to remove specific strings.

    General Filtering Use init_general_filter(filter_description, include_filters, exclude_filters) to apply inclusion/exclusion rules.

    • After processing, call get_filter_stats() to get a FilterStats object containing filtered_in_result_count and filtered_out_result_count.