The Opticks Firewall, OpticksJS and Opticks Bouncer integrations can all deliver Opticks' detections for each visit in JSON format. The JSON will be encrypted before delivery. Here is an example of the JSON format. The version is set in the data-opticks
attribute of the JS snippet. At the moment, the Opticks Firewall and Opticks Bouncer response format default is v2. In order to force v3 response format, include the macro response-opticks-version=v3
v2 format:
{
"opticksClickId": "track_20180528004215_a4bdb381_fe23_40ab_8202_ec3029bf8bd2",
"invalidClickReasons": ["blockProxy"],
"analysis": {
"level": "medium",
"detections": [{
"group": "Proxy Traffic",
"triggers": ["Hosting/CDN proxy"]
}, {
"group": "Harmful applications",
"triggers": ["Offer not rendered", "Malicious code found"]
}, {
"group": "Non-reputable IP addresses",
"triggers": ["IP flagged for Attacks"]
}]
},
"ts": 1527868404,
"version": 2
}
v3 format:
{
"invalidClickReasons": [],
"analysis": {
"level": "high",
"detections": [{
"group": {"id": 2,"group": "Header Injections"},
"triggers": [{
"id": 11,"trigger": "MSISDN Injection"
}]
}, {
"group": {"id": 6,"group": "Iframe"},
"triggers": [{
"id": 30, "trigger": "Tiny Iframe"
}]
}, {
"group": {"id": 3,"group": "Harmful applications"},
"triggers": [{
"id": 14,"trigger": "Offer not rendered"
}, {
"id": 15,"trigger": "Malicious code found"
}]
}]
},
"opticksClickId": "track_20180831102904_4209d1c2_63c2_4fb2_af40_ae2eae08fd10",
"delivered": true,
"fallbackUrl": null,
"ts": 1535711344986,
"version": 3
}
Encryption details
Parameter | Value | Notes |
---|---|---|
CIPHER | AES-128-CBC | always |
KEY | 1234567812345678 | This is an example, each Opticks customer will have its own private key. |
iv | 202_ec3029bf8bd2 | last 16 characters of clickid |
First, Opticks converts the JSON that needs to be encrypted to flat plain text, removing all whitespaces. Then It is encrypted like this:
$jsonString = $flatPlainJsonTextWithNoWhitespace;
$iv = substr($opticksClickId, -16); // last 16 characters
$cipher_raw = openssl_encrypt($jsonString, CIPHER, KEY, OPENSSL_RAW_DATA, $iv);
$encrypted64 = base64_encode($cipher_raw); // OpticksJS
$encrypted64encoded = urlencode($encrypted64); // Firewall & Bouncer
$hmac_raw = hash_hmac('sha256', $encrypted64, KEY, $as_binary = true);
$hmac64 = base64_encode($hmac_raw); // OpticksJS
$hmac64encoded = urlencode(hmac64); // Firewall & Bouncer
Opticks Firewall and Bouncer
The Firewall and Bouncer integrations will place the $encrypted64encoded
data into the {OPT}
macro and the $hmac64encoded
data into the {OPT-HMAC}
macro. Remember that these macros are placed in the Offer URL.
Here is an example using the JSON taken from the introduction of this section:
https://offer.url
?clickid=track_20180528004215_a4bdb381_fe23_40ab_8202_ec3029bf8bd2
&opt=do%2BH96Dqe7Z0tkvYYDPelHhBmvXCGmHQZxlaITH6%2BIPjwrlII%2B01v%2FPQ6Au05CyAYztUNWig06Z9HXeFEUcyis47VWj39OxSoLrYC27aBMU2f5DpfxVDFL7uz814zxcj22xsgHhHUVOUv9sX4a28HFra57iEKBeO1zi%2BOQtyia2DGtaFTSpOuzO0cF4X726LVpB%2Fq5cevotY%2B52g%2FIOrTzPSijksEMDEwZ4QkREWk7gY5u8TPwR1NV9oHzQ8xTWsrFoj5f3VVwl3HrrK7cZyP6ePoZnfdAyb61%2BlTEFTNaUqGSg1U9fBM0tS8SMeZXw5%2FOm6grgEx4FwUREZceAUcDXkl81P3TL6G1Ai6R4EQpNF9iXXdzeB6X6ADNMfZxCk6adveFDS3WzlHaAqsq%2Fzc39Uyolkf%2BO3B6v1PsA%2BtXTkEw1YgMpFlTQbzm5tSm1aKJKN36IRbRZ1U12mL5dql5ND%2FUf8qQ4n8%2B9%2BqnA0Tu4jYvvROz2%2By2QnDqCC1%2FcGzSJd5q4SecYlcVbUxeEnEqXzsogsVXFZYKG3%2Bt%2BQ0Fo%3D
&opt-hmac=gq8U6hB9YF2L19F3XDyqFLeowD00H4hqubOiQ4kjtl4%3D
You can test the encryption at this site: http://www.devglan.com/online-tools/aes-encryption-decryption.
Verify and decrypt
First, use the HMAC to verify that data has not been altered during delivery. Then, ensure that the data can be decrypted correctly using our shared key. Make sure that the click ids match and the time between encryption and decryption is reasonable, say about 5 seconds or less. Ensure that the Opticks clickid is unique, perhaps by some fast key/value store. Examine the Opticks detections.
$opticksClickId = $_REQUEST['clickid'];
$encryptedData64 = rawurldecode($_REQUEST['opt']);
$hmac64 = rawurldecode($_REQUEST['opt-hmac']);
$iv = substr($opticksClickId, -16);
$calcmac = hash_hmac('sha256', $encryptedData64, KEY, $as_binary = true);
$calcmac64 = base64_encode($calcmac);
if (!hash_equals($hmac64, $calcmac64)) {
throw new \Exception("Message verification (hmac) failure.");
}
if(!$plaintext = openssl_decrypt($encryptedData64, CIPHER, KEY, 0, $iv)) {
throw new \Exception("Message decryption failure.");
}
if (!$plainJson = json_decode($plaintext)) {
throw new \Exception("Encrypted data is not valid JSON.");
}
if($plainJson->opticksClickId != $opticksClickId) {
throw new \Exception("Click Ids do not match!");
}
$tsDiff = microtime(1) - $plainJson->ts / 1000;
if($tsDiff > 5) { // 5 seconds
throw new \Exception("Timestamp problem.");
}
if($redis->get($opticksClickId)) {
throw new \UnexpectedValueException("Opticks click id has already been used.");
}
$redis->set($opticksClickId, 1);
/** IMPORTANT **/
// code which examines Opticks groups, threat level,
// detections and invalid click reasons.
// if nothing suspicious, continue....
// Ensure there are no invalidClickReasons
if ($plainJson->invalidClickReasons) {
throw new \UnexpectedValueException("invalidClickReasons exist.");
}
// Landing page content below here
Comments
0 comments
Please sign in to leave a comment.