How to overwrite a function in the web page with Chrome extension? - javascript

Suppose there is a web site has a global namespace Q = {}, and there is a function under it: Q.foo
I'd like to overwrite this function in my chrome extension, so when the web page calls Q.foo, it would do what I like.
I tried to write:
Q.foo = function(){
alert("over written");
}
with content script. But it doesn't work....
thanks.

The main problem iis that a chrome extension exists in a separated enviornment which was created so that extension developers cant screw with the existing page's javascript and vice versa.
However geeky people can do this:
document.head.innerHTML += '<script>Q.foo = function(){alert("over written");}</script>';
Basically what this does is that it appends a script tag into the dom which is then instantly eval'd in the context of the page.

Q.prototype.foo = function(){
alert("over written");
}

Related

How can i access shadow dom elements on a web page from a chrome extension and also a firefox extension? [duplicate]

well google translate extension in chrome, has popup feature, it displays translation of selected word instantly, I wanted to access those translations displayed by popup, but this popup element is shadowRoot("closed"), so javascript cant access its content, I red an article about that subject and author says:
But really there is nothing stopping someone executing the following JavaScript before your component definition.
Element.prototype._attachShadow = Element.prototype.attachShadow; Element.prototype.attachShadow = function () { return this._attachShadow( { mode: "open" } ); };
Is it possible to change attachShadow method of other extension? if so where should it be executed by my extension? background_script or maybe somewhere. I think each extension has its own enviroment and I have no chane to edit their methods. I wish I'm wrong :)
No need to override it.
There's a special method in the content script.
Chrome 88+:
let shadowRoot = chrome.dom.openOrClosedShadowRoot(element);
Firefox 63:
let shadowRoot = element.openOrClosedShadowRoot();
Combined:
let shadowRoot = chrome.dom?.openOrClosedShadowRoot(element)
|| element.openOrClosedShadowRoot();

Accessing the console log commands via chrome extension

I'm looking to override the existing console commands via my Chrome extension - the reason for this is I wish to record the console logs for a specific site.
Unfortunately I cannot seem to update the DOM, this is what i've tried so far:
// Run functions on page change
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('core/js/app/console.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
});
console.js
// Replace functionality of console log
console.defaultLog = console.log.bind(console);
console.logs = [];
console.log = function(){
console.defaultLog.apply(console, arguments);
console.logs.push(Array.from(arguments));
};
// Replace functionality of console error
console.defaultError = console.error.bind(console);
console.errors = [];
console.error = function(){
console.defaultError.apply(console, arguments);
console.errors.push(Array.from(arguments));
};
// Replace functionality of console warn
console.defaultWarn = console.warn.bind(console);
console.warns = [];
console.warn = function(){
console.defaultWarn.apply(console, arguments);
console.warns.push(Array.from(arguments));
};
// Replace functionality of console debug
console.defaultDebug = console.debug.bind(console);
console.debugs = [];
console.debug = function(){
console.defaultDebug.apply(console, arguments);
console.debugs.push(Array.from(arguments));
};
The script runs successfully with an alert().
The goal for me is to access console.logs - but its undefined which means I haven't gotten access to the DOM, despite injecting a script.
If not possible, even a third party integration would be helpful i.e. Java or C?
Any thoughts would be greatly appreciated :)
I found this post and I think Tampermonkey injects a script with the immediate function that you add in the Tampermonkey Chrome extension page, I found something similar in extensions like Wappalyzer, and looks good and safe, you could use WebRequest to inject to your website the new "polyfill" before the page is fully loaded as the post says.
Here the example of Wappalyzer that I mentioned before, this is the JS load in StackOverflow with Wappalyzer using the code injection, I didn't test it with Tampermonkey yet
EDIT
Checking Wappalyzer, how to inject the code is the easy part, you can use (Wappalyzer github example):
const script = document.createElement('script')
script.setAttribute('src', chrome.extension.getURL('js/inject.js'))
This probably will not fix your problem, this code is executed after all the content was loaded in the DOM. But, you can find how to fix that problem in this post
I'll suggest to use onCommitted event (doc1/doc2)
Using the mozilla.org example you will have something like
const filter = {
url: //website to track logs
[
{hostContains: "example.com"},
{hostPrefix: "developer"}
]
}
function logOnCommitted(details) {
//Inject Script on webpage
}
browser.webNavigation.onCommitted.addListener(logOnCommitted, filter);
It might be worth trying to redefine the entire console object:
const saved = window.console
window.console = {...saved, log: function(...args){ saved.log("Hello", ...args) }}
But it's probably impossible, because content scripts live in an isolated world:
Isolated worlds do not allow for content scripts, the extension, and the web page to access any variables or functions created by the others. This also gives content scripts the ability to enable functionality that should not be accessible to the web page.
Although in Tampermonkey this script works.
I believe Tampermonkey handles this by knowing the subtleties and tracking changes in the extensions host's protection mechanism.
BTW, for small tasks, there is a decent alternative to chrome extensions in the form of code snippets.

