Class: Zwischen::Scanner::Semgrep

Inherits:
Base
  • Object
show all
Defined in:
lib/zwischen/scanner/semgrep.rb

Constant Summary collapse

DEFAULT_CONFIG =

Use open ruleset that works without Semgrep login

"p/security-audit"

Constants inherited from Base

Base::ZWISCHEN_BIN_DIR

Instance Attribute Summary

Attributes inherited from Base

#command, #name

Instance Method Summary collapse

Methods inherited from Base

#available?, #executable_path, #find_executable, #scan

Constructor Details

#initialize(config: DEFAULT_CONFIG) ⇒ Semgrep

Returns a new instance of Semgrep.



13
14
15
16
# File 'lib/zwischen/scanner/semgrep.rb', line 13

def initialize(config: DEFAULT_CONFIG)
  super(name: "semgrep", command: "semgrep")
  @config = config
end

Instance Method Details

#build_command(project_root) ⇒ Object



18
19
20
# File 'lib/zwischen/scanner/semgrep.rb', line 18

def build_command(project_root)
  [executable_path, "--json", *config_args, project_root]
end

#build_command_for_files(files, _project_root) ⇒ Object



22
23
24
# File 'lib/zwischen/scanner/semgrep.rb', line 22

def build_command_for_files(files, _project_root)
  [executable_path, "--json", *config_args, *files]
end

#parse_output(output) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/zwischen/scanner/semgrep.rb', line 26

def parse_output(output)
  return [] if output.strip.empty?

  findings = []
  json_data = JSON.parse(output)

  # Semgrep returns results in a "results" array
  Array(json_data["results"]).each do |result|
    severity = map_severity(result["extra"]&.dig("severity"))
    
    findings << Zwischen::Finding::Finding.new(
      type: "sast",
      scanner: "semgrep",
      severity: severity,
      file: result["path"],
      line: result["start"]&.dig("line"),
      message: result.dig("extra", "message") || result["message"] || result["check_id"],
      rule_id: result["check_id"],
      code_snippet: result["extra"]&.dig("lines"),
      raw_data: result
    )
  end

  findings
rescue JSON::ParserError => e
  warn "Failed to parse Semgrep output: #{e.message}"
  []
end