Chrome webRequest API: onBeforeSendHeaders event will no change headers - google-chrome-extension

I created an extension, that sends different User-Agent header, if a kill switch is not enabled. Kill switch is a button, that, once clicked, changes 'ks' in chrome.storage.sync value from 0 to 1 and from 1 to 0. In the background.js, in onBeforeSendHeaders listener, I check the chrome storage for 'ks' or kill switch value. If its a 1, then the extensions should change the user agent to default. If its a 0, then user agent gets changed to the custom agent. The thing is - without that check, the code works fine, but you cant stop the listener from changing the user agent. When the check is added, it only sends the default, even tho 'ks' is 0.
manifest.json
{
"manifest_version": 2,
"name": "UserAgent changer",
"description": "changes user agent",
"version": "1.0.1",
"permissions": ["tabs","webRequest","webRequestBlocking", "*://*/*", "storage"],
"background":{
"scripts":["background.js"],
"persistent": true
},
"browser_action": {
"default_popup": "popup.html"
}
}
background.js
chrome.webRequest.onBeforeSendHeaders.addListener(function(details){
var headers = details.requestHeaders,
blockingResponse = {};
for( var i = 0, l = headers.length; i < l; ++i ) {
if( headers[i].name == 'User-Agent' ) {
chrome.storage.sync.get('ks', function(result){
if (result.ks == 0){
headers[i].value = 'Custom agent';
}else{
headers.value = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36";
}
});
break;
}
}
blockingResponse.requestHeaders = headers;
return blockingResponse;
},
{urls: [ "<all_urls>" ]},['requestHeaders','blocking']);
chrome.runtime.onInstalled.addListener(function() {
// Set kill switch to True by default
chrome.storage.sync.set({ks: 1});
});
popup.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Popup</title>
<style>
button{
width: 100px;
}
</style>
</head>
<body>
<button id="toggleAgent">Turn on agent</button>
<script src="popup.js"></script>
</body>
</html>
popup.js
console.log("loaded");
btn = document.getElementById("toggleAgent");
chrome.storage.sync.get('ks', function(result){
if (result.ks == 1){
btn.innerText = "Turn on agent";
}else{
btn.innerText = "Turn off agent";
}
});
btn.onclick = function(){
chrome.storage.sync.get('ks', function(result){
console.log(result);
if (result.ks == 1){
btn.innerText = "Turn off agent";
chrome.storage.sync.set({ks: 0});
}else{
btn.innerText = "Turn on agent";
chrome.storage.sync.set({ks: 1});
}
});
};

Related

Notification not sending to Firefox client(Firebase Cloud Messaging)

I am using Node.JS on server side to send notification to 3 clients(browsers). Clients on Microsoft Edge and Chrome receive notifications, but Firefox do not (p.s. i'am testing on domain with https encryption)
Client code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script type="module">
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.9.1/firebase-app.js";
import {
getMessaging,
getToken,
onMessage,
} from "https://www.gstatic.com/firebasejs/9.9.1/firebase-messaging.js";
const firebaseConfig = {
/* <config> */
};
const app = initializeApp(firebaseConfig);
const vapidKey = "vapid";
window.messaging = getMessaging();
window.messaging.onMessageHandler = console.log;
getToken(window.messaging, { vapidKey }).then((token) => {
const p = document.createElement("p");
p.appendChild(document.createTextNode(token));
document.querySelector("html").appendChild(p);
});
</script>
</body>
</html>
Server side code:
const firebase = require("firebase-admin");
const serviceAccount = require("mycredentials.json");
const app = firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
});
firebase
.messaging(app)
.sendMulticast({
tokens: [
"<edge token>",
"<chrome token>",
"<firefox token>"
],
data: {
test: "Test",
},
webpush: {
notification: {
body: "Halo!",
title: "notification_new_message",
},
},
})
.then((response) => {
console.log(JSON.stringify(response, null, 4));
});
Unfortunately, I receive error:
{
"responses": [
{
"success": true,
"messageId": "<messageId>"
},
{
"success": true,
"messageId": "<messageId>"
},
{
"success": false,
"error": {
"code": "messaging/third-party-auth-error",
"message": "Auth error from APNS or Web Push Service"
}
}
],
"successCount": 2,
"failureCount": 1
}
I tried sending single request(messages:send) to Firefox Client, but it fails with the same error. Also, I tried to manually build and send raw Batch Request, but result was the same.
How can I figure it out?