WKWebView doesn't interact anymore with Javascript in iOS10

I have a native app which has to interact with a website. It has been working normally up to iOS 9, but with iOS 10, the Javascript code inside the web app is no longer valid.
Here is an example of the JS code I use on the onClick event of a button, which as mentioned worked like a charm before iOS10.
function DoSomething()
{
var iframe = document.createElement("IFRAME");
var url='codeToBeUsed://id=1230';
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
when I debug the app on Xcode, the request variable which normally contained the content of the "url" variable on the example provided, now returns a blank value...
<NSMutableURLRequest: 0x170011070> { URL: about:blank }
I even tested placing a alert('click'); but it didn't work either. Does anybody know how to solve this issue?
Using a code close to yours (I pass a stringified json in the src), I also got an embarassing 'about;blank' in the request.
It seems iOs10 has some new restrictions on what you pass to iframe 'src'. I found it requires a valid url to trigger properly the request.
Try to use :
var url='codeToBeUsed://?id=1230';
Edit : or encode URI...

Controlling a Firefox Extension via Javascript

Is it possible, using javascript, to control an overlay firefox extension? I've extracted the contents of the extension and have identified what functions/methods I need to run, but they are not accessible within the scope of the console.
Thanks in advance for any ideas.
Yes it possible to interact with other add-ons, given the right circumstances.
My test case here will be com.googlecode.sqlitemanager.openInOwnWindow(), which is part of the SqliteManager addon.
In newer builds (I'm using Nightly), there is the Browser Toolbox. With it is is as simple as opening a toolbox and executing com.googlecode.sqlitemanager.openInOwnWindow() in the Console.
You may instead use the Browser Console (or any chrome enabled WebDev Console for that matter, e.g. the Console of "about:newtab"). But you need some boilerplate code to first find the browser window. So here is the code you can execute there: var bwin = Services.wm.getMostRecentWindow("navigator:browser"); bwin.com.googlecode.sqlitemanager.openInOwnWindow()
Again, enable chrome debugging. Then open a Scratchpad and switch to Chrome in the Environment menu. Now executing com.googlecode.sqlitemanager.openInOwnWindow() in our Scratchpad will work.
You may of course write your own overlay add-on.
As a last resort, patch the add-on itself.
Bootstrapped/SDK add-ons: you can load XPIProvider.jsm (which changed location recently) and get to the bootstrapped scope (run environment of bootstrap.js) via XPIProvider.bootstrapScopes[addonID], and take it from there (use whatever is in the bootstrap scope, e.g. the SDK loader).
Now about the right circumstances: If and how you can interact with a certain add-on depends on the add-on. Add-ons may have global symbols in their overlay and hence browser window, such as in the example I used. Or may use (to some extend) JS code modules. Or have their own custom loader stuff (e.g. AdBlock Plus has their own require()-like stuff and SDK add-ons have their own loader, which isn't exactly easy to infiltate)...
Since your question is rather unspecific, I'll leave it at this.
Edit by question asker: This is correct, however I figured I'd add an example of the code I ended up using in the end, which was in fact taken directly from mozilla's developer network website:
In my chrome js:
var myExtension = {
myListener: function(evt) {
IprPreferences.setFreshIpStatus(true); // replace with whatever you want to 'fire' in the extension
}
}
document.addEventListener("MyExtensionEvent", function(e) { myExtension.myListener(e); }, false, true);
// The last value is a Mozilla-specific value to indicate untrusted content is allowed to trigger the event.
In the web content:
var element = document.createElement("MyExtensionDataElement");
element.setAttribute("attribute1", "foobar");
element.setAttribute("attribute2", "hello world");
document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent("MyExtensionEvent", true, false);
element.dispatchEvent(evt);
Update for Firefox 47 and up
Things changed drastically in Firefox 47. This is the new way to access it.
var XPIScope = Cu.import('resource://gre/modules/addons/XPIProvider.jsm');
var addonid = 'Profilist#jetpack';
var scope = XPIScope.XPIProvider.activeAddons.get(addonid).bootstrapScope
Old way for < Firefox 47
Update for methods of today
Typically you will do so like this:
If i wanted to get into AdBlocks scope, I check AdBlock id, it is {d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d} so I would go:
var XPIScope = Cu.import('resource://gre/modules/addons/XPIProvider.jsm');
var adblockScope = XPIScope.XPIProvider.bootstrapScopes['{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'];
You can now tap into anything there.
Another example, I have an addon installed with id NativeShot#jetpack
I would tap into it like this:
var XPIScope = Cu.import('resource://gre/modules/addons/XPIProvider.jsm');
var nativeshotScope = XPIScope.XPIProvider.bootstrapScopes['NativeShot#jetpack'];
if you do console.log(nativeshotScope) you will see all that is inside.

Search for injected script code on the Windows Server for my ASP.NET site

My site was probably hacked. I am finding script.js from bigcatsolutions.com in my page. It triggers a popup of an affiliate program. The script isn't on the page by default and I want to know how can I find where it was injected. The script sometimes injects other ad sites.
In chrome I see this:
The injected script code:
function addEvent(obj, eventName, func) {
if (obj.attachEvent) {
obj.attachEvent("on" + eventName, func);
} else if (obj.addEventListener) {
obj.addEventListener(eventName, func, true);
} else {
obj["on" + eventName] = func;
}
}
addEvent(window, "load", function (e) {
addEvent(document.body, "click", function (e) {
if (document.cookie.indexOf("booknow") == -1) {
params = 'width=800';
params += ', height=600';
params += ', top=50, left=50,scrollbars=yes';
var w = window.open("http://booknowhalong.com/discount-news", 'window', params).blur();
document.cookie = "booknow";
window.focus();
}
});
})
My site is moved from my hosting company to Amazon EC2 Windows 2013 Server and still have the issues, so it means that the code still resides on the server somewhere. My site was build using ASP.ENT / C#.
Things I did:
tried to search the original aspx and aspx.cs code files
Have you checked the IIS logs to see if they are hitting a specific page and injecting it there?
Do you load any data from a database? You could check in the tables and see if anything out of the ordinary appears there.
It is unlikely that the .aspx pages have actually been physically modified and even more unlikely that the DLL have been as .aspx.cs files are compiled in to your BIN folder as DLL's. The more likely scenario is that you have an unsecure page that a malicious site is injecting its script into. The other possible attack vector is that you have had malicious code via SQL injection and are loading it each time.
After deep searching and I missed it in the first run, I found that the script was injected into the ASP.NET masterpage.
I ran a search to search for a specific string in all the files and that's how I found it. It seems that the server itself was breached and the hacker put the code into several websites.
So for those of you who have this type of problem, I recommend running a text search and try to find the URL that is tights to the running script.
Hope that helps and thanks for your time.

Categories

Resources