CVE-2017-12617
Description
When running Apache Tomcat versions 9.0.0.M1 to 9.0.0, 8.5.0 to 8.5.22, 8.0.0.RC1 to 8.0.46 and 7.0.0 to 7.0.81 with HTTP PUTs enabled (e.g. via setting the readonly initialisation parameter of the Default servlet to false) it was possible to upload a JSP file to the server via a specially crafted request. This JSP could then be requested and any code it contained would be executed by the server.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.tomcat:tomcat-catalinaMaven | >= 9.0.0.M1, < 9.0.1 | 9.0.1 |
org.apache.tomcat:tomcat-catalinaMaven | >= 8.5.0, < 8.5.23 | 8.5.23 |
org.apache.tomcat:tomcat-catalinaMaven | >= 8.0.0-RC1, < 8.0.47 | 8.0.47 |
org.apache.tomcat:tomcat-catalinaMaven | >= 7.0.0, < 7.0.82 | 7.0.82 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 9.0.0.M1, < 9.0.1 | 9.0.1 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 8.5.0, < 8.5.23 | 8.5.23 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 8.0.0-RC1, < 8.0.47 | 8.0.47 |
org.apache.tomcat.embed:tomcat-embed-coreMaven | >= 7.0.0, < 7.0.82 | 7.0.82 |
Affected products
151cpe:2.3:a:netapp:active_iq_unified_manager:*:*:*:*:*:vmware_vsphere:*:*+ 1 more
- cpe:2.3:a:netapp:active_iq_unified_manager:*:*:*:*:*:vmware_vsphere:*:*range: >=9.5
- cpe:2.3:a:netapp:active_iq_unified_manager:*:*:*:*:*:windows:*:*range: >=7.3
- cpe:2.3:a:netapp:oncommand_balance:-:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:oncommand_insight:-:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:oncommand_shift:-:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:oncommand_workflow_automation:-:*:*:*:*:*:*:*
- cpe:2.3:a:netapp:snapcenter:-:*:*:*:*:*:*:*
cpe:2.3:a:oracle:agile_plm:9.3.3:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:a:oracle:agile_plm:9.3.3:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:agile_plm:9.3.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:agile_plm:9.3.5:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:agile_plm:9.3.6:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:communications_instant_messaging_server:10.0.1:*:*:*:*:*:*:*
cpe:2.3:a:oracle:endeca_information_discovery_integrator:3.1.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:endeca_information_discovery_integrator:3.1.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:endeca_information_discovery_integrator:3.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:enterprise_manager_for_mysql_database:12.1.0.4.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:financial_services_analytical_applications_infrastructure:*:*:*:*:*:*:*:*Range: >=7.3.3.0.0,<=7.3.5.3.0
cpe:2.3:a:oracle:fmw_platform:12.2.1.2.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:fmw_platform:12.2.1.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:fmw_platform:12.2.1.3.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:health_sciences_empirica_inspections:1.0.1.1:*:*:*:*:*:*:*
cpe:2.3:a:oracle:hospitality_guest_access:4.2.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:hospitality_guest_access:4.2.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:hospitality_guest_access:4.2.1:*:*:*:*:*:*:*
cpe:2.3:a:oracle:instantis_enterprisetrack:17.1:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:instantis_enterprisetrack:17.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:instantis_enterprisetrack:17.2:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:management_pack:11.2.1.0.13:*:*:*:*:goldengate:*:*
- cpe:2.3:a:oracle:micros_lucas:2.9.5:*:*:*:*:*:*:*
cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.0.1:*:*:*:*:*:*:*+ 5 more
- cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.5.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.6.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.7.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.8.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:micros_retail_xbri_loss_prevention:10.8.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:mysql_enterprise_monitor:*:*:*:*:*:*:*:*Range: <=3.3.6.3293
cpe:2.3:a:oracle:retail_advanced_inventory_planning:13.2:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:a:oracle:retail_advanced_inventory_planning:13.2:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_advanced_inventory_planning:13.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_advanced_inventory_planning:14.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_advanced_inventory_planning:15.0:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_back_office:14.0.4:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:retail_back_office:14.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_back_office:14.1.3:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_central_office:14.0.4:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:retail_central_office:14.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_central_office:14.1.3:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_convenience_and_fuel_pos_software:2.1.132:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_eftlink:1.1.124:*:*:*:*:*:*:*+ 2 more
- cpe:2.3:a:oracle:retail_eftlink:1.1.124:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_eftlink:15.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_eftlink:16.0.2:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_insights:14.0:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:a:oracle:retail_insights:14.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_insights:14.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_insights:15.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_insights:16.0:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_invoice_matching:12.0:*:*:*:*:*:*:*+ 7 more
- cpe:2.3:a:oracle:retail_invoice_matching:12.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:13.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:13.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:13.2:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:14.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:14.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:15.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_invoice_matching:16.0:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_order_broker:15.0:*:*:*:*:*:*:*+ 4 more
- cpe:2.3:a:oracle:retail_order_broker:15.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_broker:16.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_broker:5.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_broker:5.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_broker:5.2:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_order_management_system:4.0:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:a:oracle:retail_order_management_system:4.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_management_system:4.5:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_management_system:4.7:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_order_management_system:5.0:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_point-of-service:14.0.4:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:oracle:retail_point-of-service:14.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_point-of-service:14.1.3:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_price_management:12.0:*:*:*:*:*:*:*+ 7 more
- cpe:2.3:a:oracle:retail_price_management:12.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:13.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:13.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:13.2:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:14.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:14.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:15.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_price_management:16.0:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_returns_management:14.0.4:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:a:oracle:retail_returns_management:14.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_returns_management:14.1.3:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_returns_management:2.3.8:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_returns_management:2.4.9:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_store_inventory_management:12.0.12:*:*:*:*:*:*:*+ 7 more
- cpe:2.3:a:oracle:retail_store_inventory_management:12.0.12:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:13.0.7:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:13.1.9:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:13.2.9:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:14.0.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:14.1.3:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:15.0.2:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_store_inventory_management:16.0.1:*:*:*:*:*:*:*
cpe:2.3:a:oracle:retail_xstore_point_of_service:15.0.1:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:a:oracle:retail_xstore_point_of_service:15.0.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_xstore_point_of_service:6.0.11:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_xstore_point_of_service:7.0.6:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:retail_xstore_point_of_service:7.1.6:*:*:*:*:*:*:*
cpe:2.3:a:oracle:transportation_management:6.3.1:*:*:*:*:*:*:*+ 6 more
- cpe:2.3:a:oracle:transportation_management:6.3.1:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:transportation_management:6.3.2:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:transportation_management:6.3.3:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:transportation_management:6.3.4:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:transportation_management:6.3.5:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:transportation_management:6.3.6:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:transportation_management:6.3.7:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:tuxedo_system_and_applications_monitor:12.1.3.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:webcenter_sites:11.1.1.8.0:*:*:*:*:*:*:*
- cpe:2.3:a:oracle:workload_manager:12.2.0.1:*:*:*:*:*:*:*
cpe:2.3:a:redhat:jboss_enterprise_application_platform:6.0.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:redhat:jboss_enterprise_application_platform:6.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:redhat:jboss_enterprise_application_platform:6.4.0:*:*:*:*:*:*:*
cpe:2.3:a:redhat:jboss_enterprise_web_server:2.0.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:a:redhat:jboss_enterprise_web_server:2.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:redhat:jboss_enterprise_web_server:3.0.0:*:*:*:*:*:*:*
- cpe:2.3:a:redhat:jboss_enterprise_web_server_text-only_advisories:-:*:*:*:*:*:*:*
cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:esm:*:*:*+ 3 more
- cpe:2.3:o:canonical:ubuntu_linux:12.04:*:*:*:esm:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:16.04:*:*:*:esm:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:17.10:*:*:*:*:*:*:*
- cpe:2.3:o:canonical:ubuntu_linux:18.04:*:*:*:esm:*:*:*
- cpe:2.3:o:debian:debian_linux:7.0:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_desktop:6.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:redhat:enterprise_linux_desktop:6.0:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_desktop:7.0:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_eus:7.4:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:o:redhat:enterprise_linux_eus:7.4:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus:7.5:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus:7.7:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_eus_compute_node:7.4:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:o:redhat:enterprise_linux_eus_compute_node:7.4:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus_compute_node:7.5:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus_compute_node:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_eus_compute_node:7.7:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems:6.0_s390x:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems:6.0_s390x:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems:7.0_s390x:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems_eus:7.4_s390x:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems_eus:7.4_s390x:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems_eus:7.5_s390x:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems_eus:7.6_s390x:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_ibm_z_systems_eus:7.7_s390x:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian:6.0_ppc64:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian:6.0_ppc64:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian:7.0_ppc64:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian_eus:7.4_ppc64:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian_eus:7.4_ppc64:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian_eus:7.5_ppc64:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian_eus:7.6_ppc64:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_big_endian_eus:7.7_ppc64:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_little_endian:7.0:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_for_power_little_endian_eus:7.4_ppc64le:*:*:*:*:*:*:*+ 3 more
- cpe:2.3:o:redhat:enterprise_linux_for_power_little_endian_eus:7.4_ppc64le:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_little_endian_eus:7.5_ppc64le:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_little_endian_eus:7.6_ppc64le:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_for_power_little_endian_eus:7.7_ppc64le:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_server:6.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:redhat:enterprise_linux_server:6.0:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server:7.0:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_server_aus:7.4:*:*:*:*:*:*:*+ 2 more
- cpe:2.3:o:redhat:enterprise_linux_server_aus:7.4:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_aus:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_aus:7.7:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_server_tus:7.4:*:*:*:*:*:*:*+ 2 more
- cpe:2.3:o:redhat:enterprise_linux_server_tus:7.4:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_tus:7.6:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_server_tus:7.7:*:*:*:*:*:*:*
cpe:2.3:o:redhat:enterprise_linux_workstation:6.0:*:*:*:*:*:*:*+ 1 more
- cpe:2.3:o:redhat:enterprise_linux_workstation:6.0:*:*:*:*:*:*:*
- cpe:2.3:o:redhat:enterprise_linux_workstation:7.0:*:*:*:*:*:*:*
Patches
21027da9e603ac66ebf0df1f2f3c78e95e3626f1b85da754c4Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=62498
3 files changed · +111 −1
java/org/apache/naming/resources/VirtualDirContext.java+2 −1 modified@@ -212,7 +212,8 @@ protected File file(String name, boolean mustExist) { } } } - if (name.startsWith(path + "/")) { + path += "/"; + if (name.startsWith(path)) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { file = new File(resourcesDir, res);
test/org/apache/naming/resources/TestVirtualDirContext.java+102 −0 added@@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.naming.resources; + +import java.io.File; + +import javax.naming.NamingException; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.startup.LoggingBaseTest; + +public class TestVirtualDirContext { + + @Test + public void testBug62498() throws NamingException { + VirtualDirContext vdc = new VirtualDirContext(); + // No docBase + vdc.setExtraResourcePaths("/=" + LoggingBaseTest.getBuildDirectory().getAbsolutePath()); + + vdc.allocate(); + + File f1 = vdc.file(""); + Assert.assertNotNull(f1); + File f2 = vdc.file("/"); + Assert.assertNotNull(f2); + Assert.assertEquals(f1.getAbsolutePath(), f2.getAbsolutePath()); + + Object obj1 = vdc.lookup(""); + Assert.assertTrue(obj1 instanceof FileDirContext); + Object obj2 = vdc.lookup("/"); + Assert.assertTrue(obj2 instanceof FileDirContext); + Assert.assertEquals(((FileDirContext) obj1).absoluteBase, ((FileDirContext) obj2).absoluteBase); + } + + + @Test + public void testBug62498a() { + VirtualDirContext vdc = new VirtualDirContext(); + // No docBase + vdc.setExtraResourcePaths("/=" + LoggingBaseTest.getBuildDirectory().getAbsolutePath()); + + vdc.allocate(); + + File f1 = vdc.file(""); + Assert.assertNotNull(f1); + } + + + @Test + public void testBug62498b() { + VirtualDirContext vdc = new VirtualDirContext(); + // No docBase + vdc.setExtraResourcePaths("/=" + LoggingBaseTest.getBuildDirectory().getAbsolutePath()); + + vdc.allocate(); + + File f2 = vdc.file("/"); + Assert.assertNotNull(f2); + } + + + @Test + public void testBug62498c() throws NamingException { + VirtualDirContext vdc = new VirtualDirContext(); + // No docBase + vdc.setExtraResourcePaths("/=" + LoggingBaseTest.getBuildDirectory().getAbsolutePath()); + + vdc.allocate(); + + Object obj1 = vdc.lookup(""); + Assert.assertTrue(obj1 instanceof FileDirContext); + } + + + @Test + public void testBug62498d() throws NamingException { + VirtualDirContext vdc = new VirtualDirContext(); + // No docBase + vdc.setExtraResourcePaths("/=" + LoggingBaseTest.getBuildDirectory().getAbsolutePath()); + + vdc.allocate(); + + Object obj2 = vdc.lookup("/"); + Assert.assertTrue(obj2 instanceof FileDirContext); + } +}
webapps/docs/changelog.xml+7 −0 modified@@ -58,6 +58,13 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 7.0.90 (violetagg)"> + <subsection name="Catalina"> + <changelog> + <fix>62498</fix>: Correct a regression in the fix for CVE-2017-12617 that + caused request failures for some requests when using the + <code>VirtualDirContext</code>. (markt) + </changelog> + </subsection> </section> <section name="Tomcat 7.0.89 (violetagg)"> <subsection name="Catalina">
24aea94807f9Further alignment with 8.0.x and later. Fixes Linux test failures.
1 file changed · +4 −0
java/org/apache/naming/resources/FileDirContext.java+4 −0 modified@@ -804,6 +804,10 @@ protected File file(String name) { * @param mustExist Must the specified resource exist? */ protected File file(String name, boolean mustExist) { + if (name.equals("/")) { + name = ""; + } + File file = new File(base, name); return validate(file, name, mustExist, absoluteBase, canonicalBase); }
2 files changed · +4 −4
java/org/apache/naming/resources/FileDirContext.java+1 −1 modified@@ -810,7 +810,7 @@ protected File file(String name, boolean mustExist) { protected File validate(File file, String name, boolean mustExist, String absoluteBase, - String canonicalBase) { + String canonicalBase) { // If the requested names ends in '/', the Java File API will return a // matching file if one exists. This isn't what we want as it is not
java/org/apache/naming/resources/VirtualDirContext.java+3 −3 modified@@ -330,9 +330,9 @@ protected String doGetRealPath(String path) { return null; } } - - + + protected File validate(File file, String name, boolean mustExist, String absoluteBase) { - return validate(file, name, mustExist, normalize(absoluteBase), absoluteBase); + return validate(file, name, mustExist, normalize(absoluteBase), absoluteBase); } }
cf0b37beb062Fix failing tests on Windows
2 files changed · +10 −4
java/org/apache/naming/resources/FileDirContext.java+5 −4 modified@@ -805,11 +805,12 @@ protected File file(String name) { */ protected File file(String name, boolean mustExist) { File file = new File(base, name); - return validate(file, name, mustExist, absoluteBase); + return validate(file, name, mustExist, absoluteBase, canonicalBase); } - protected File validate(File file, String name, boolean mustExist, String absoluteBase) { + protected File validate(File file, String name, boolean mustExist, String absoluteBase, + String canonicalBase) { // If the requested names ends in '/', the Java File API will return a // matching file if one exists. This isn't what we want as it is not @@ -850,8 +851,8 @@ protected File validate(File file, String name, boolean mustExist, String absolu // Ensure that the file is not outside the fileBase. This should not be // possible for standard requests (the request is normalized early in // the request processing) but might be possible for some access via the - // Servlet API (RequestDispatcheretc.) therefore these checks are - // retained as an additional safety measure absoluteBase has been + // Servlet API (RequestDispatcher etc.) therefore these checks are + // retained as an additional safety measure. absoluteBase has been // normalized so absPath needs to be normalized as well. String absPath = normalize(file.getAbsolutePath()); if ((absoluteBase.length() > absPath.length())) {
java/org/apache/naming/resources/VirtualDirContext.java+5 −0 modified@@ -330,4 +330,9 @@ protected String doGetRealPath(String path) { return null; } } + + + protected File validate(File file, String name, boolean mustExist, String absoluteBase) { + return validate(file, name, mustExist, normalize(absoluteBase), absoluteBase); + } }
bbcbb749c750First pass at aligning 7.0.x checks with 8.0.x
2 files changed · +110 −17
java/org/apache/naming/resources/FileDirContext.java+51 −17 modified@@ -14,8 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - package org.apache.naming.resources; import java.io.File; @@ -97,6 +95,8 @@ public FileDirContext(Hashtable<String,Object> env) { */ protected String absoluteBase = null; + private String canonicalBase = null; + /** * Allow linking. @@ -106,7 +106,6 @@ public FileDirContext(Hashtable<String,Object> env) { // ------------------------------------------------------------- Properties - /** * Set the document root. * @@ -137,14 +136,14 @@ public void setDocBase(String docBase) { throw new IllegalArgumentException(sm.getString("fileResources.base", docBase)); } + this.absoluteBase = normalize(base.getAbsolutePath()); + // absoluteBase also needs to be normalized. Using the canonical path is // the simplest way of doing this. try { - this.absoluteBase = base.getCanonicalPath(); + this.canonicalBase = base.getCanonicalPath(); } catch (IOException e) { - log.warn(sm.getString("fileResources.canonical.fail", base.getPath())); - // Fall back to the absolute path - this.absoluteBase = base.getAbsolutePath(); + throw new IllegalArgumentException(e); } super.setDocBase(docBase); } @@ -827,8 +826,15 @@ protected File validate(File file, String name, boolean mustExist, String absolu // If allow linking is enabled, files are not limited to being located // under the fileBase so all further checks are disabled. - if (allowLinking) + if (allowLinking) { return file; + } + + // Additional Windows specific checks to handle known problems with + // File.getCanonicalPath() + if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) { + return null; + } // Check that this file is located under the web application root String canPath = null; @@ -837,17 +843,16 @@ protected File validate(File file, String name, boolean mustExist, String absolu } catch (IOException e) { // Ignore } - if (canPath == null || !canPath.startsWith(absoluteBase)) { + if (canPath == null || !canPath.startsWith(canonicalBase)) { return null; } // Ensure that the file is not outside the fileBase. This should not be // possible for standard requests (the request is normalized early in // the request processing) but might be possible for some access via the - // Servlet API (RequestDispatcher, HTTP/2 push etc.) therefore these - // checks are retained as an additional safety measure - // absoluteBase has been normalized so absPath needs to be normalized as - // well. + // Servlet API (RequestDispatcheretc.) therefore these checks are + // retained as an additional safety measure absoluteBase has been + // normalized so absPath needs to be normalized as well. String absPath = normalize(file.getAbsolutePath()); if ((absoluteBase.length() > absPath.length())) { return null; @@ -857,7 +862,7 @@ protected File validate(File file, String name, boolean mustExist, String absolu // was not part of the requested path and the remaining check only // applies to the request path absPath = absPath.substring(absoluteBase.length()); - canPath = canPath.substring(absoluteBase.length()); + canPath = canPath.substring(canonicalBase.length()); // Case sensitivity check // The normalized requested path should be an exact match the equivalent @@ -870,9 +875,8 @@ protected File validate(File file, String name, boolean mustExist, String absolu // // absPath is normalized so canPath needs to be normalized as well // Can't normalize canPath earlier as canonicalBase is not normalized - canPath = normalize(canPath); - if (absPath.length() == 0) { - absPath = "/"; + if (canPath.length() > 0) { + canPath = normalize(canPath); } if (!canPath.equals(absPath)) { return null; @@ -882,6 +886,36 @@ protected File validate(File file, String name, boolean mustExist, String absolu } + private boolean isInvalidWindowsFilename(String name) { + final int len = name.length(); + if (len == 0) { + return false; + } + // This consistently ~10 times faster than the equivalent regular + // expression irrespective of input length. + for (int i = 0; i < len; i++) { + char c = name.charAt(i); + if (c == '\"' || c == '<' || c == '>') { + // These characters are disallowed in Windows file names and + // there are known problems for file names with these characters + // when using File#getCanonicalPath(). + // Note: There are additional characters that are disallowed in + // Windows file names but these are not known to cause + // problems when using File#getCanonicalPath(). + return true; + } + } + // Windows does not allow file names to end in ' ' unless specific low + // level APIs are used to create the files that bypass various checks. + // File names that end in ' ' are known to cause problems when using + // File#getCanonicalPath(). + if (name.charAt(len -1) == ' ') { + return true; + } + return false; + } + + /** * List the resources which are members of a collection. *
java/org/apache/naming/resources/JrePlatform.java+59 −0 added@@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.naming.resources; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class JrePlatform { + + private static final String OS_NAME_PROPERTY = "os.name"; + private static final String OS_NAME_WINDOWS_PREFIX = "Windows"; + + static { + /* + * There are a few places where a) the behaviour of the Java API depends + * on the underlying platform and b) those behavioural differences have + * an impact on Tomcat. + * + * Tomcat therefore needs to be able to determine the platform it is + * running on to account for those differences. + * + * In an ideal world this code would not exist. + */ + + // This check is derived from the check in Apache Commons Lang + String osName; + if (System.getSecurityManager() == null) { + osName = System.getProperty(OS_NAME_PROPERTY); + } else { + osName = AccessController.doPrivileged( + new PrivilegedAction<String>() { + + @Override + public String run() { + return System.getProperty(OS_NAME_PROPERTY); + } + }); + } + + IS_WINDOWS = osName.startsWith(OS_NAME_WINDOWS_PREFIX); + } + + + public static final boolean IS_WINDOWS; +}
74ad0e216c79Updates after kkolinko review
2 files changed · +38 −14
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+10 −10 modified@@ -136,14 +136,14 @@ protected final File file(String name, boolean mustExist) { private boolean isInvalidWindowsFilename(String name) { - if (name.length() == 0) { + final int len = name.length(); + if (len == 0) { return false; } - // For typical length file names, this is 2-3 times faster than the - // equivalent regular expression. The cut-over point is file names (not - // full paths) of ~65 characters. - char[] chars = name.toCharArray(); - for (char c : chars) { + // This consistently ~10 times faster than the equivalent regular + // expression irrespective of input length. + for (int i = 0; i < len; i++) { + char c = name.charAt(i); if (c == '\"' || c == '<' || c == '>') { // These characters are disallowed in Windows file names and // there are known problems for file names with these characters @@ -154,11 +154,11 @@ private boolean isInvalidWindowsFilename(String name) { return true; } } - // Windows does allow file names to end in ' ' unless specific low level - // APIs are used to create the files that bypass various checks. File - // names that end in ' ' are known to cause problems when using + // Windows does not allow file names to end in ' ' unless specific low + // level APIs are used to create the files that bypass various checks. + // File names that end in ' ' are known to cause problems when using // File#getCanonicalPath(). - if (chars[chars.length -1] == ' ') { + if (name.charAt(len -1) == ' ') { return true; } return false;
test/org/apache/catalina/webresources/TestAbstractFileResourceSetPerformance.java+28 −4 modified@@ -27,7 +27,7 @@ public class TestAbstractFileResourceSetPerformance { private static final int LOOPS = 10_000_000; /* - * Checking individual characters is about 3 times faster on markt's dev + * Checking individual characters is about 10 times faster on markt's dev * PC for typical length file names. The file names need to get to ~65 * characters before the Pattern matching is faster. */ @@ -36,22 +36,31 @@ public void testFileNameFiltering() { long start = System.nanoTime(); for (int i = 0; i < LOOPS; i++) { - UNSAFE_WINDOWS_FILENAME_PATTERN.matcher("testfile.jsp ").matches(); + UNSAFE_WINDOWS_FILENAME_PATTERN.matcher("testfile.jsp ").find(); } long end = System.nanoTime(); System.out.println("Regular expression took " + (end - start) + "ns or " + (end-start)/LOOPS + "ns per iteration"); start = System.nanoTime(); for (int i = 0; i < LOOPS; i++) { - checkForBadChars("testfile.jsp "); + checkForBadCharsArray("testfile.jsp "); } end = System.nanoTime(); System.out.println("char[] check took " + (end - start) + "ns or " + (end-start)/LOOPS + "ns per iteration"); + + start = System.nanoTime(); + for (int i = 0; i < LOOPS; i++) { + checkForBadCharsAt("testfile.jsp "); + } + end = System.nanoTime(); + System.out.println("charAt() check took " + (end - start) + "ns or " + + (end-start)/LOOPS + "ns per iteration"); + } - private boolean checkForBadChars(String filename) { + private boolean checkForBadCharsArray(String filename) { char[] chars = filename.toCharArray(); for (char c : chars) { if (c == '\"' || c == '<' || c == '>') { @@ -63,4 +72,19 @@ private boolean checkForBadChars(String filename) { } return true; } + + + private boolean checkForBadCharsAt(String filename) { + final int len = filename.length(); + for (int i = 0; i < len; i++) { + char c = filename.charAt(i); + if (c == '\"' || c == '<' || c == '>') { + return false; + } + } + if (filename.charAt(len - 1) == ' ') { + return false; + } + return true; + } }
31e99502e2c6Cache the value earlier. Followup to r1809684
1 file changed · +2 −2
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+2 −2 modified@@ -136,12 +136,12 @@ protected final File file(String name, boolean mustExist) { private boolean isInvalidWindowsFilename(String name) { - if (name.length() == 0) { + final int len = name.length(); + if (len == 0) { return false; } // This consistently ~10 times faster than the equivalent regular // expression irrespective of input length. - final int len = name.length(); for (int i = 0; i < len; i++) { char c = name.charAt(i); if (c == '\"' || c == '<' || c == '>') {
e650cf1b83e4Updates after kkolinko review
2 files changed · +37 −13
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+9 −9 modified@@ -139,11 +139,11 @@ private boolean isInvalidWindowsFilename(String name) { if (name.length() == 0) { return false; } - // For typical length file names, this is 2-3 times faster than the - // equivalent regular expression. The cut-over point is file names (not - // full paths) of ~65 characters. - char[] chars = name.toCharArray(); - for (char c : chars) { + // This consistently ~10 times faster than the equivalent regular + // expression irrespective of input length. + final int len = name.length(); + for (int i = 0; i < len; i++) { + char c = name.charAt(i); if (c == '\"' || c == '<' || c == '>') { // These characters are disallowed in Windows file names and // there are known problems for file names with these characters @@ -154,11 +154,11 @@ private boolean isInvalidWindowsFilename(String name) { return true; } } - // Windows does allow file names to end in ' ' unless specific low level - // APIs are used to create the files that bypass various checks. File - // names that end in ' ' are known to cause problems when using + // Windows does not allow file names to end in ' ' unless specific low + // level APIs are used to create the files that bypass various checks. + // File names that end in ' ' are known to cause problems when using // File#getCanonicalPath(). - if (chars[chars.length -1] == ' ') { + if (name.charAt(len -1) == ' ') { return true; } return false;
test/org/apache/catalina/webresources/TestAbstractFileResourceSetPerformance.java+28 −4 modified@@ -27,7 +27,7 @@ public class TestAbstractFileResourceSetPerformance { private static final int LOOPS = 10_000_000; /* - * Checking individual characters is about 3 times faster on markt's dev + * Checking individual characters is about 10 times faster on markt's dev * PC for typical length file names. The file names need to get to ~65 * characters before the Pattern matching is faster. */ @@ -36,22 +36,31 @@ public void testFileNameFiltering() { long start = System.nanoTime(); for (int i = 0; i < LOOPS; i++) { - UNSAFE_WINDOWS_FILENAME_PATTERN.matcher("testfile.jsp ").matches(); + UNSAFE_WINDOWS_FILENAME_PATTERN.matcher("testfile.jsp ").find(); } long end = System.nanoTime(); System.out.println("Regular expression took " + (end - start) + "ns or " + (end-start)/LOOPS + "ns per iteration"); start = System.nanoTime(); for (int i = 0; i < LOOPS; i++) { - checkForBadChars("testfile.jsp "); + checkForBadCharsArray("testfile.jsp "); } end = System.nanoTime(); System.out.println("char[] check took " + (end - start) + "ns or " + (end-start)/LOOPS + "ns per iteration"); + + start = System.nanoTime(); + for (int i = 0; i < LOOPS; i++) { + checkForBadCharsAt("testfile.jsp "); + } + end = System.nanoTime(); + System.out.println("charAt() check took " + (end - start) + "ns or " + + (end-start)/LOOPS + "ns per iteration"); + } - private boolean checkForBadChars(String filename) { + private boolean checkForBadCharsArray(String filename) { char[] chars = filename.toCharArray(); for (char c : chars) { if (c == '\"' || c == '<' || c == '>') { @@ -63,4 +72,19 @@ private boolean checkForBadChars(String filename) { } return true; } + + + private boolean checkForBadCharsAt(String filename) { + final int len = filename.length(); + for (int i = 0; i < len; i++) { + char c = filename.charAt(i); + if (c == '\"' || c == '<' || c == '>') { + return false; + } + } + if (filename.charAt(len - 1) == ' ') { + return false; + } + return true; + } }
1 file changed · +3 −0
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+3 −0 modified@@ -136,6 +136,9 @@ protected final File file(String name, boolean mustExist) { private boolean isInvalidWindowsFilename(String name) { + if (name.length() == 0) { + return false; + } // For typical length file names, this is 2-3 times faster than the // equivalent regular expression. The cut-over point is file names (not // full paths) of ~65 characters.
1 file changed · +3 −0
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+3 −0 modified@@ -136,6 +136,9 @@ protected final File file(String name, boolean mustExist) { private boolean isInvalidWindowsFilename(String name) { + if (name.length() == 0) { + return false; + } // For typical length file names, this is 2-3 times faster than the // equivalent regular expression. The cut-over point is file names (not // full paths) of ~65 characters.
d5b170705d24Add some additional checks required on Windows to keep all the checks in one place and to avoid exceptions later in the processing.
4 files changed · +170 −0
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+35 −0 modified@@ -22,6 +22,7 @@ import java.net.URL; import org.apache.catalina.LifecycleException; +import org.apache.tomcat.util.compat.JrePlatform; import org.apache.tomcat.util.http.RequestUtil; public abstract class AbstractFileResourceSet extends AbstractResourceSet { @@ -77,6 +78,12 @@ protected final File file(String name, boolean mustExist) { return file; } + // Additional Windows specific checks to handle known problems with + // File.getCanonicalPath() + if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) { + return null; + } + // Check that this file is located under the WebResourceSet's base String canPath = null; try { @@ -127,6 +134,34 @@ protected final File file(String name, boolean mustExist) { return file; } + + private boolean isInvalidWindowsFilename(String name) { + // For typical length file names, this is 2-3 times faster than the + // equivalent regular expression. The cut-over point is file names (not + // full paths) of ~65 characters. + char[] chars = name.toCharArray(); + for (char c : chars) { + if (c == '\"' || c == '<' || c == '>') { + // These characters are disallowed in Windows file names and + // there are known problems for file names with these characters + // when using File#getCanonicalPath(). + // Note: There are additional characters that are disallowed in + // Windows file names but these are not known to cause + // problems when using File#getCanonicalPath(). + return true; + } + } + // Windows does allow file names to end in ' ' unless specific low level + // APIs are used to create the files that bypass various checks. File + // names that end in ' ' are known to cause problems when using + // File#getCanonicalPath(). + if (chars[chars.length -1] == ' ') { + return true; + } + return false; + } + + /** * Return a context-relative path, beginning with a "/", that represents * the canonical version of the specified path after ".." and "." elements
java/org/apache/tomcat/util/compat/JrePlatform.java+59 −0 added@@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.compat; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class JrePlatform { + + private static final String OS_NAME_PROPERTY = "os.name"; + private static final String OS_NAME_WINDOWS_PREFIX = "Windows"; + + static { + /* + * There are a few places where a) the behaviour of the Java API depends + * on the underlying platform and b) those behavioural differences have + * an impact on Tomcat. + * + * Tomcat therefore needs to be able to determine the platform it is + * running on to account for those differences. + * + * In an ideal world this code would not exist. + */ + + // This check is derived from the check in Apache Commons Lang + String osName; + if (System.getSecurityManager() == null) { + osName = System.getProperty(OS_NAME_PROPERTY); + } else { + osName = AccessController.doPrivileged( + new PrivilegedAction<String>() { + + @Override + public String run() { + return System.getProperty(OS_NAME_PROPERTY); + } + }); + } + + IS_WINDOWS = osName.startsWith(OS_NAME_WINDOWS_PREFIX); + } + + + public static final boolean IS_WINDOWS; +}
test/org/apache/catalina/webresources/TestAbstractFileResourceSetPerformance.java+66 −0 added@@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.catalina.webresources; + +import java.util.regex.Pattern; + +import org.junit.Test; + +public class TestAbstractFileResourceSetPerformance { + + private static final Pattern UNSAFE_WINDOWS_FILENAME_PATTERN = Pattern.compile(" $|[\"<>]"); + + private static final int LOOPS = 10_000_000; + + /* + * Checking individual characters is about 3 times faster on markt's dev + * PC for typical length file names. The file names need to get to ~65 + * characters before the Pattern matching is faster. + */ + @Test + public void testFileNameFiltering() { + + long start = System.nanoTime(); + for (int i = 0; i < LOOPS; i++) { + UNSAFE_WINDOWS_FILENAME_PATTERN.matcher("testfile.jsp ").matches(); + } + long end = System.nanoTime(); + System.out.println("Regular expression took " + (end - start) + "ns or " + + (end-start)/LOOPS + "ns per iteration"); + + start = System.nanoTime(); + for (int i = 0; i < LOOPS; i++) { + checkForBadChars("testfile.jsp "); + } + end = System.nanoTime(); + System.out.println("char[] check took " + (end - start) + "ns or " + + (end-start)/LOOPS + "ns per iteration"); + } + + private boolean checkForBadChars(String filename) { + char[] chars = filename.toCharArray(); + for (char c : chars) { + if (c == '\"' || c == '<' || c == '>') { + return false; + } + } + if (chars[chars.length -1] == ' ') { + return false; + } + return true; + } +}
webapps/docs/changelog.xml+10 −0 modified@@ -45,6 +45,16 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 8.5.23 (markt)" rtext="in development"> + <subsection name="Catalina"> + <changelog> + <fix> + Add additional validation to the resource handling required to fix + CVE-2017-12617 on Windows. The checks were being performed elsewhere but + adding them to the resource handling ensures that the checks are always + performed. (markt) + </fix> + </changelog> + </subsection> <subsection name="Other"> <changelog> <fix>
a9dd96046d7aAdd some additional checks required on Windows to keep all the checks in one place and to avoid exceptions later in the processing.
3 files changed · +160 −0
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+35 −0 modified@@ -22,6 +22,7 @@ import java.net.URL; import org.apache.catalina.LifecycleException; +import org.apache.tomcat.util.compat.JrePlatform; import org.apache.tomcat.util.http.RequestUtil; public abstract class AbstractFileResourceSet extends AbstractResourceSet { @@ -77,6 +78,12 @@ protected final File file(String name, boolean mustExist) { return file; } + // Additional Windows specific checks to handle known problems with + // File.getCanonicalPath() + if (JrePlatform.IS_WINDOWS && isInvalidWindowsFilename(name)) { + return null; + } + // Check that this file is located under the WebResourceSet's base String canPath = null; try { @@ -127,6 +134,34 @@ protected final File file(String name, boolean mustExist) { return file; } + + private boolean isInvalidWindowsFilename(String name) { + // For typical length file names, this is 2-3 times faster than the + // equivalent regular expression. The cut-over point is file names (not + // full paths) of ~65 characters. + char[] chars = name.toCharArray(); + for (char c : chars) { + if (c == '\"' || c == '<' || c == '>') { + // These characters are disallowed in Windows file names and + // there are known problems for file names with these characters + // when using File#getCanonicalPath(). + // Note: There are additional characters that are disallowed in + // Windows file names but these are not known to cause + // problems when using File#getCanonicalPath(). + return true; + } + } + // Windows does allow file names to end in ' ' unless specific low level + // APIs are used to create the files that bypass various checks. File + // names that end in ' ' are known to cause problems when using + // File#getCanonicalPath(). + if (chars[chars.length -1] == ' ') { + return true; + } + return false; + } + + /** * Return a context-relative path, beginning with a "/", that represents * the canonical version of the specified path after ".." and "." elements
java/org/apache/tomcat/util/compat/JrePlatform.java+59 −0 added@@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.compat; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +public class JrePlatform { + + private static final String OS_NAME_PROPERTY = "os.name"; + private static final String OS_NAME_WINDOWS_PREFIX = "Windows"; + + static { + /* + * There are a few places where a) the behaviour of the Java API depends + * on the underlying platform and b) those behavioural differences have + * an impact on Tomcat. + * + * Tomcat therefore needs to be able to determine the platform it is + * running on to account for those differences. + * + * In an ideal world this code would not exist. + */ + + // This check is derived from the check in Apache Commons Lang + String osName; + if (System.getSecurityManager() == null) { + osName = System.getProperty(OS_NAME_PROPERTY); + } else { + osName = AccessController.doPrivileged( + new PrivilegedAction<String>() { + + @Override + public String run() { + return System.getProperty(OS_NAME_PROPERTY); + } + }); + } + + IS_WINDOWS = osName.startsWith(OS_NAME_WINDOWS_PREFIX); + } + + + public static final boolean IS_WINDOWS; +}
test/org/apache/catalina/webresources/TestAbstractFileResourceSetPerformance.java+66 −0 added@@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.catalina.webresources; + +import java.util.regex.Pattern; + +import org.junit.Test; + +public class TestAbstractFileResourceSetPerformance { + + private static final Pattern UNSAFE_WINDOWS_FILENAME_PATTERN = Pattern.compile(" $|[\"<>]"); + + private static final int LOOPS = 10_000_000; + + /* + * Checking individual characters is about 3 times faster on markt's dev + * PC for typical length file names. The file names need to get to ~65 + * characters before the Pattern matching is faster. + */ + @Test + public void testFileNameFiltering() { + + long start = System.nanoTime(); + for (int i = 0; i < LOOPS; i++) { + UNSAFE_WINDOWS_FILENAME_PATTERN.matcher("testfile.jsp ").matches(); + } + long end = System.nanoTime(); + System.out.println("Regular expression took " + (end - start) + "ns or " + + (end-start)/LOOPS + "ns per iteration"); + + start = System.nanoTime(); + for (int i = 0; i < LOOPS; i++) { + checkForBadChars("testfile.jsp "); + } + end = System.nanoTime(); + System.out.println("char[] check took " + (end - start) + "ns or " + + (end-start)/LOOPS + "ns per iteration"); + } + + private boolean checkForBadChars(String filename) { + char[] chars = filename.toCharArray(); + for (char c : chars) { + if (c == '\"' || c == '<' || c == '>') { + return false; + } + } + if (chars[chars.length -1] == ' ') { + return false; + } + return true; + } +}
327e8a6644e1Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61542
2 files changed · +12 −2
java/org/apache/naming/resources/FileDirContext.java+7 −2 modified@@ -476,11 +476,16 @@ public void modifyAttributes(String name, ModificationItem[] mods) * @exception NamingException if a naming exception is encountered */ @Override - public void bind(String name, Object obj, Attributes attrs) - throws NamingException { + public void bind(String name, Object obj, Attributes attrs) throws NamingException { // Note: No custom attributes allowed + // bind() is meant to create a file so ensure that the path doesn't end + // in '/' + if (name.endsWith("/")) { + throw new NamingException(sm.getString("resources.bindFailed", name)); + } + File file = file(name, false); if (file == null) { throw new NamingException(sm.getString("resources.bindFailed", name));
webapps/docs/changelog.xml+5 −0 modified@@ -90,6 +90,11 @@ <code>DirContext</code> that represented the web application in a <code>ProxyDirContext</code> twice rather than just once. (markt) </fix> + <fix> + <bug>61542</bug>: Fix CVE-2017-12617 and prevent JSPs from being + uploaded via a specially crafted request when HTTP PUT was enabled. + (markt) + </fix> </changelog> </subsection> <subsection name="Coyote">
512a3c3aecdbPartial fix for CVE-2017-12617
4 files changed · +64 −28
java/org/apache/catalina/servlets/DefaultServlet.java+0 −17 modified@@ -860,23 +860,6 @@ protected void serveResource(HttpServletRequest request, return; } - // If the resource is not a collection, and the resource path - // ends with "/" or "\", return NOT FOUND - if (cacheEntry.context == null) { - if (path.endsWith("/") || (path.endsWith("\\"))) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND, - requestUri); - return; - } - } - // Check if the conditions specified in the optional If headers are // satisfied. if (cacheEntry.context == null) {
java/org/apache/naming/resources/FileDirContext.java+9 −2 modified@@ -801,11 +801,18 @@ protected File file(String name) { */ protected File file(String name, boolean mustExist) { File file = new File(base, name); - return validate(file, mustExist, absoluteBase); + return validate(file, name, mustExist, absoluteBase); } - protected File validate(File file, boolean mustExist, String absoluteBase) { + protected File validate(File file, String name, boolean mustExist, String absoluteBase) { + + // If the requested names ends in '/', the Java File API will return a + // matching file if one exists. This isn't what we want as it is not + // consistent with the Servlet spec rules for request mapping. + if (file.isFile() && name.endsWith("/")) { + return null; + } if (!mustExist || file.exists() && file.canRead()) {
java/org/apache/naming/resources/VirtualDirContext.java+9 −9 modified@@ -163,16 +163,16 @@ public Attributes getAttributes(String name) throws NamingException { String resourcesDir = dirList.get(0); if (name.equals(path)) { File f = new File(resourcesDir); - f = validate(f, true, resourcesDir); + f = validate(f, name, true, resourcesDir); if (f != null) { return new FileResourceAttributes(f); } } path += "/"; if (name.startsWith(path)) { String res = name.substring(path.length()); - File f = new File(resourcesDir + "/" + res); - f = validate(f, true, resourcesDir); + File f = new File(resourcesDir, res); + f = validate(f, res, true, resourcesDir); if (f != null) { return new FileResourceAttributes(f); } @@ -206,7 +206,7 @@ protected File file(String name, boolean mustExist) { if (name.equals(path)) { for (String resourcesDir : dirList) { file = new File(resourcesDir); - file = validate(file, true, resourcesDir); + file = validate(file, name, true, resourcesDir); if (file != null) { return file; } @@ -216,7 +216,7 @@ protected File file(String name, boolean mustExist) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { file = new File(resourcesDir, res); - file = validate(file, true, resourcesDir); + file = validate(file, res, true, resourcesDir); if (file != null) { return file; } @@ -252,7 +252,7 @@ protected List<NamingEntry> list(File file) { if (res != null) { for (String resourcesDir : dirList) { File f = new File(resourcesDir, res); - f = validate(f, true, resourcesDir); + f = validate(f, res, true, resourcesDir); if (f != null && f.isDirectory()) { List<NamingEntry> virtEntries = super.list(f); for (NamingEntry entry : virtEntries) { @@ -288,7 +288,7 @@ protected Object doLookup(String name) { if (name.equals(path)) { for (String resourcesDir : dirList) { File f = new File(resourcesDir); - f = validate(f, true, resourcesDir); + f = validate(f, name, true, resourcesDir); if (f != null) { if (f.isFile()) { return new FileResource(f); @@ -304,8 +304,8 @@ protected Object doLookup(String name) { if (name.startsWith(path)) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { - File f = new File(resourcesDir + "/" + res); - f = validate(f, true, resourcesDir); + File f = new File(resourcesDir, res); + f = validate(f, res, true, resourcesDir); if (f != null) { if (f.isFile()) { return new FileResource(f);
test/org/apache/naming/resources/TestFileDirContext.java+46 −0 added@@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.naming.resources; + +import java.io.File; + +import javax.servlet.http.HttpServletResponse; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.buf.ByteChunk; + +public class TestFileDirContext extends TomcatBaseTest { + + @Test + public void testLookupResourceWithTrailingSlash() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0"); + // app dir is relative to server home + tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); + + tomcat.start(); + + int sc = getUrl("http://localhost:" + getPort() + + "/test/index.html/", new ByteChunk(), null); + Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, sc); + } +}
4cf7dab88282Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61542
3 files changed · +20 −7
java/org/apache/catalina/webresources/DirResourceSet.java+6 −0 modified@@ -217,6 +217,12 @@ public boolean write(String path, InputStream is, boolean overwrite) { return false; } + // write() is meant to create a file so ensure that the path doesn't + // end in '/' + if (path.endsWith("/")) { + return false; + } + File dest = null; String webAppMount = getWebAppMount(); if (path.startsWith(webAppMount)) {
test/org/apache/catalina/webresources/AbstractTestResourceSet.java+9 −7 modified@@ -447,14 +447,8 @@ public final void testWriteDirA() { public final void testWriteDirB() { WebResource d1 = resourceRoot.getResource(getMount() + "/d1/"); InputStream is = new ByteArrayInputStream("test".getBytes()); - if (d1.exists()) { + if (d1.exists() || d1.isVirtual()) { Assert.assertFalse(resourceRoot.write(getMount() + "/d1/", is, false)); - } else if (d1.isVirtual()) { - Assert.assertTrue(resourceRoot.write( - getMount() + "/d1/", is, false)); - File file = new File(getBaseDir(), "d1"); - Assert.assertTrue(file.exists()); - Assert.assertTrue(file.delete()); } else { Assert.fail("Unhandled condition in unit test"); } @@ -490,6 +484,14 @@ public final void testWrite() { } } + @Test + public final void testWriteWithTrailingSlash() { + String newFileName = getNewFileName() + "/"; + InputStream is = new ByteArrayInputStream("test".getBytes()); + Assert.assertFalse(resourceRoot.write( + getMount() + "/" + newFileName, is, false)); + } + protected abstract String getNewFileName(); // ------------------------------------------------------ getCanonicalPath()
webapps/docs/changelog.xml+5 −0 modified@@ -57,6 +57,11 @@ Add an option to reject requests that contain HTTP headers with invalid (non-token) header names with a 400 response. (markt) </add> + <fix> + <bug>61542</bug>: Fix CVE-2017-12617 and prevent JSPs from being + uploaded via a specially crafted request when HTTP PUT was enabled. + (markt) + </fix> </changelog> </subsection> <subsection name="Coyote">
506d862e7edfPartial fix for CVE-2017-12617
3 files changed · +15 −14
java/org/apache/catalina/servlets/DefaultServlet.java+0 −14 modified@@ -804,20 +804,6 @@ protected void serveResource(HttpServletRequest request, return; } - // If the resource is not a collection, and the resource path - // ends with "/" or "\", return NOT FOUND - if (resource.isFile() && (path.endsWith("/") || path.endsWith("\\"))) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri); - return; - } - boolean included = false; // Check if the conditions specified in the optional If headers are // satisfied.
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+8 −0 modified@@ -57,6 +57,14 @@ protected final File file(String name, boolean mustExist) { name = ""; } File file = new File(fileBase, name); + + // If the requested names ends in '/', the Java File API will return a + // matching file if one exists. This isn't what we want as it is not + // consistent with the Servlet spec rules for request mapping. + if (file.isFile() && name.endsWith("/")) { + return null; + } + if (!mustExist || file.canRead()) { if (getRoot().getAllowLinking()) {
test/org/apache/catalina/webresources/AbstractTestResourceSet.java+7 −0 modified@@ -131,6 +131,13 @@ public final void testGetResourceFile() { Assert.assertNotNull(webResource.getInputStream()); } + @Test + public final void testGetResourceFileWithTrailingSlash() { + WebResource webResource = + resourceRoot.getResource(getMount() + "/d1/d1-f1.txt/"); + Assert.assertFalse(webResource.exists()); + } + @Test public final void testGetResourceCaseSensitive() { WebResource webResource =
b7e0435d17abPartial fix for CVE-2017-12617
3 files changed · +24 −7
java/org/apache/catalina/webresources/DirResourceSet.java+6 −0 modified@@ -217,6 +217,12 @@ public boolean write(String path, InputStream is, boolean overwrite) { return false; } + // write() is meant to create a file so ensure that the path doesn't + // end in '/' + if (path.endsWith("/")) { + return false; + } + File dest = null; String webAppMount = getWebAppMount(); if (path.startsWith(webAppMount)) {
test/org/apache/catalina/webresources/AbstractTestResourceSet.java+9 −7 modified@@ -447,14 +447,8 @@ public final void testWriteDirA() { public final void testWriteDirB() { WebResource d1 = resourceRoot.getResource(getMount() + "/d1/"); InputStream is = new ByteArrayInputStream("test".getBytes()); - if (d1.exists()) { + if (d1.exists() || d1.isVirtual()) { Assert.assertFalse(resourceRoot.write(getMount() + "/d1/", is, false)); - } else if (d1.isVirtual()) { - Assert.assertTrue(resourceRoot.write( - getMount() + "/d1/", is, false)); - File file = new File(getBaseDir(), "d1"); - Assert.assertTrue(file.exists()); - Assert.assertTrue(file.delete()); } else { Assert.fail("Unhandled condition in unit test"); } @@ -490,6 +484,14 @@ public final void testWrite() { } } + @Test + public final void testWriteWithTrailingSlash() { + String newFileName = getNewFileName() + "/"; + InputStream is = new ByteArrayInputStream("test".getBytes()); + Assert.assertFalse(resourceRoot.write( + getMount() + "/" + newFileName, is, false)); + } + protected abstract String getNewFileName(); // ------------------------------------------------------ getCanonicalPath()
webapps/docs/changelog.xml+9 −0 modified@@ -45,6 +45,15 @@ issues do not "pop up" wrt. others). --> <section name="Tomcat 9.0.0.M28 (markt)" rtext="in development"> + <subsection name="Catalina"> + <changelog> + <fix> + <bug>61542</bug>: Fix CVE-2017-12617 and prevent JSPs from being + uploaded via a specially crafted request when HTTP PUT was enabled. + (markt) + </fix> + </changelog> + </subsection> <subsection name="Coyote"> <changelog> <add>
b577f9a7996bFix https://bz.apache.org/bugzilla/show_bug.cgi?id=61542
3 files changed · +15 −14
java/org/apache/catalina/servlets/DefaultServlet.java+0 −14 modified@@ -820,20 +820,6 @@ protected void serveResource(HttpServletRequest request, return; } - // If the resource is not a collection, and the resource path - // ends with "/" or "\", return NOT FOUND - if (resource.isFile() && (path.endsWith("/") || path.endsWith("\\"))) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND, requestUri); - return; - } - boolean included = false; // Check if the conditions specified in the optional If headers are // satisfied.
java/org/apache/catalina/webresources/AbstractFileResourceSet.java+8 −0 modified@@ -57,6 +57,14 @@ protected final File file(String name, boolean mustExist) { name = ""; } File file = new File(fileBase, name); + + // If the requested names ends in '/', the Java File API will return a + // matching file if one exists. This isn't what we want as it is not + // consistent with the Servlet spec rules for request mapping. + if (file.isFile() && name.endsWith("/")) { + return null; + } + if (!mustExist || file.canRead()) { if (getRoot().getAllowLinking()) {
test/org/apache/catalina/webresources/AbstractTestResourceSet.java+7 −0 modified@@ -131,6 +131,13 @@ public final void testGetResourceFile() { Assert.assertNotNull(webResource.getInputStream()); } + @Test + public final void testGetResourceFileWithTrailingSlash() { + WebResource webResource = + resourceRoot.getResource(getMount() + "/d1/d1-f1.txt/"); + Assert.assertFalse(webResource.exists()); + } + @Test public final void testGetResourceCaseSensitive() { WebResource webResource =
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
89- www.oracle.com/technetwork/security-advisory/cpuapr2018-3678067.htmlnvdPatchThird Party AdvisoryWEB
- www.oracle.com/technetwork/security-advisory/cpujan2018-3236628.htmlnvdPatchThird Party AdvisoryWEB
- www.oracle.com/technetwork/security-advisory/cpujul2018-4258247.htmlnvdPatchThird Party AdvisoryWEB
- lists.apache.org/thread.html/1dd0a59c1295cc08ce4c9e7edae5ad2268acc9ba55adcefa0532e5ba%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/343558d982879bf88ec20dbf707f8c11255f8e219e81d45c4f8d0551%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/388a323769f1dff84c9ec905455aa73fbcb20338e3c7eb131457f708%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/3d19773b4cf0377db62d1e9328bf9160bf1819f04f988315086931d7%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/5c0e00fd31efc11e147bf99d0f03c00a734447d3b131ab0818644cdb%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/6af47120905aa7d8fe12f42e8ff2284fb338ba141d3b77b8c7cb61b3%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/845312a10aabbe2c499fca94003881d2c79fc993d85f34c1f5c77424%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/88855876c33f2f9c532ffb75bfee570ccf0b17ffa77493745af9a17a%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/b5e3f51d28cd5d9b1809f56594f2cf63dcd6a90429e16ea9f83bbedc%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/e85e83e9954f169bbb77b44baae5a33d8de878df557bb32b7f793661%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/eb6efa8d59c45a7a9eff94c4b925467d3b3fec8ba7697f3daa314b04%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/r3bbb800a816d0a51eccc5a228c58736960a9fffafa581a225834d97d%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/r48c1444845fe15a823e1374674bfc297d5008a5453788099ea14caf0%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/r6ccee4e849bc77df0840c7f853f6bd09d426f6741247da2b7429d5d9%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/r9136ff5b13e4f1941360b5a309efee2c114a14855578c3a2cbe5d19c%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- lists.apache.org/thread.html/raba0fabaf4d56d4325ab2aca8814f0b30a237ab83d8106b115ee279a%40%3Cdev.tomcat.apache.org%3EnvdMailing ListPatchWEB
- www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.htmlnvdPatchThird Party AdvisoryWEB
- www.exploit-db.com/exploits/42966/nvdExploitThird Party AdvisoryVDB Entry
- www.exploit-db.com/exploits/43008/nvdExploitThird Party AdvisoryVDB Entry
- www.securityfocus.com/bid/100954nvdThird Party AdvisoryVDB EntryBroken LinkWEB
- www.securitytracker.com/id/1039552nvdThird Party AdvisoryVDB EntryBroken LinkWEB
- access.redhat.com/errata/RHSA-2017:3080nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2017:3081nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2017:3113nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2017:3114nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0268nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0269nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0270nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0271nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0275nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0465nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:0466nvdThird Party AdvisoryWEB
- access.redhat.com/errata/RHSA-2018:2939nvdThird Party AdvisoryWEB
- github.com/advisories/GHSA-xjgh-84hx-56c5ghsaADVISORY
- lists.debian.org/debian-lts-announce/2017/11/msg00009.htmlnvdMailing ListThird Party AdvisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2017-12617ghsaADVISORY
- security.netapp.com/advisory/ntap-20171018-0002/nvdThird Party Advisory
- security.netapp.com/advisory/ntap-20180117-0002/nvdThird Party Advisory
- support.f5.com/csp/article/K53173544nvdThird Party AdvisoryWEB
- support.hpe.com/hpsc/doc/public/displaynvdThird Party AdvisoryWEB
- support.hpe.com/hpsc/doc/public/displaynvdThird Party AdvisoryWEB
- usn.ubuntu.com/3665-1/nvdThird Party Advisory
- github.com/apache/tomcat/commit/24aea94807f940ee44aa550378dc903289039dddghsaWEB
- github.com/apache/tomcat/commit/31e99502e2c602449a2f8835bd23ade772b77333ghsaWEB
- github.com/apache/tomcat/commit/327e8a6644e188764325a013aa2725a60f1b37e5ghsaWEB
- github.com/apache/tomcat/commit/46dfedbc0523d7182be97f4244d7b6c942164485ghsaWEB
- github.com/apache/tomcat/commit/4cf7dab88282c8f3c92f0b961cdb0096e1d63e88ghsaWEB
- github.com/apache/tomcat/commit/506d862e7edfa991de198e0f2e4c4540830fa531ghsaWEB
- github.com/apache/tomcat/commit/512a3c3aecdb52de092c6bacddd71b85c4feda06ghsaWEB
- github.com/apache/tomcat/commit/74ad0e216c791454a318c1811300469eedc5c6f3ghsaWEB
- github.com/apache/tomcat/commit/a9dd96046d7acb0357c6b7b9e6cc70d186fae663ghsaWEB
- github.com/apache/tomcat/commit/b577f9a7996b92b650b1649af3c3bae11c120db9ghsaWEB
- github.com/apache/tomcat/commit/b7e0435d17aba69f16ae9e8a78ad0f1565b552afghsaWEB
- github.com/apache/tomcat/commit/bbcbb749c75056a2781f37038d63e646fe972104ghsaWEB
- github.com/apache/tomcat/commit/c177e9668d1278710bdb14c0eb8d2702b3655f5aghsaWEB
- github.com/apache/tomcat/commit/cf0b37beb0622abdf24acc7110daf883f3fe4f95ghsaWEB
- github.com/apache/tomcat/commit/d5b170705d24c386d76038e5989045c89795c28cghsaWEB
- github.com/apache/tomcat/commit/e650cf1b83e441dbd3863f3f6b61c972cafce19eghsaWEB
- github.com/apache/tomcat/commit/f1b85da754c4760787d68a99e839b50878140b57ghsaWEB
- github.com/apache/tomcat/commit/fd52f8601170b91f9d7162510e54563e5bf6bdfeghsaWEB
- lists.apache.org/thread.html/1dd0a59c1295cc08ce4c9e7edae5ad2268acc9ba55adcefa0532e5ba@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/343558d982879bf88ec20dbf707f8c11255f8e219e81d45c4f8d0551@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/388a323769f1dff84c9ec905455aa73fbcb20338e3c7eb131457f708@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/3d19773b4cf0377db62d1e9328bf9160bf1819f04f988315086931d7@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/3fd341a604c4e9eab39e7eaabbbac39c30101a022acc11dd09d7ebcb%40%3Cannounce.tomcat.apache.org%3EnvdIssue TrackingMailing ListWEB
- lists.apache.org/thread.html/3fd341a604c4e9eab39e7eaabbbac39c30101a022acc11dd09d7ebcb@%3Cannounce.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/5c0e00fd31efc11e147bf99d0f03c00a734447d3b131ab0818644cdb@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/6af47120905aa7d8fe12f42e8ff2284fb338ba141d3b77b8c7cb61b3@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/845312a10aabbe2c499fca94003881d2c79fc993d85f34c1f5c77424@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/88855876c33f2f9c532ffb75bfee570ccf0b17ffa77493745af9a17a@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/b5e3f51d28cd5d9b1809f56594f2cf63dcd6a90429e16ea9f83bbedc@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/e85e83e9954f169bbb77b44baae5a33d8de878df557bb32b7f793661@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/eb6efa8d59c45a7a9eff94c4b925467d3b3fec8ba7697f3daa314b04@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r3bbb800a816d0a51eccc5a228c58736960a9fffafa581a225834d97d@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r48c1444845fe15a823e1374674bfc297d5008a5453788099ea14caf0@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r6ccee4e849bc77df0840c7f853f6bd09d426f6741247da2b7429d5d9@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/r9136ff5b13e4f1941360b5a309efee2c114a14855578c3a2cbe5d19c@%3Cdev.tomcat.apache.org%3EghsaWEB
- lists.apache.org/thread.html/raba0fabaf4d56d4325ab2aca8814f0b30a237ab83d8106b115ee279a@%3Cdev.tomcat.apache.org%3EghsaWEB
- security.netapp.com/advisory/ntap-20171018-0002ghsaWEB
- security.netapp.com/advisory/ntap-20180117-0002ghsaWEB
- usn.ubuntu.com/3665-1ghsaWEB
- web.archive.org/web/20171110171954/http://www.securityfocus.com/bid/100954ghsaWEB
- web.archive.org/web/20201209024734/http://www.securitytracker.com/id/1039552ghsaWEB
- www.cisa.gov/known-exploited-vulnerabilities-catalognvdUS Government ResourceWEB
- www.exploit-db.com/exploits/42966ghsaWEB
- www.exploit-db.com/exploits/43008ghsaWEB
News mentions
0No linked articles in our index yet.