Class: Dependabot::NpmAndYarn::UpdateChecker::VulnerabilityAuditor

Inherits:
Object
  • Object
show all
Defined in:
lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb

Instance Method Summary collapse

Constructor Details

#initialize(dependency_files:, credentials:) ⇒ VulnerabilityAuditor

Returns a new instance of VulnerabilityAuditor.



19
20
21
22
# File 'lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb', line 19

def initialize(dependency_files:, credentials:)
  @dependency_files = dependency_files
  @credentials = credentials
end

Instance Method Details

#audit(dependency:, security_advisories:) ⇒ Hash<String, [String, Array<Hash<String, String>>]>

rubocop:disable Metrics/MethodLength Finds any dependencies in the ‘package-lock.json` or `npm-shrinkwrap.json` that have a subdependency on the given dependency that is locked to a vuln version range.

NOTE: yarn is currently not supported.

Parameters:

  • dependency (Dependabot::Dependency)

    the dependency to check

  • security_advisories (Array<Dependabot::SecurityAdvisory>)

    advisories for the dependency

Returns:

  • (Hash<String, [String, Array<Hash<String, String>>]>)

    the audit results

    • :dependency_name [String] the name of the dependency

    • :fix_available [Boolean] whether a fix is available

    • :current_version [String] the version of the dependency

    • :target_version [String] the version of the dependency after the fix

    • :fix_updates [Array<Hash<String, String>>] a list of dependencies to update in order to fix

      • :dependency_name [String] the name of the blocking dependency

      • :current_version [String] the current version of the blocking dependency

      • :target_version [String] the target version of the blocking dependency

      • :top_level_ancestors [Array<String>] the names of top-level dependencies with a transitive dependency on the blocking dependency

    • :top_level_ancestors [Array<String>] the names of all top-level dependencies with a transitive dependency on the dependency

    • :explanation [String] an explanation for why the project failed the vulnerability auditor run



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/dependabot/npm_and_yarn/update_checker/vulnerability_auditor.rb', line 46

def audit(dependency:, security_advisories:)
  Dependabot.logger.info("VulnerabilityAuditor: starting audit")

  fix_unavailable = {
    "dependency_name" => dependency.name,
    "fix_available" => false,
    "fix_updates" => [],
    "top_level_ancestors" => []
  }

  SharedHelpers.in_a_temporary_directory do
    dependency_files_builder = DependencyFilesBuilder.new(
      dependency: dependency,
      dependency_files: dependency_files,
      credentials: credentials
    )
    dependency_files_builder.write_temporary_dependency_files

    # `npm-shrinkwrap.js`, if present, takes precedence over `package-lock.js`.
    # Both files use the same format. See https://bit.ly/3lDIAJV for more.
    lockfile = (dependency_files_builder.shrinkwraps + dependency_files_builder.package_locks).first
    unless lockfile
      Dependabot.logger.info("VulnerabilityAuditor: missing lockfile")
      return fix_unavailable
    end

    vuln_versions = security_advisories.map do |a|
      {
        dependency_name: a.dependency_name,
        affected_versions: a.vulnerable_version_strings
      }
    end

    audit_result = SharedHelpers.run_helper_subprocess(
      command: NativeHelpers.helper_path,
      function: "npm:vulnerabilityAuditor",
      args: [Dir.pwd, vuln_versions]
    )

    validation_result = validate_audit_result(audit_result, security_advisories)
    if validation_result != :viable
      Dependabot.logger.info("VulnerabilityAuditor: audit result not viable: #{validation_result}")
      fix_unavailable["explanation"] = explain_fix_unavailable(validation_result, dependency)
      return fix_unavailable
    end

    Dependabot.logger.info("VulnerabilityAuditor: audit result viable")
    audit_result
  end
rescue SharedHelpers::HelperSubprocessFailed => e
  log_helper_subprocess_failure(dependency, e)
  fix_unavailable
end