Skip to content

Escape shipping postcode city XML fields#326

Open
haradahinata wants to merge 2 commits into
BAWES-Universe:mainfrom
haradahinata:codex/escape-shipping-postcode-city-xml
Open

Escape shipping postcode city XML fields#326
haradahinata wants to merge 2 commits into
BAWES-Universe:mainfrom
haradahinata:codex/escape-shipping-postcode-city-xml

Conversation

@haradahinata
Copy link
Copy Markdown

@haradahinata haradahinata commented May 17, 2026

Summary

  • XML-escape postcode and city values before ShippingHelper::get_postcode_city() builds DHL/Aramex address fragments
  • preserve the existing no-postcode-country behavior and the current empty-city omission behavior
  • add a focused static guard so raw postcode/city interpolation is not reintroduced

/claim #59

Why this satisfies the bounty

Carrier rate requests are part of keeping the store platform running reliably at scale. The helper currently writes raw address values directly into XML, so customer/store cities or postcodes containing characters such as &, <, >, quotes, or apostrophes can produce malformed DHL/Aramex request XML. Escaping the fields keeps the generated XML valid without changing the carrier flow.

Existing PRs checked

  • Harden shipping package errors #319 hardens shipping package packing errors in the same helper, but it does not touch the postcode/city XML fragment.
  • I searched open PRs for shipping XML/postcode/city escaping and did not find a duplicate for this helper.

Validation

  • C:\Users\Harada Hinata\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe tests\check-shipping-helper-xml-escaping.py
  • C:\Users\Harada Hinata\.cache\codex-runtimes\codex-primary-runtime\dependencies\python\python.exe -m py_compile tests\check-shipping-helper-xml-escaping.py
  • git diff --cached --check

php -l common/models/shipping/util/ShippingHelper.php could not be run locally because PHP is not installed in this environment.

Summary by CodeRabbit

  • Bug Fixes

    • Strengthened security in shipping operations by implementing proper escaping for postal codes and city information to prevent potential injection vulnerabilities and ensure safer data transmission when processing customer orders.
  • Tests

    • Added automated testing to verify and ensure that security escaping measures are correctly implemented, properly functioning, and maintained within the shipping module.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Warning

Rate limit exceeded

@haradahinata has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 41 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3dadd3b6-d1de-4625-a9f3-5b327994a648

📥 Commits

Reviewing files that changed from the base of the PR and between eee6b26 and 1f42c0e.

📒 Files selected for processing (1)
  • tests/check-shipping-helper-xml-escaping.py
📝 Walkthrough

Walkthrough

This PR hardens XML output generation in shipping utilities by adding XML-escaping to the get_postcode_city method in ShippingHelper, preventing XML injection attacks. A new Python test script validates that the escaping is correctly applied and raw values are not leaked into XML output.

Changes

XML Escaping for Shipping Data

Layer / File(s) Summary
XML escaping implementation in ShippingHelper
common/models/shipping/util/ShippingHelper.php
The get_postcode_city method now applies htmlspecialchars(..., ENT_XML1 | ENT_QUOTES, 'UTF-8') to both $postcode and $city before constructing the <Postalcode> and <City> XML output, preventing XML injection through user-supplied location data.
XML escaping validation test
tests/check-shipping-helper-xml-escaping.py
A Python validation script checks that the required escaping function calls are present for both postcode and city, and scans for any unsafe patterns where raw unescaped values are directly interpolated into XML tags.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A shipping postcode once posed a risk,
Raw XML made the syntax brisk,
But escaping is here, with ENT_XML1,
No injection shall break, the test makes it fun!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Escape shipping postcode city XML fields' clearly and concisely summarizes the main change: adding XML escaping to postcode and city values in ShippingHelper.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/check-shipping-helper-xml-escaping.py (1)

7-27: ⚡ Quick win

Make the guard resilient to formatting-only edits.

This test relies on exact source-string matches across the whole file, so harmless formatting/refactors can break it or unrelated text can satisfy it. Scope checks to get_postcode_city and match patterns instead of exact snippets.

Proposed refactor
 from pathlib import Path
+import re
@@
 source = shipping_helper.read_text(encoding="utf-8")
 
