Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added audit beacon to detect misuse of this bidder. Detects auctions… #1134

Merged
merged 6 commits into from
May 2, 2017
151 changes: 64 additions & 87 deletions src/adapters/rhythmone.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,18 @@ var bidmanager = require('../bidmanager.js'),
CONSTANTS = require('../constants.json');

import {ajax as ajax} from '../ajax';

function track(debug) {
if(debug === true){
//console.log('GA: %s %s %s', p1, p2, p3 || '');
}
}

var w = (typeof window !== "undefined" ? window : {});
w.trackR1Impression = track;

module.exports = function(bidManager, global, loader){

var version = "0.9.0.0",
defaultZone = "1r",
defaultPath = "mvo",
debug = false,
auctionEnded = false,
requestCompleted = false,
placementCodes = {};
placementCodes = {},
loadStart,
configuredPlacements = [],
fat = /(^v|(\.0)+$)/gi;

if(typeof global === "undefined")
global = window;
Expand Down Expand Up @@ -71,8 +64,7 @@ module.exports = function(bidManager, global, loader){
return false;
}

var bidderCode = "rhythmone",
bidLostTimeout = null;
var bidderCode = "rhythmone";

function attempt(valueFunction, defaultValue){
try{
Expand All @@ -86,34 +78,6 @@ module.exports = function(bidManager, global, loader){
console.log(txt);
}

function sniffAuctionEnd(){

global.$$PREBID_GLOBAL$$.onEvent('bidWon', function (e) {

if(e.bidderCode === bidderCode){
placementCodes[e.adUnitCode] = true;
track(debug, 'hb', "bidWon");
}

if(auctionEnded){
clearTimeout(bidLostTimeout);
bidLostTimeout = setTimeout(function(){
for(var k in placementCodes)
if(placementCodes[k] === false)
track(debug, 'hb', "bidLost");
}, 50);
}
});

global.$$PREBID_GLOBAL$$.onEvent('auctionEnd', function () {

auctionEnded = true;

if(requestCompleted === false)
track(debug, 'hb', 'rmpReplyFail', "prebid timeout post auction");
});
}

function getBidParameters(bids){
for(var i=0;i<bids.length;i++)
if(typeof bids[i].params === "object" && bids[i].params.placementId)
Expand All @@ -127,7 +91,6 @@ module.exports = function(bidManager, global, loader){
logToConsole("registering nobid for slot "+params.bids[i].placementCode);
var bid = bidfactory.createBid(CONSTANTS.STATUS.NO_BID);
bid.bidderCode = bidderCode;
track(debug, 'hb', 'bidResponse', 0);
bidmanager.addBidResponse(params.bids[i].placementCode, bid);
}
}
Expand Down Expand Up @@ -169,12 +132,12 @@ module.exports = function(bidManager, global, loader){
var d = global.document.location.ancestorOrigins;
if(d && d.length > 0)
return d[d.length-1];
return global.top.document.location.hostname;
return global.top.document.location.hostname; // try/catch is in the attempt function
},""));
p("title", attempt(function(){return global.top.document.title;},""));
p("title", attempt(function(){return global.top.document.title;},"")); // try/catch is in the attempt function
p("url", attempt(function(){
var l;
try{l = global.top.document.location.href.toString();}
try{l = global.top.document.location.href.toString();} // try/catch is in the attempt function
catch(ex){l = global.document.location.href.toString();}
return l;
},""));
Expand All @@ -184,19 +147,18 @@ module.exports = function(bidManager, global, loader){
p("dtype", ((/(ios|ipod|ipad|iphone|android)/i).test(global.navigator.userAgent) ? 1 : ((/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(global.navigator.userAgent) ? 3 : 2)));
p("flash", (flashInstalled() ? 1 : 0));

var placementCodes = [],
heights = [],
var heights = [],
widths = [],
floors = [],
mediaTypes = [],
fat = /(^v|(\.0)+$)/gi,
i=0;

configuredPlacements = [];

p("hbv", global.$$PREBID_GLOBAL$$.version.replace(fat,"")+","+version.replace(fat,""));
for(; i<bids.length; i++){

track(debug, 'hb', 'bidRequest');
var th = [], tw = [];

if(bids[i].sizes.length > 0 && typeof bids[i].sizes[0] === "number")
Expand All @@ -206,14 +168,14 @@ module.exports = function(bidManager, global, loader){
tw.push(bids[i].sizes[j][0]);
th.push(bids[i].sizes[j][1]);
}
placementCodes.push(bids[i].placementCode);
configuredPlacements.push(bids[i].placementCode);
heights.push(th.join("|"));
widths.push(tw.join("|"));
mediaTypes.push(((/video/i).test(bids[i].mediaType) ? "v" : "d"));
floors.push(0);
}

p("imp", placementCodes);
p("imp", configuredPlacements);
p("w", widths);
p("h", heights);
p("floor", floors);
Expand All @@ -224,53 +186,76 @@ module.exports = function(bidManager, global, loader){
return endpoint;
}

function sendAuditBeacon(placementId){
var data = {
doc_version : 1,
doc_type : "Prebid Audit",
placement_id: placementId
},
ao = document.location.ancestorOrigins,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is browser support for ancestorOrigins a concern here?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a concern, it is only available in webkit browsers TMK so it will only be used if there.

q = [],
u = "//hbevents.1rx.io/audit?",
i = new Image();

if(ao && ao.length > 0){
data.ancestor_origins = ao[ao.length-1];
}

data.popped = window.opener!==null?1:0;
data.framed = window.top===window?0:1;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please place this window.top reference in a try/catch as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With all due respect, this is unnecessary. A security exception is only thrown when accessing the properties of top. The window object itself can be compared safely.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

odd, I get no exception when I run that code in a sample file with a cross domain iframe. Furthermore, I don't get that exception when running the same code by targeting chrome's console to that iframe. What sorcery is this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. It's the alert causing the exception. If you just run "window.top" no exception.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah that makes sense. This is good. Prebid core should probably just utility this function because tons of bidders do this check.

Copy link
Contributor Author

@jstocker76 jstocker76 May 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://jsfiddle.net/10j1yw82/

alert must automatically run .toString() on window.top, which would trigger the exception

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reeling in the proliferation of duplicate functionality must be a full time job. The list of bidders is getting quite long


try{
data.url = window.top.document.location.href.toString();
}catch(ex){
data.url = window.document.location.href.toString();
}

var prebid_instance = global.$$PREBID_GLOBAL$$;

data.prebid_version = prebid_instance.version.replace(fat,"");
data.response_ms = (new Date()).getTime() - loadStart;
data.placement_codes = configuredPlacements.join(",");
data.bidder_version = version;
data.prebid_timeout = prebid_instance.cbTimeout || prebid_instance.bidderTimeout;

for(var k in data){
q.push(encodeURIComponent(k)+"="+encodeURIComponent((typeof data[k] === "object" ? JSON.stringify(data[k]) : data[k])));
}

q.sort();
i.src = u+q.join("&");
}

this.callBids = function(params){

var slotMap = {},
bidParams = getBidParameters(params.bids);

debug = (bidParams !== null && bidParams.debug === true);

track(debug, 'hb', 'callBids');

if(bidParams === null){
noBids(params);
track(debug, 'hb', 'misconfiguration');
return;
}

sniffAuctionEnd();

track(debug, 'hb', 'rmpRequest');

for(var i = 0; i<params.bids.length; i++)
slotMap[params.bids[i].placementCode] = params.bids[i];

loadStart = (new Date()).getTime();
load(bidParams, getRMPURL(bidParams, params.bids), function(code, msg, txt){
if(auctionEnded === true)
return;

// send quality control beacon here
sendAuditBeacon(bidParams.placementId);

requestCompleted = true;

logToConsole("response text: "+txt);

if(code === -1)
track(debug, "hb", "rmpReplyFail", msg);
else{

if(code !== -1){
try{
var result = JSON.parse(txt),
registerBid = function(bid){

//{"id":"ffe73abd-91b3-56d3-d0ee-015a91b356d4",
// "impid":"123",
// "price":17.13,
// "nurl":"http://1r-qa-ads.rhythmxchange.com/rmp/389633/0/ivh?reqId=6594035297396414163",
// "cid":"366183",
// "crid":"366182",
// "h":480,
// "w":640}


slotMap[bid.impid].success = 1;

var pbResponse = bidfactory.createBid(CONSTANTS.STATUS.GOOD),
Expand All @@ -293,27 +278,19 @@ module.exports = function(bidManager, global, loader){

logToConsole("registering bid "+placementCode+" "+JSON.stringify(pbResponse));

track(debug, "hb", "bidResponse", 1);
bidManager.addBidResponse(placementCode, pbResponse);
};

track(debug, "hb", "rmpReplySuccess");

for(i=0; result.seatbid && i<result.seatbid.length; i++)
for(var j=0; result.seatbid[i].bid && j<result.seatbid[i].bid.length; j++){
registerBid(result.seatbid[i].bid[j]);
}
}
catch(ex){
track(debug, "hb", "rmpReplyFail", "invalid json in rmp response");
}
catch(ex){}
}

// if no bids are successful, inform prebid
noBids(params);

// when all bids are complete, log a report
track(debug, 'hb', 'bidsComplete');
});

logToConsole("version: "+version);
Expand Down