Securing Requests

Securing requests sent from the Castle JS Snippet on Web

We strongly encourage all Castle customers to enable Secure Mode to prevent fraudsters from impersonating your users. This is important to make sure fraudsters can't lock out your users by feeding in bad behavior.

Step 1. Signing requests

To sign requests, you'll need to generate a user signature on your backend, then pass it to the Javascript snippet:

_castle('secure', 'YOUR_GENERATED_SIGNATURE');

The signature is a SHA-256 HMAC in hex format.

The HMAC shared secret is your API Secret, and the value is the User ID being tracked in identify.

Example

<script type="text/javascript">
  _castle('secure',
    '<%= OpenSSL::HMAC.hexdigest("sha256", "YOUR_API_SECRET", "1234") %>');
</script>
<?
<script type="text/javascript">
  _castle('secure',
    '<?= hash_hmac("sha256", "1234", "YOUR_API_SECRET"); ?>');
</script>
<script type="text/javascript">
  _castle('secure', 
    '<%= Castle.instance().secureUserID("1234") %>');
</script>
<script type="text/javascript">
  _castle('secure',
    '@Castle.Signature.Compute("YOUR_API_SECRET", "1234")');
</script>

Step 2. Enabling secure mode in the dashboard

Once the secure signatures are included in your requests, you need to enable Secure Mode in the Castle dashboard. This informs Castle that only requests including the secure signature should be trusted, and all other frontend events will be dropped.

If you are using Castles Mobile SDKs in your native apps, be sure to configure secure signatures for them as well or their frontend events will be dropped.

To enable secure mode, visit the Castle Dashboard and select the environment in the top right for which you want to enable secure mode. Then go to Settings > General, toggle on Secure Mode, and click Save.

Review email

Securing requests sent from the Castle Mobile SDKs in native apps

To securely sign requests from Mobile SDKs, please visit the Mobile section of our docs here: https://castle.io/docs/mobile

Any environment that has Secure Mode enabled in your Castle Dashboard requires all frontend events to include a secure signature. If you are using a combination of Castle JS for web and Castle Mobile SDKs for native apps, make sure they are all configured to include a secure signature before toggling on Secure Mode in your Castle Dashboard. Otherwise their frontend events will be dropped.

Securing Webhooks received from Castle

Since anyone could in principle send webhooks to your application, it’s important to verify that these webhooks originated from Castle. Valid webhooks will therefore contain the header X-Castle-Signature which points to a HMAC SHA256 signature of the webhook payload (body):

require "json"

# Using Sinatra
require 'rubygems'
require 'base64'
require 'openssl'
require 'sinatra'

helpers do
  # Compare the computed HMAC digest based on the shared secret and the
  # request contents to the reported HMAC in the headers
  def verify_webhook(data, hmac_header)
    digest  = OpenSSL::Digest::Digest.new('sha256')
    calculated_hmac =
      Base64.encode64(OpenSSL::HMAC.digest(
        digest,
        'YOUR_API_SECRET',
        data)
      ).strip
    calculated_hmac == hmac_header
  end
end

# Respond to HTTP POST requests sent to this web service
post '/' do
  request.body.rewind
  data = request.body.read
  hmac_header = request.headers['X-Castle-Signature']
  verified = verify_webhook(data, hmac_header)

  # IMPLEMENT: handle the alert

  # Output 'true' or 'false'
  puts "Webhook verified: #{verified}"
end
<?
function verify_webhook($data, $hmac_header)
{
  $calculated_hmac = base64_encode(hash_hmac('sha256',
                                             $data,
                                             'YOUR_API_SECRET',
                                             true));
  return ($hmac_header == $calculated_hmac);
}

$hmac_header = $_SERVER['HTTP_X_CASTLE_SIGNATURE'];
$data = file_get_contents('php://input');
$verified = verify_webhook($data, $hmac_header);
error_log('Webhook verified: '.var_export($verified, true));
?>