Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 37 additions & 18 deletions common/models/shipping/Ups.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,25 @@ function getQuote($address)

// $fetch_accountrates = ($this->config->get('shipping_hitups_auto_rate_type') == 'ACCOUNT') ? "<PaymentAccountNumber>" . $custom_settings[$key]['ups_acc_no'] . "</PaymentAccountNumber>" : "";

$ups_access_key = $this->escapeXmlValue($custom_settings[$key]['ups_access_key']);
$ups_id = $this->escapeXmlValue($custom_settings[$key]['ups_id']);
$ups_pass = $this->escapeXmlValue($custom_settings[$key]['ups_pass']);
$ups_account = $this->escapeXmlValue($custom_settings[$key]['ups_acc_no']);
$shipper_name = $this->escapeXmlValue($custom_settings[$key]['ups_ship_name']);
$ship_city = $this->escapeXmlValue($custom_settings[$key]['ups_ship_city']);
$ship_state = $this->escapeXmlValue($custom_settings[$key]['ups_ship_state']);
$ship_country = $this->escapeXmlValue($custom_settings[$key]['ups_ship_country']);
$ship_postcode = $this->escapeXmlValue($custom_settings[$key]['ups_ship_zip']);
$destination_city = $this->escapeXmlValue($address['city']);
$destination_state = $this->escapeXmlValue($address['zone_code']);
$destination_country = $this->escapeXmlValue($address['iso_code_2']);
$destination_postcode = $this->escapeXmlValue($address['postcode']);

$xml = '<?xml version="1.0"?>';
$xml .= '<AccessRequest xml:lang="en-US">';
$xml .= ' <AccessLicenseNumber>' . $custom_settings[$key]['ups_access_key'] . '</AccessLicenseNumber>';
$xml .= ' <UserId>' . $custom_settings[$key]['ups_id'] . '</UserId>';
$xml .= ' <Password>' . $custom_settings[$key]['ups_pass'] . '</Password>';
$xml .= ' <AccessLicenseNumber>' . $ups_access_key . '</AccessLicenseNumber>';
$xml .= ' <UserId>' . $ups_id . '</UserId>';
$xml .= ' <Password>' . $ups_pass . '</Password>';
$xml .= '</AccessRequest>';
$xml .= '<?xml version="1.0"?>';
$xml .= '<RatingServiceSelectionRequest xml:lang="en-US">';
Expand All @@ -251,29 +265,29 @@ function getQuote($address)
$xml .= ' </Request>';
$xml .= ' <Shipment>';
$xml .= ' <Shipper>';
$xml .= ' <Name>' . $custom_settings[$key]['ups_ship_name'] . '</Name>';
$xml .= ' <ShipperNumber>' . $custom_settings[$key]['ups_acc_no'] . '</ShipperNumber>';
$xml .= ' <Name>' . $shipper_name . '</Name>';
$xml .= ' <ShipperNumber>' . $ups_account . '</ShipperNumber>';
$xml .= ' <Address>';
$xml .= ' <City>' . $custom_settings[$key]['ups_ship_city'] . '</City>';
$xml .= ' <StateProvinceCode>' . $custom_settings[$key]['ups_ship_state'] . '</StateProvinceCode>';
$xml .= ' <CountryCode>' . $custom_settings[$key]['ups_ship_country'] . '</CountryCode>';
$xml .= ' <PostalCode>' . $custom_settings[$key]['ups_ship_zip'] . '</PostalCode>';
$xml .= ' <City>' . $ship_city . '</City>';
$xml .= ' <StateProvinceCode>' . $ship_state . '</StateProvinceCode>';
$xml .= ' <CountryCode>' . $ship_country . '</CountryCode>';
$xml .= ' <PostalCode>' . $ship_postcode . '</PostalCode>';
$xml .= ' </Address>';
$xml .= ' </Shipper>';
$xml .= ' <ShipTo>';
$xml .= ' <Address>';
$xml .= ' <City>' . $address['city'] . '</City>';
$xml .= ' <StateProvinceCode>' . $address['zone_code'] . '</StateProvinceCode>';
$xml .= ' <CountryCode>' . $address['iso_code_2'] . '</CountryCode>';
$xml .= ' <PostalCode>' . $address['postcode'] . '</PostalCode>';
$xml .= ' <City>' . $destination_city . '</City>';
$xml .= ' <StateProvinceCode>' . $destination_state . '</StateProvinceCode>';
$xml .= ' <CountryCode>' . $destination_country . '</CountryCode>';
$xml .= ' <PostalCode>' . $destination_postcode . '</PostalCode>';
$xml .= ' </Address>';
$xml .= ' </ShipTo>';
$xml .= ' <ShipFrom>';
$xml .= ' <Address>';
$xml .= ' <City>' . $custom_settings[$key]['ups_ship_city'] . '</City>';
$xml .= ' <StateProvinceCode>' . $custom_settings[$key]['ups_ship_state'] . '</StateProvinceCode>';
$xml .= ' <CountryCode>' . $custom_settings[$key]['ups_ship_country'] . '</CountryCode>';
$xml .= ' <PostalCode>' . $custom_settings[$key]['ups_ship_zip'] . '</PostalCode>';
$xml .= ' <City>' . $ship_city . '</City>';
$xml .= ' <StateProvinceCode>' . $ship_state . '</StateProvinceCode>';
$xml .= ' <CountryCode>' . $ship_country . '</CountryCode>';
$xml .= ' <PostalCode>' . $ship_postcode . '</PostalCode>';
$xml .= ' </Address>';
$xml .= ' </ShipFrom>';
$xml .= $packages_xml;
Expand Down Expand Up @@ -392,6 +406,11 @@ function getQuote($address)
return $method_data;
}

