This blog post is the continuation of our parcel research. We already reported about how we broke parcel tracking at DHL and the disclosure process of the identified problems. As DHL is not the only parcel service in Germany, we also investigated the other available parcel services. In this blog post, we want to talk about DPD, also called Geopost, which belongs to the French Post Office.
Efficient Guessing of Tracking Numbers
DPD uses the recipient’s ZIP code to unlock detailed shipment information and additional options. After trying some ZIP codes manually, we received CAPTCHA prompts in the web interface (more on this later).
While opening the basic tracking page of a tracking number (without providing the correct ZIP code), it showed just fundamental information – not even locations.
A little inconspicuous button (in the upper right corner in the previous screenshot) opened a more detailed tracking panel. This detailed tracking presented the location of the parcel and, therefore, the destination region because the last hop before the delivery showed the name of the destination parcel center.
We reused our approach outlined in the DHL blog post. The approach consists of getting a list of ZIP codes and the serving DPD parcel center. Afterwards the ZIPs are ordered by population (descending) under the assumption that more parcels are shipped to more populous areas. This aims to reduce the time for guessing the correct ZIP code. Compared to DHL, DPD has many more parcel centers, resulting in fewer served ZIP codes per parcel center and reducing the mean number of tries in a brute-force attempt to find the correct ZIP code for a tracking number.
A little math showed us that a DPD parcel center serves, on average, 105 ZIP codes and that – on average – the 24 most populous ZIP codes represent 50% of the population served by a parcel center. As a result, we need a few guesses until we hit the correct ZIP code.
With all this information, we automated the approach for the DPD website in a small Python script. Because we received CAPTCHA prompts during manual testing in the web interface, we expected rate limiting, more CAPTCHA prompts and other DPD web app security control to slow us down – but there was no countermeasure. While human users were bothered with CAPTCHAS, scripts apparently could bypass this measure. Our script could brute force its way through large amounts of tracking numbers and was quite efficient: In many cases, the tool needed less than two seconds to guess the correct ZIP code.
Since businesses get a DPD tracking number prefix, we were able to get a list of customers who recently ordered at certain online shops.
More Fun with Tracking Numbers
While playing around with all the tracking numbers, we discovered something interesting:
We saw two different tracking histories for the same tracking number. One tracking history showed events from September 2022 (green box). The other showed events from March 2023 (blue box). The dates were suspiciously close to a 180-day difference. We concluded that DPD reuses tracking numbers after about half a year.
Even more interesting was that we could guess two different correct ZIP codes for this tracking number. One was from the Hamburg area (green box) and the other from the Ludwigsburg area (blue box). This means we could take an old DPD tracking number, wait for it to be reused, and use the previous recipient’s ZIP code to unlock the data of the current recipient.
After contacting CERT La Poste – the CERT responsible for DPD, as DPD belongs to the French Post Office – we quickly got an acknowledgment that they were working on fixes for the identified problems. During the 90 days period after the initial contact, we got multiple updates about the work on fixes in progress.
In June 2023, we observed changes to the web interface and exposed functionality so that our approach of limiting the list of potential ZIP codes to a certain subset and brute-forcing the correct ZIP was not possible anymore.
We could not verify the tracking number reuse issue or its remediation as this requires access to a tracking number that was used approximately six months before. Even though the issue would still be present, its impact is greatly reduced as limiting the ZIP codes for brute-forcing is not possible anymore.
03.04.2023 – First contact to CERT La Poste (responsible CERT) and start of 90-day disclosure period.
12.04.2023 – First response by CERT La Poste, assuring action for mitigating findings.
04.05.2023 – Information that DPD is working on implementing mitigations.
07.06.2023 – Information that first mitigations are implemented.
12.09.2023 – Public disclosure of findings by ERNW
13.09.2023 – Presentation at Heise devSec
Dennis Kniel & Florian Bausch