Use a safe access pattern to retrieve parcel journeys

Information available in parcel journeys should only be accessed by a person that genuinely knows about an order or a parcel, or by a support function of an organisation that answers enquiries about orders or parcels for their customers.

It should be difficult for anyone else to guess information that can be used maliciously to retrieve parcel journeys.

In order to protect this sensitive information, the API endpoint that returns parcel journeys supports a combination of query parameters that prevents maliscious access to such information.

The query parameters available for accessing parcel journeys are:

  • orderRef : the reference of an order generated at the time an order is created.
  • trackingIdentifier : the tracking identifer of a parcel generated at the time a parcel is allocated to a carrier.
  • customerRef : the reference of the customer that purchased the order.
  • postcode : the postal code of the recipient of the order or the parcel.

By combining these query parameters when querrying for parcel journeys, the API ensures that only genuine requests will succeed as the odds of guessing the correct values for a combination of query parameters are very low.

Access patterns to retrieve parcel journeys by order reference

The logic for combining query parameters when retrieving the parcel journeys for an order works as follow:

orderRef is a required query parameter that takes precedence over any other query parameters.

The additional query parameters that can be added to the request are:

  • customerRef : it ensures that parcel journeys for a given order reference are returned only if the customer reference in the order matches the customer reference passed as parameter.
  • postcode : it ensures that parcel journeys for a given order reference are returned only if the postal code of the recipient matches the postal code passed as parameter.
  • trackingIdentifier : it ensures that parcel journeys for a given order are returned only if at least one parcel contains a leg with a matching tracking identifier.

Access patterns to retrieve a specific parcel journey by tracking identifier

The logic for combining query parameters when retrieving the parcel journey for a parcel works as follow:

trackingIdentifier is a required query parameter in this case and takes precedence over any other query parameters except for orderRef.

The additional query parameters that can be added to the request are:

  • customerRef : it ensures that the parcel journey for a given tracking identifier is returned only if the customer reference in the order matches the customer reference passed as parameter.
  • postcode : it ensures that the parcel journey for a given tracking identifier is returned only if the postal code of the recipient matches the postal code passed as parameter.

Access patterns examples

In this example, a customer with the reference CUST-ACCESS-01 purchased items in an order with the reference ORDER-ACCESS-01 that is delivered to the recipient address with the postal code WC1X 8XZ. The delivery with the reference DEL-ACCESS-01 is made of two parcels with the references PAR-ACCESS-01 and PAR-ACCESS-02 with each parcel delivered in a single leg that includes its respective tracking identifier TRACK-ACCESS-01 and TRACK-ACCESS-02.

Let's test the effect of these access patterns when retrieving parcel journeys.

Copy
Copied
{
  "order": {
    "orderRef": "ORDER-ACCESS-01",
    "customer": {
        "customerRef": "CUST-ACCESS-01"
    }
  },
  "deliveryRef": "DEL-ACCESS-01",
  "recipient": {
    "postCode": "WC1X 8XZ"
  }
}
  • Send the request to create the delivery with the order information.
  • Expect a successful response with 204 No Content response code.
  • Open the resource POST Create or update a delivery leg .
  • Update the body with the following JSON object:
Copy
Copied
{
    "trackingIdentifier": "TRACK-ACCESS-01",
    "deliveryRef": "DEL-ACCESS-01",
    "parcel": {
        "parcelRef": "PAR-ACCESS-01"
    }
}
  • Send the request to create the delivery leg for the first parcel.
  • Expect a successful response with 204 No Content response code.
  • Update the body with the following JSON object:
Copy
Copied
{
    "trackingIdentifier": "TRACK-ACCESS-02",
    "deliveryRef": "DEL-ACCESS-01",
    "parcel": {
        "parcelRef": "PAR-ACCESS-02"
    }
}
  • Send the request to create the delivery leg for the second parcel.
  • Expect a successful response with 204 No Content response code.

Retrieve all the parcel journeys for the order using the order reference and customer reference.

  • Open the resource GET Retrieve the parcel journeys for an order or a parcel .
  • In the tab Parameters :
    • set the value of the query parameter orderRef to ORDER-ACCESS-01
    • set the value of the query parameter customerRef to CUST-ACCESS-01 .
  • Remove all other query parameters so that only the query parameters orderRef and customerRef are retained.
  • Send the request to retrieve the parcel journeys for the order using the order reference and customer reference.
  • Expect a successful response with a 200 OK response code and the following JSON body:
