Advisory
Secunia Advisory SA 49652
Analysis
TheCartPress has functionality for an admin to view and print an order. This functionality extends also to the customer to print the order. By providing the orderID, the user can view and print the order. However there was a distinct lack of any validation about whether or not the user requesting the order owned it.
The entry point to print an order is /admin/PrintOrder.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$order_id = isset( $_REQUEST['order_id'] ) ? $_REQUEST['order_id'] : 0; $file_name = 'tcp_print_order.php'; $template = STYLESHEETPATH . '/' . $file_name; $template = apply_filters( 'tcp_get_print_order_template', $template, $order_id ); if ( file_exists( $template ) ) { include( $template ); } else { $template = get_template_directory() . '/' . $file_name; if ( STYLESHEETPATH != get_template_directory() && file_exists( $template ) ) { include( $template ); } else { $template = TCP_THEMES_TEMPLATES_FOLDER . $file_name; if ( file_exists( $template ) ) { include( $template ); } } } |
This fetches the template that is going to be used to used for the page to be printed. By default, this is /theme-templates/tcp_print_order.php:
1 2 3 4 5 |
if ( isset( $_REQUEST['order_id'] ) ) { require_once( TCP_CLASSES_FOLDER . 'OrderPage.class.php' ); $order_id = $_REQUEST['order_id']; OrderPage::show( $order_id, true ); } |
The template goes ahead and passes on the order_id in the request to the OrderPage::show method. Notice that at no point has there been any validation of the order belonging to the user requesting the page. Anyway, we call into the show method, which is in fact the only method on the OrderPage class in /classes/OrderPage.class.php:
1 2 3 4 5 6 7 8 9 |
class OrderPage { static function show( $order_id, $see_comment = true, $echo = true, $see_address = true, $see_full = false ) { require_once( TCP_CLASSES_FOLDER . 'CartTable.class.php' ); require_once( TCP_CLASSES_FOLDER . 'CartSourceDB.class.php' ); $cart_table = new TCPCartTable( ); return $cart_table->show( new TCP_CartSourceDB( $order_id, $see_address, $see_full, true, $see_comment ), $echo ); } } |
This method effectively just fetches the order from database, and then returns it. There’s no reference to the active user, which is the gist of this vulnerability. A lack of validation of the requesting user being also the owner of the order, or an admin.