# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'rack' require 'contrast/utils/hash_digest' require 'contrast/utils/string_utils' require 'contrast/agent/assess/rule/response/base_rule' module Contrast module Agent module Assess module Rule module Response # These rules check the content of the HTTP Response to determine if something was set incorrectly or # insecurely in it. module BodyRule protected HTML_PROP = 'html'.cs__freeze START_PROP = 'start'.cs__freeze END_PROP = 'end'.cs__freeze FORM_START_REGEXP = /
] the found elements of this section, as well as their start and end indexes. def html_elements section, element_start_str = '', capture_overflow: false elements = [] section_start = 0 return [] unless section potential_elements(section, element_start_str).flatten.each do |potential_element| next unless potential_element next unless element_openings.any? { |opening| potential_element.starts_with?(opening) } section_start = section.index(element_start_str, section_start) next unless section_start element_stop = potential_element.index('>').to_i next unless element_stop section_close = section_start + 6 + element_stop elements << capture(section, section_start, section_close, element_stop, overflow: capture_overflow) section_start = section_close end elements end def potential_elements section, element_start section.split(element_start) end def element_openings [' ', "\n", "\r", "\t", '>'] end # Capture the information needed to build the properties of this finding by parsing out from the body # # @param body [String] the entire HTTP Response body # @param body_start [Integer] the start of the range to take from the body # @param body_close [Integer] the end of the range to take from the body # @param tag_stop [Integer] the index of the end of the html tag from its start # @return [Hash] def capture body, body_start, body_close, tag_stop, overflow: false tag = {} # Capture the 50 characters in front of the form, or up to the start if the form starts before 50. if overflow capture_start = body_start < 50 ? 0 : body_start - 50 # Start is where the '') accounts for finding the rest of the form # 50 accounts for the context to capture beyond capture_close = body_close + 50 tag[HTML_PROP] = body[capture_start...capture_close] tag[START_PROP] = body_start < 50 ? body_start : 50 else tag[HTML_PROP] = body[body_start...body_close] tag[START_PROP] = body_start end tag[END_PROP] = tag[START_PROP] + 6 + tag_stop tag end end end end end end end