Send command 'Emulation.setDeviceMetricsOverride' does not work in chrome.debugger

I writing an extension to emulate the mobile device whenever user click on extension icon. This is just the first version of extension so that everything was hardcoded.
I basically attached successfully to Chrome current tab but I do not know why my commands does not work as expected. I using Chrome version 79 with protocolversion command is 1.3. The steps I currently implemented are:
Attach to current chrome tab.
Using Browser.getVersion to checking whether I am using correct protocol version
Using Emulation.canEmulate to make sure chrome can emulate mobile device.
Using Emulation.clearDeviceMetricsOverride to clear all of metrics if any.
Using Emulation.setUserAgentOverride to override current user agent.
Using Emulation.setDeviceMetricsOverride to emulate mobile device.
Enable touch event using Emulation.setTouchEmulationEnabled to emulate mobile event.
Here is code of above steps:
function EmulateMobileDevice(tabId) {
var protocolVersion = '1.3';
chrome.debugger.attach({
tabId: tabId
}, protocolVersion, function() {
if (chrome.runtime.lastError) {
alert(chrome.runtime.lastError.message);
return;
}
// Browser.getVersion
chrome.debugger.sendCommand({
tabId: tabId
}, "Browser.getVersion", {}, function(response) {
console.log(response);
});
// Emulation.canEmulate
chrome.debugger.sendCommand({
tabId: tabId
}, "Emulation.canEmulate", {}, function(response) {
console.log(response);
});
// Emulation.clearDeviceMetricsOverride
chrome.debugger.sendCommand({
tabId: tabId
}, "Emulation.clearDeviceMetricsOverride", {}, function(response) {
console.log(response);
// Emulation.setUserAgentOverride
chrome.debugger.sendCommand({
tabId: tabId
}, "Emulation.setUserAgentOverride", {
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1',
acceptLanguage: 'en',
platform: 'mobile'
}, function(response) {
console.log(response);
//Emulation.setDeviceMetricsOverride
chrome.debugger.sendCommand({
tabId: tabId
}, "Emulation.setDeviceMetricsOverride", {
width: 0,
height: 0,
deviceScaleFactor: 0,
mobile: true,
screenOrientation: { type: 'portraitPrimary', angle: 1}
}, function(response) {
console.log(response);
// Emulation.setTouchEmulationEnabled
chrome.debugger.sendCommand({
tabId: tabId
}, "Emulation.setTouchEmulationEnabled", {
enabled: true
}, function(response) {
console.log(response);
});
});
});
}); });}
I refered the same idea here implemented by #paulirish but he demonstrated in protocol version 1.1 which was deprecated for now. And I also read the document from here for protocol version 1.3.
Unfortunately I can not get it work.
Here is the screenshot I logged in background script of above method.
Many thanks.
I think you need to reload the page after modifying DeviceMetricsOverride
using
chrome.tabs.reload(tabId);
If you can brief about what you want to do with your code that would help,
As of now, code would just show the tab as it is because when width, height and deviceScaleFactor are set to '0'(zero) it would set the website to the default size, but since you specified mobile true default scroll bar would change(It may hide based on your css).

login website using casperjs?