-required_snippets = [
-    "htmlspecialchars((string) $postcode, ENT_XML1 | ENT_QUOTES, 'UTF-8')",
-    "htmlspecialchars((string) $city, ENT_XML1 | ENT_QUOTES, 'UTF-8')",
-    '"<Postalcode>{$escaped_postcode}</Postalcode>"',
-    '"<City>{$escaped_city}</City>"',
-]
+func_match = re.search(
+    r"function\s+get_postcode_city\s*\([^)]*\)\s*\{(?P<body>.*?)\n\s*\}",
+    source,
+    flags=re.S,
+)
+if not func_match:
+    raise SystemExit("Could not locate ShippingHelper::get_postcode_city")
+
+body = func_match.group("body")
+
+required_patterns = [
+    r"htmlspecialchars\(\(string\)\s*\$postcode,\s*ENT_XML1\s*\|\s*ENT_QUOTES,\s*'UTF-8'\)",
+    r"htmlspecialchars\(\(string\)\s*\$city,\s*ENT_XML1\s*\|\s*ENT_QUOTES,\s*'UTF-8'\)",
+    r"<Postalcode>\{\$escaped_postcode\}</Postalcode>",
+    r"<City>\{\$escaped_city\}</City>",
+]
 
-missing = [snippet for snippet in required_snippets if snippet not in source]
+missing = [p for p in required_patterns if not re.search(p, body)]
 if missing:
     raise SystemExit(
-        "ShippingHelper::get_postcode_city is missing XML escaping snippets: "
+        "ShippingHelper::get_postcode_city is missing XML escaping patterns: "
         + ", ".join(missing)
     )
@@
-    if unsafe_snippet in source:
+    if unsafe_snippet in body:
         raise SystemExit(
             f"ShippingHelper::get_postcode_city still writes raw XML value: {unsafe_snippet}"
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/check-shipping-helper-xml-escaping.py` around lines 7 - 27, The test
currently checks exact string snippets across the whole file which is brittle;
update the check to isolate the ShippingHelper::get_postcode_city function body
(look for the get_postcode_city definition) and then assert presence of
XML-escaping patterns using regexes rather than exact literal snippets: verify
that within get_postcode_city the postcode and city are passed to
htmlspecialchars (or equivalent) with ENT_XML1 and ENT_QUOTES and that the
escaped variables (e.g., $escaped_postcode/$escaped_city or the result of
htmlspecialchars) are used inside the "<Postalcode>...</Postalcode>" and
"<City>...</City>" tags; also detect and fail if raw "$postcode" or "$city" are
inserted unescaped in those tags. Ensure the test searches only inside the
function body and uses pattern matching so formatting changes don’t break it.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/check-shipping-helper-xml-escaping.py`:
- Around line 7-27: The test currently checks exact string snippets across the
whole file which is brittle; update the check to isolate the
ShippingHelper::get_postcode_city function body (look for the get_postcode_city
definition) and then assert presence of XML-escaping patterns using regexes
rather than exact literal snippets: verify that within get_postcode_city the
postcode and city are passed to htmlspecialchars (or equivalent) with ENT_XML1
and ENT_QUOTES and that the escaped variables (e.g.,
$escaped_postcode/$escaped_city or the result of htmlspecialchars) are used
inside the "<Postalcode>...</Postalcode>" and "<City>...</City>" tags; also
detect and fail if raw "$postcode" or "$city" are inserted unescaped in those
tags. Ensure the test searches only inside the function body and uses pattern
matching so formatting changes don’t break it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: be595ace-1338-4fa8-811a-3cc02e7f1e44

📥 Commits

Reviewing files that changed from the base of the PR and between bc485b0 and eee6b26.

📒 Files selected for processing (2)
  • common/models/shipping/util/ShippingHelper.php
  • tests/check-shipping-helper-xml-escaping.py

@haradahinata
Copy link
Copy Markdown
Author

Follow-up after CodeRabbit review: I pushed 1f42c0e to make the ShippingHelper XML escape guard less brittle.

What changed:

  • scopes the static guard to ShippingHelper::get_postcode_city
  • uses whitespace-tolerant regex checks instead of full-file exact snippets
  • still fails if raw $postcode / $city are interpolated into the XML tags

Validation run locally:

python tests/check-shipping-helper-xml-escaping.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant