---
# System prepended metadata

title: ALBAIK Ordering Security Audit

---

# ALBAIK Ordering Security Audit

## Sensitive payment data can be created from Mastercard access
The following endpoints initiate an interaction with Mastercard. Responses from the Mastercard API can include payment data that should not be leaked:

| Endpoint | Mastercard access |
| --- | --- |
| POST /payment/sessions | create_session |
| POST /orders | get_session, purchase, tokenize_card |
| DELETE /orders | void |
| POST /group_orders | get_session, purchase, tokenize_card |
| POST /payment/3d_secure/check | check_3ds |
| POST /payment/3d_secure/authorize | process_3ds |
| POST /admin/refunds | refund |
| POST /payment_methods | tokenize_card |
| DELETE /payment_methods | delete_token |



## Sensitive payment data stored in the database
Some of the interactions with the Mastercard API result in payment data being stored in the following database tables:

- ThreeDSecureCheckStatus
- PaymentEvent
- PaymentMethod

When payment data is stored in the database it opens up the possibility of an endpoint exposing the data.   The following endpoints initiate code that interacts with the above tables:

- POST /api/v1/payment_methods
- GET /api/v1/payment_methods
- DELETE /api/v1/payment_methods
- POST /api/v1/orders
- PATCH /api/v1/orders
- DELETE /api/v1/orders/:id
- POST /api/v1/group_orders
- POST /admin/refunds/create
- GET /admin/refunds/new
- POST /admin/refunds
- GET /admin/orders/:id
- POST /admin/order_exports
- POST /api/v1/payments/three_d_secure/check
- POST /api/v1/payments/three_d_secure/authorize
- GET api/v1/three_d_secure_check_statuses/:id

(detailed documentation of the link between these tables and the endpoints listed is available [in this spreadsheet](https://docs.google.com/spreadsheets/d/17Trhcyc7ztX3XnPn8465-VWBJPB1l3sFdHA7uH-x2z4/edit#gid=340270619))


## Review of all relevant endpoints
All endpoints that create payment data (by interacting with the Mastercard API) or could expose it (by interacting with stored payment data) are reviewed below:

|  | Authentication | Authenticated user /<br>Authorisation | DB Scope | Returns |
| --- | --- | --- | --- | --- |
| POST /api/v1/payment/sessions | ApiController#authenticate_client |  | (no DB access, initial session is not connected to user) | payment_gateway, session_id |
| POST /api/v1/payments/three_d_secure/authorize |  |  | (no DB access, passes through to Mastercard) | "3DS_SUCCESS"/"3DS_FAILURE" |
| POST /api/v1/payments/three_d_secure/check | ApiController#authenticate_client | ApiController#authorize | ThreeDSecureCheckStatus.create(user_id: user.id) | MasterCard::Check (gateway_recommendation, html, 3d_secure_id) OR<br>ThreeDSecureCheckStatus (id, amount, error, error_message, gateway_recommendation, html)<br> |
| GET api/v1/three_d_secure_check_statuses/:id | ApiController#authenticate_client | ApiController#authorize | ThreeDSecureCheckStatus.where(user_id: current_user.id) | id, amount, gateway_recommendation, html |
| GET /api/v1/payment_methods | ApiController#authenticate_client | ApiController#authorize | user.payment_methods | id, payment_token, card_number, card_type, expiry_date, require_security_code, name_on_card |
| DELETE /api/v1/payment_methods | ApiController#authenticate_client | ApiController#authorize | user.payment_methods | 204 NO CONTENT |
| POST /api/v1/payment_methods | ApiController#authenticate_client | ApiController#authorize | user.payment_methods | payment_token, card_number, card_type, expiry_date, require_security_code, name_on_card |
| POST /api/v1/orders | ApiController#authenticate_client | ApiController#authorize | Order.create(user_id: user_id) | albaik_identifier, id, check_identifier, created_at, fees_total, items_subtotal, items_tax, items_total, pickup_code, status, tax_percent, total, delivery_method |
| PATCH /api/v1/orders | ApiController#authenticate_client |  | Order.active | albaik_identifier, id, check_identifier, created_at, fees_total, items_subtotal, items_tax, items_total, pickup_code, status, tax_percent, total, delivery_method |
| DELETE /api/v1/orders/:id | ApiController#authenticate_client | ApiController#authorize | user.orders | 204 NO CONTENT |
| POST /api/v1/group_orders | ApiController#authenticate_client | ApiController#authorize | Order.create(user_id: user_id) | albaik_identifier, id, check_identifier, created_at, fees_total, items_subtotal, items_tax, items_total, pickup_code, status, tax_percent, total, delivery_method, fees, order_items |
| GET /admin/refunds/new | require_login | admin only |  | html |
| POST /admin/refunds | require_login | admin only |  | payment_event.order_items, payment_event.amount |
| POST /admin/order_exports | require_login | admin, sales, licensee_manager only |  | redirect |
| GET /admin/orders/ | require_login | <br>admin, licensee_manager, customer_relationship, driver_coach, sales only |  | html |

## Conclusions

- Payment session ID is no longer being exposed unsafely. The only endpoint that returns payment session ID is `POST /api/v1/payment/sessions`, which creates it, and this is before the session is updated with real card details.
- An attacker could update another user's order by using `PATCH /api/v1/orders`. They would only be able to change the status on the order.
- `POST /api/v1/payments/three_d_secure/authorize` can be called by anyone, but does not mutate any data and only returns success/failure of a transaction

## Actions

- Prevent a user from updating a different user's order
  - [Ticket here](https://teams.microsoft.com/l/entity/com.microsoft.teamspace.tab.planner/tt.c_19:0f061ef0eb0043a08baf2d7996911627@thread.skype_p_fl5Vbc3lXk2lxweyLV-81JcAAj_p_h_1646647547094?tenantId=92b0c512-8439-4285-a96c-188896a9afa9&webUrl=https%3A%2F%2Ftasks.teams.microsoft.com%2Fteamsui%2FpersonalApp%2Falltasklists&context=%7B%22subEntityId%22%3A%22%2Fboard%2Ftask%2FbDapUNsOEkCquRiB6Twgz5cAA3rX%22%2C%22channelId%22%3A%2219%3A0f061ef0eb0043a08baf2d7996911627%40thread.skype%22%7D)
- Prevent a user from checking whether a different user's 3DSecure transaction succeeded
  - [Ticket here](https://teams.microsoft.com/l/entity/com.microsoft.teamspace.tab.planner/tt.c_19:0f061ef0eb0043a08baf2d7996911627@thread.skype_p_fl5Vbc3lXk2lxweyLV-81JcAAj_p_h_1646647547094?tenantId=92b0c512-8439-4285-a96c-188896a9afa9&webUrl=https%3A%2F%2Ftasks.teams.microsoft.com%2Fteamsui%2FpersonalApp%2Falltasklists&context=%7B%22subEntityId%22%3A%22%2Fboard%2Ftask%2FOQXA4Ecs5Ee478DFBWzIkpcAGi67%22%2C%22channelId%22%3A%2219%3A0f061ef0eb0043a08baf2d7996911627%40thread.skype%22%7D)