I am try to login a site using casperjs .
I try this code.
var casper = require('casper').create({
pageSettings: {
loadImages: false,
loadPlugins: false,
userAgent: 'Mozilla/45.0.2 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
}
});
casper.start().thenOpen("https://sellercentral.amazon.in/gp/homepage.html", function() {
console.log("amazon site website opened");
var html = this.getPageContent();
console.log(html);
});
casper.then(function(){
console.log("Login using username and password");
this.evaluate(function(){
document.getElementById("username").value="******";
document.getElementById("password").value="******";
document.getElementById("sign-in-button").click();
});
});
casper.then(function(){
console.log("Make a screenshot and save it as AfterLogin.png");
this.wait(40000);
this.capture('AfterLogin.png');
});
casper.run();
But I get the output
<html><head></head><body></body></html>
Login using username and password
Make a screenshot and save it as AfterLogin.png
[]
when I print console.log(html) that only print above html tags.
I also try same code for facebook.com still get same .
You can use nightmare.js or phantom.js. Both will allow i to read html from website and simulate events.
Alternatively, u can check the endpoints and just hit them there to retrieve data
Your issue may be binded to unsuccessful CAPTCHA test pass (you'll miss it when using loadImages: false) at //*[#id="ap_captcha_img"]/img XPath on given response.
In a CasperJS/1.1.1+PhantomJS/2.1.1 setup, using a similar code
var sURL = 'https://sellercentral.amazon.in/gp/homepage.html';
var casper = require("casper").create({
pageSettings: {
loadImages: true,
userAgent: 'Mozilla/45.0.2 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.75 Safari/537.36'
}
});
casper.start();
casper.thenOpen(sURL, function() {
console.log("website opened");
var html = this.getPageContent();
console.log(html);
});
casper.then(function(){
console.log("Login using username and password");
this.fill('form[name=signinWidget]', {
'username': 'username',
'password': '123456'
}, true);
});
casper.wait(10000, function() {
console.log("Make a screenshot and save it as AfterLogin.png");
this.capture('AfterLogin.png');
});
casper.run(function() {
this.exit();
});
got the following output
website opened
<!DOCTYPE html><html><head>
<!--
whole resource HTML
-->
</body></html>
Login using username and password
Make a screenshot and save it as AfterLogin.png

Access-Control-Allow-Origin chrome extension persmission not working

I try to get the html page from a internal webserver in my js code, and parse it to make bookmarks.
At the moment I have problems with Access-Control-Allow-Origin, but the permissions are set !
{
"manifest_version": 2,
"name": "test",
"description": "test",
"version": "1.0",
"options_page":"config.html",
"browser_action": {
"default_popup": "test.html",
"permissions": [
"*://*/*"
],
"content_security_policy": "script-src 'self' https://example.com; object-src 'self'"
}
}
I try the code from the example here : https://developer.chrome.com/extensions/xhr :
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = JSON.parse(xhr.responseText);
}
}
xhr.send();
But I get the error
XMLHttpRequest cannot load http://api.example.com/data.json. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'chrome-extension://nnbpdlokhkemfjmfkmlfnjonmeaccdmo'
is therefore not allowed access.
I'm pretty lost !
Actually I want to do that (that doesn't work either) :
function httpGet(url,user,pass)
{
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET",url, false );
xmlHttp.setRequestHeader("Authorization", "Basic " + btoa(user + ":" +pass))
xmlHttp.send( null );
response= xmlHttp.responseText;
startT=response.indexOf("menuData = [");
//alert(startT);
Text=response.substr(startT+11 );
Text=Text.substr(0,Text.indexOf("\n"));
var obj = eval (Text)
return Text
}
The permissions section of the manifest should be an independent entry, not located inside browser_action. Check the documentation for the manifest file format.

not allowed by Access-Control-Allow-Origin

If I run this Code:
function sendRequest() {
var req = new XMLHttpRequest();
req.open("GET", "http://www.google.com/search?XXXX", true);
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
alert( req.responseText );
}
}
};
req.send();
}
I get this error:
XMLHttpRequest cannot load http://www.google.com/search?XXXX. Origin chrome-extension://loifkhcbcjakjhcmecadcbdgfldfjfce is not allowed by Access-Control-Allow-Origin.
why??
In manifest file I have:
"permissions": [
"<all_urls>"
]
Demi
That will work for a packaged Chrome app, but not a hosted one.

Resources