Authentication and Authorization

Exploitation of access control vulnerabilities is a core skill of attackers. To protect against the attackers, enforce server-side access control checks for business functions such as account management, order management, and purchasing.

To control access to sensitive objects, use authentication and authorization. The following objects are examples of sensitive objects:

  • Order
  • Customer
  • CustomerPaymentInstrument
  • OrderPaymentInstrument
  • Basket

Script API objects are identified using object identifiers (UUID, ID, Token). Knowing the identifiers shouldn’t grant read or write access to sensitive objects. Always perform additional authentication and authorization in the storefront before processing any requests. Some script APIs provide both secure and insecure methods. Although insecure methods accommodate legacy use cases, we highly recommend using the secure methods.

For example, the class OrderMgr provides two signatures to the method getOrder:

static getOrder(orderNumber : String)
static getOrder(orderNumber : String, orderToken : String)

The second signature is the secure method. For more information, see Class OrderMgr.

Authentication

If you use the Storefront Reference Architecture (SFRA) in your cartridge path, you can use its userLoggedIn middleware capability to check whether the request is from an authenticated user. This middleware exposes the validateLoggedIn function to check whether the user is authenticated to invoke the function. The middleware also exposes the validateLoggedInAjax function to validate whether a user is authenticated from an AJAX request.

var userLoggedIn = require('*/cartridge/scripts/middleware/userLoggedIn');
server.get(
     'Show',
     server.middleware.https,
     userLoggedIn.validateLoggedIn,
     consentTracking.consent,
     function (req, res, next) {
        var CustomerMgr = require('dw/customer/CustomerMgr');
        var Resource = require('dw/web/Resource');
        var URLUtils = require('dw/web/URLUtils');

This code snippet includes the middleware userLoggedIn for an exposed business function.

If you use SiteGenesis in your cartridge path, you can use guards to wrap controller functions when they’re exported. The functions specified in the guard module act as a request filter. You can specify multiple levels of access to controller functionality.

  • Require HTTPS.
  • Require or forbid a certain HTTP method, like GET or POST.
  • Require that a current user is logged in.

This example shows an edit profile controller that requires HTTPS and that the user is logged in.

exports.EditProfile = guard.ensure(['get', 'https', 'loggedIn'], editProfile);

Authorization

When implementing storefront operations, use authorization checks that are relevant to your business workflow. When performing an administrative action on a sensitive object, authenticate the requesting user using a secret about that object. For example, when a guest creates an account after successfully checking out, and the order is reassigned to that guest, authenticate the user using a secret about the order. This approach provides high confidence that the requesting user is the user who created the object.

The following sections include examples of authorization checks for the Order object for registered and guest shoppers.

Registered Shoppers

When a registered shopper wants to access an order, verify the following information in the storefront:

  • The shopper is authenticated. For more information, see the authentication information earlier in this topic.
  • The order has a cancelable status. Whether a status is cancelable depends on the order management flow of each storefront. See Class Order for supported statuses.
  • The shopper owns the order to be canceled.
var orderCustomer = order.getCustomer();
var sessionCustomer = session.getCustomer();
If ( orderCustomer.ID === sessionCustomer.ID ) {
    // The logged-in shopper is the owner of the order
    // perform actions in accordance with the order management workflow
    ...
} else {
    // A user attempts to access an order they don’t own
    // Reject this request with an error message ( HTTP 401 unauthorized or a custom error page)
    // Log an error message to track this occurrence
}

Guest Shoppers

Implementing a robust authentication and authorization scheme that applies to guest (unregistered) shoppers is more challenging than for registered shoppers. To reduce the risk of fraud, consider the following options as applicable for your use case:

  • Prohibit guest shoppers from changing existing orders; prompt them to create an account when they try to change orders.
  • Allow access to an order only if the shopper can produce the order number, order token, and a combination of other data included in the order, such as:
    • Email
    • Last name
    • Postal code
    • Phone number
  • Don’t allow guest shoppers to access orders that registered users own.
  • Limit the permitted actions to the strict minimum. For example:
    • Don’t display payment or personal information stored in the order.
    • Don’t allow changes that would let a malicious user modify the order, for example by changing the shipping address.
  • Implement bot/script protection controls to protect from brute force attacks. For example:
    • Rate limiting
    • CAPTCHA