private function escapeXmlValue($value)
{
return htmlspecialchars((string) $value, ENT_XML1 | ENT_QUOTES, 'UTF-8');
}

public function getDefaultVenConfig($vendor_id = "default"){
$custom_settings['ups_id'] = $this->config->get('shipping_hitups_auto_key');
$custom_settings['ups_pass'] = $this->config->get('shipping_hitups_auto_password');
Expand All @@ -409,4 +428,4 @@ public function getDefaultVenConfig($vendor_id = "default"){
$custom_settings['ups_ship_country'] = $this->config->get('shipping_hitups_auto_country_code');
return $custom_settings;
}
}
}
33 changes: 33 additions & 0 deletions tests/check-ups-rate-xml-escaping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from pathlib import Path


ups = Path("common/models/shipping/Ups.php")
source = ups.read_text(encoding="utf-8")

required_snippets = [
"private function escapeXmlValue($value)",
"htmlspecialchars((string) $value, ENT_XML1 | ENT_QUOTES, 'UTF-8')",
"$ups_access_key = $this->escapeXmlValue($custom_settings[$key]['ups_access_key']);",
"$ship_city = $this->escapeXmlValue($custom_settings[$key]['ups_ship_city']);",
"$destination_city = $this->escapeXmlValue($address['city']);",
"'\t<AccessLicenseNumber>' . $ups_access_key . '</AccessLicenseNumber>'",
"'\t\t<Name>' . $shipper_name . '</Name>'",
"'\t\t\t\t<City>' . $destination_city . '</City>'",
]

missing = [snippet for snippet in required_snippets if snippet not in source]
if missing:
raise SystemExit(
"UPS rate XML is missing expected escaping snippets: " + ", ".join(missing)
)

unsafe_snippets = [
"'\t<AccessLicenseNumber>' . $custom_settings[$key]['ups_access_key']",
"'\t\t<Name>' . $custom_settings[$key]['ups_ship_name']",
"'\t\t\t\t<City>' . $custom_settings[$key]['ups_ship_city']",
"' \t\t\t\t<City>' . $address['city']",
]

for unsafe_snippet in unsafe_snippets:
if unsafe_snippet in source:
raise SystemExit(f"UPS rate XML still writes raw value: {unsafe_snippet}")