Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/support/lib/module_validation.rb
Views: 11780
require 'active_model'12module ModuleValidation3# Checks if values within arrays included within the passed list of acceptable values4class ArrayInclusionValidator < ActiveModel::EachValidator5def validate_each(record, attribute, value)6unless value.is_a?(Array)7record.errors.add(attribute, "#{attribute} must be an array")8return9end1011invalid_options = value - options[:in]12message = "contains invalid values #{invalid_options.inspect} - only #{options[:in].inspect} is allowed"1314if invalid_options.any?15record.errors.add(attribute, :array_inclusion, message: message, value: value)16end17end18end1920# Validates module metadata21class Validator < SimpleDelegator22include ActiveModel::Validations2324validate :validate_filename_is_snake_case25validate :validate_reference_ctx_id26validate :validate_author_bad_chars27validate :validate_target_platforms2829attr_reader :mod3031def initialize(mod)32super33@mod = mod34end3536#37# Acceptable Stability ratings38#39VALID_STABILITY_VALUES = [40Msf::CRASH_SAFE,41Msf::CRASH_SERVICE_RESTARTS,42Msf::CRASH_SERVICE_DOWN,43Msf::CRASH_OS_RESTARTS,44Msf::CRASH_OS_DOWN,45Msf::SERVICE_RESOURCE_LOSS,46Msf::OS_RESOURCE_LOSS47]4849#50# Acceptable Side-effect ratings51#52VALID_SIDE_EFFECT_VALUES = [53Msf::ARTIFACTS_ON_DISK,54Msf::CONFIG_CHANGES,55Msf::IOC_IN_LOGS,56Msf::ACCOUNT_LOCKOUTS,57Msf::SCREEN_EFFECTS,58Msf::AUDIO_EFFECTS,59Msf::PHYSICAL_EFFECTS60]6162#63# Acceptable Reliability ratings64#65VALID_RELIABILITY_VALUES = [66Msf::FIRST_ATTEMPT_FAIL,67Msf::REPEATABLE_SESSION,68Msf::UNRELIABLE_SESSION,69Msf::EVENT_DEPENDENT70]7172#73# Acceptable site references74#75VALID_REFERENCE_CTX_ID_VALUES = %w[76CVE77CWE78BID79MSB80EDB81US-CERT-VU82ZDI83URL84WPVDB85PACKETSTORM86LOGO87SOUNDTRACK88OSVDB89VTS90OVE91]9293def validate_notes_values_are_arrays94notes.each do |k, v|95unless v.is_a?(Array)96errors.add :notes, "note value #{k.inspect} must be an array, got #{v.inspect}"97end98end99end100101def validate_crash_safe_not_present_in_stability_notes102if rank == Msf::ExcellentRanking && !stability.include?(Msf::CRASH_SAFE)103errors.add :stability, "must have CRASH_SAFE value if module has an ExcellentRanking, instead found #{stability.inspect}"104end105end106107def validate_filename_is_snake_case108unless file_path.split('/').last.match?(/^[a-z0-9]+(?:_[a-z0-9]+)*\.rb$/)109errors.add :file_path, "must be snake case, instead found #{file_path.inspect}"110end111end112113def validate_reference_ctx_id114references_ctx_id_list = references.map(&:ctx_id)115invalid_references = references_ctx_id_list - VALID_REFERENCE_CTX_ID_VALUES116117invalid_references.each do |ref|118if ref.casecmp?('NOCVE')119errors.add :references, "#{ref} please include NOCVE values in the 'notes' section, rather than in 'references'"120elsif ref.casecmp?('AKA')121errors.add :references, "#{ref} please include AKA values in the 'notes' section, rather than in 'references'"122else123errors.add :references, "#{ref} is not valid, must be in #{VALID_REFERENCE_CTX_ID_VALUES}"124end125end126end127128def validate_author_bad_chars129author.each do |i|130if i.name =~ /^@.+$/131errors.add :author, "must not include username handles, found #{i.name.inspect}. Try leaving it in a comment instead"132end133end134end135136def validate_target_platforms137if platform.blank? && type == 'exploit'138targets.each do |target|139if target.platform.blank?140errors.add :platform, 'must be included either within targets or platform module metadata'141end142end143end144end145146def has_notes?147!notes.empty?148end149150validates :mod, presence: true151152with_options if: :has_notes? do |mod|153mod.validate :validate_crash_safe_not_present_in_stability_notes154mod.validate :validate_notes_values_are_arrays155156mod.validates :stability,157'module_validation/array_inclusion': { in: VALID_STABILITY_VALUES }158159mod.validates :side_effects,160'module_validation/array_inclusion': { in: VALID_SIDE_EFFECT_VALUES }161162mod.validates :reliability,163'module_validation/array_inclusion': { in: VALID_RELIABILITY_VALUES }164end165166validates :license,167presence: true,168inclusion: { in: LICENSES, message: 'must include a valid license' }169170validates :rank,171presence: true,172inclusion: { in: Msf::RankingName.keys, message: 'must include a valid module ranking' }173174validates :author,175presence: true176177validates :name,178presence: true,179format: { with: /\A[^&<>]+\z/, message: 'must not contain the characters &<>' }180181validates :description,182presence: true183end184end185186187