Copy
Copied
[
    {
        "delivery": {
            "type": "HOME",
            "direction": "OUTBOUND",
            "carrierServiceType": "TRACKED"
        },
        "order": {
            "orderRef": "ORDER-ACCESS-01",
            "customer": {
                "customerRef": "CUST-ACCESS-01"
            }
        },
        "recipient": {
            "postCode": "WC1X 8XZ"
        },
        "parcel": {
            "deliveryRef": "DEL-ACCESS-01",
            "parcelRef": "PAR-ACCESS-01",
            "deliveryLegs": [
                {
                    "trackingIdentifier": "TRACK-ACCESS-01",
                    "finalDeliveryLeg": true
                }
            ],
            "items": []
        },
        "trackingEvents": []
    },
    {
        "delivery": {
            "type": "HOME",
            "direction": "OUTBOUND",
            "carrierServiceType": "TRACKED"
        },
        "order": {
            "orderRef": "ORDER-ACCESS-01",
            "customer": {
                "customerRef": "CUST-ACCESS-01"
            }
        },
        "recipient": {
            "postCode": "WC1X 8XZ"
        },
        "parcel": {
            "deliveryRef": "DEL-ACCESS-01",
            "parcelRef": "PAR-ACCESS-02",
            "deliveryLegs": [
                {
                    "trackingIdentifier": "TRACK-ACCESS-02",
                    "finalDeliveryLeg": true
                }
            ],
            "items": []
        },
        "trackingEvents": []
    }
]

The two parcel journeys are returned as expected as the query parameters match the information available in the parcel journey.

Let's see how a hacker could attempt to malisciously access this information by trying to guess the value of a customer reference.

  • Set the value of the query parameter customerRef to CUST-GUESS-REF-HACK .
  • Send the request to retrieve the parcel journey for the order using the order reference and a guess for the customer reference.
  • Expect a successful response with a 200 OK response code and the following JSON body:
Copy
Copied
[]

No information is returned. This is expected as there is a mismatch in the information within the parcel journey and the information that was requested.

This time, let's retrieve the parcel journey for a specific parcel.

  • Open the resource GET Retrieve the parcel journeys for an order or a parcel .
  • In the tab Parameters :
    • set the value of the query parameter trackingIdentifier to TRACK-ACCESS-01
    • set the value of the query parameter postcode to WC1X 8XZ .
  • Remove all other query parameters so that only the query parameters trackingIdentifier and postcode are retained.
  • Send the request to retrieve the parcel journey for the parcel in the order using the using the tracking identifier and recipient postal code.
  • Expect a successful response with a 200 OK response code and the following JSON body:
Copy
Copied
[
    {
        "delivery": {
            "type": "HOME",
            "direction": "OUTBOUND",
            "carrierServiceType": "TRACKED"
        },
        "order": {
            "orderRef": "ORDER-ACCESS-01",
            "customer": {
                "customerRef": "CUST-ACCESS-01"
            }
        },
        "recipient": {
            "postCode": "WC1X 8XZ"
        },
        "parcel": {
            "deliveryRef": "DEL-ACCESS-01",
            "parcelRef": "PAR-ACCESS-01",
            "deliveryLegs": [
                {
                    "trackingIdentifier": "TRACK-ACCESS-01",
                    "finalDeliveryLeg": true
                }
            ],
            "items": []
        },
        "trackingEvents": []
    }
]

The parcel journey for one parcel is returned as expected, although the order has two parcels.

Let's see how a hacker could attempt to malisciously access this information by trying to guess the value of a the recipient postcode.

  • Set the value of the query parameter postcode to EC3N 4AB .
  • Send the request to retrieve the parcel journey for using the tracking idenfier of the parcel and a guess for the recipient postcode.
  • Expect a successful response with a 200 OK response code and the following JSON body:
Copy
Copied
[]

Again, no information is returned. This is expected as there is a mismatch in the information within the parcel journey and the information that was requested.

Try out the different combinations of query parameters and pick the ones that work best with the data available in the parcel journeys as to ensure that access to sensitive information cannot be gained easily.