chrome extension post request to other web page

I am a newb here, I am trying to make a chrome extension which will work alongside my rails app. It is a bookmarking app, so Id like a user to be able to browse on other sites, then to bookmark a page by clicking the chrome extension icon, and it would make the post request and add it to the users homepage.

Currently I can only get this to work from the users home page, but not from any other, which is not very useful. The issue I think is in the csrf token, which when set is set to the page of the current tab, but I think it would need to be the csrf token for the users home page in order for the request to go through? I have tried simply not including it, but this does not work, as it is required.

manifest.json :

    {
  "manifest_version": 2,
  "name": "My Cool Extension",
  "version": "0.1",
  "permissions" : [
    "tabs", 
    "", 
    "https://*/",
    "http://*/"
  ],
  "browser_action": {
    "default_icon": "icon.png"
  },
  "content_scripts": [
    {
      "matches": [""],
      "js": ["content.js", "html2canvas.js"]
    }
  ],
  "background": {
    "scripts": ["background.js"]
  }
}

background.js

    //Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
  // Send a message to the active tab
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var activeTab = tabs[0];
    chrome.tabs.sendMessage(activeTab.id, {"message": "clicked_browser_action"});
  });
});

content.js

savePage = () => {
  console.log('save page called');
  var token = document.querySelector('meta[name="csrf- 
    token"]').getAttribute('content');
  var data = {"url":window.location.href, "screenshot":'tempScreen.png', 
    "user_id": 2, "title":document.title};

  var xhr = new XMLHttpRequest();
  xhr.open('POST', 'https://hidden-bastion-43962.herokuapp.com/bookmarks');
  xhr.withCredentials = true;
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.setRequestHeader('X-CSRF-Token', token);
  xhr.send(JSON.stringify(data));
}

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if( request.message === "clicked_browser_action" ) {
      var firstHref = window.location.href;
      console.log(firstHref);
      takeScreenshot();
    }
  }
);

Why can browser extensions use “fetch” without cross-origin permissions?

When XMLHttpRequest is being used to do cross-origin requests, permissions are required via manifest.json, as stated here: https://developer.chrome.com/apps/xhr

But when using fetch, it doesn’t need it and can requests to all ressources.

What makes fetch different than XMLHttpRequest that it works without persmissions? Or is that just bug?

Overwritten headers do not work for iframes

For a very specifiy task I need to get the contents of an iframe with a different domain. The frame points to a foreign domain for which I cannot control the headers.

So I came up with a chrome extension to bypass the origin-policy of the foreign domain. Here is the extension:

manifest.json:

{
  ...

  "background": {
    "scripts": ["background.js"]
  },
  "permissions": ["webRequest", "webRequestBlocking", ""]
}

background.js:

var strip = [
  "content-security-policy",
  "x-frame-options",
  "access-control-allow-origin",
  "x-content-type-options"
];

chrome.webRequest.onHeadersReceived.addListener(
  function(details) {
    var headers = details.responseHeaders.filter(function(header) {
      return strip.indexOf(header.name.toLowerCase()) < 0;
    });
    headers.push({
      name: "Access-Control-Allow-Origin",
      value: "*"
    });

    return {
      responseHeaders: headers
    };
  },
  {
    urls: [""]
    /* types: [  // default: all types
      "main_frame",
      "sub_frame",
      "stylesheet",
      "script",
      "image",
      "object",
      "xmlhttprequest",
      "other"
    ] */
  },
  ["blocking", "responseHeaders"]
);

With the extension I am able to frame pages which were otherwise not allowed to display inside a frame. But on the other hand, the Access-Control-Allow-Origin does not take effect on iframes at all. If I run $('iframe').contents(); with the extension, I still get

Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "https://my.domain" from accessing a cross-origin frame.
at contents (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.js:3199:25)
at Function.map (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.js:451:13)
at jQuery.fn.init.jQuery.fn.(anonymous function) [as contents] (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.js:3213:24)
at :1:16

Is this a bug?

How to destroy or unset PHP session variables from chrome extension using AJAX call to the logout.php page?

logout.php


This is my AJAX call to logout in chrome extension

$('#signout_button').on('click', function(){

    $.ajax({
      type: 'GET',
      url: 'http://127.0.0.1/extension_server/logout.php',
      data:{action:'logout'},
      success: function(data) {
        console.log(data);
        chrome.storage.local.set({ "login_status" : 0, "profile_id" : null }, function() {
          $('#signout_button').css('display','none');
          $('#signin_button').css('display','block');
          $('#login_info').css('display','none');

        });

      }

    });

});

I am trying to logout from the server when i click on sign out button from chrome extension popup. Any help will be appreciated.

chrome extension access inactive tabs/ manifest must request permission

I want to create a chrome extension that is able to open an inactive tab of yelp’s page and get some contents(like title) from that page and display those contents in the pop up. But the chrome console shows the error:

Extension manifest must request permission.

manifest.json:

var tab_title = '';
var tab_id='';
function display_h1 (results){
  h1=results;
  document.querySelector("#id1").innerHTML = "

tab title: " + tab_title + "

dom h1: " + h1 + "

id:"+tab_id+"

"; } chrome.tabs.create({url:'https://www.yelp.com/biz/bareburger-forest-hills?osq=burger', active:false}); chrome.tabs.query({active:false}, function(tabs) { var tab = tabs[tabs.length-1]; tab_title = tab.title; tab_id=tab.id; chrome.tabs.executeScript(tab.id, { code: 'document.querySelectorAll("[itemprop=description]")[0].textContent' }, display_h1); });
{
  "name": "Hello World",
  "description": "Hello World Chrome App.",
  "version": "0.1",
  "manifest_version": 2,
  "permissions": [
    "tabs",
    "activeTab",
    "bookmarks",
        "http://*/",
        "https://*/",
        "*://www.yelp.com/fe",
        "https://www.yelp.com/biz/bareburger-forest-hills?osq=burger"
  ],
  "browser_action": {
    "default_icon": "hello-16.png",
    "default_popup": "popup.html"
  }
}


  
  
  
    
-

Iframe cross domain extension

So im just trying to get google to display in an Iframe, which is cross domain using a chrome extension. However i still get the error “Refused to display ‘https://www.google.com/‘ in a frame because it set ‘X-Frame-Options’ to ‘sameorigin’.” which i thought i could do with a chrome extension as long as I allowed it in the permission section. Here is the manifest and html files:

{
  "name": "Frames",
  "description": "display a frame",
  "version": "1.0",
  "permissions": [
    "activeTab",
    "https://www.google.com/"
  ],   
  "browser_action": {
    "default_icon": {
    "16": "extension.png"
    },
    "default_title": "display a frame",
  },
  "manifest_version": 2
}







random

Open an Iframe.

Accessing html of a page inside iFrame

I’m implementing a chrome extension that takes a screenshot of an iframe based on this solution. The only difference is that captured area is not selected by mouse dragging – it’s just an iframe that’s captured.

So far so good – iframe is captured as ecpected. But I would like to capture whole content of a page that’s displayed in an iframe, not just the visible part. So I thought about extracting html from that page and making a screenshot using some js library (for example html2canvas). I tried to read the content using ‘contents()’ function on an iframe object but I get an error because of cross-origin access:

Error in event handler for runtime.onMessage: SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://localhost:10039" from accessing a cross-origin frame.

I don’t have access to a target page so I cannot add any code on it. Is there any way to access target page html and make that screenshot? Maybe some other idea about getting screenshot of the whole page not just the visible part?

Thanks!

manifest.json

    {
    "name": "Iframe Capture",
    "version": "1.0.0",
    "manifest_version": 2,
    "description": "Take iframe screenshot",

    "icons": {
        "16": "img/icon16.png",
        "48": "img/icon48.png",
        "128": "img/icon128.png"
    },

    "background": {
        "scripts": [
            "js/background.js"
        ],
        "persistent": false
    },

    "content_scripts": [
        {
            "matches": ["http://*/*", "https://*/*"],
            "js": ["js/jquery/3.2.1/jquery-3.2.1.min.js", "js/content.js"],
            "run_at": "document_end",
            "all_frames": true
        }
    ],

    "browser_action": {
        "default_title": "Iframe Capture",
        "default_icon": "img/icon.png"
    },

    "permissions": [
        "tabs",
        "activeTab",
        "http://*/*",
        "https://*/*"
    ]
}

background.js

    var contentURL = '';

function cropData(str, coords, callback) {
    var img = new Image();

    img.onload = function() {
        var canvas = document.createElement('canvas');
        canvas.width = coords.w;
        canvas.height = coords.h;

        var ctx = canvas.getContext('2d');

        ctx.drawImage(img, coords.x, coords.y, coords.w, coords.h, 0, 0, coords.w, coords.h);

        callback({dataUri: canvas.toDataURL()});
    };

    img.src = str;
}

function capture(coords) {
    chrome.tabs.captureVisibleTab(null, {format: "png"}, function(data) {
        cropData(data, coords, function(data) {
            saveFile(data.dataUri);
        });
    });
}

chrome.browserAction.onClicked.addListener(function(tab) {
    contentURL = tab.url;

    sendMessage({type: 'start-screenshots'}, tab);

});

chrome.extension.onMessage.addListener(gotMessage);

function gotMessage(request, sender, sendResponse) {
    if (request.type == "coords")
        capture(request.coords);

    sendResponse({}); // snub them.
}

function sendMessage(msg, tab) {
    console.log('sending message');

    chrome.tabs.sendMessage(tab.id, msg, function(response) {});
};

function saveFile(dataURI) {

    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs
    var byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    // create a blob for writing to a file
    var blob = new Blob([ab], {type: mimeString});

    // come up with a filename
    var name = contentURL.split('?')[0].split('#')[0];
    if (name) {
        name = name
            .replace(/^https?:///, '')
            .replace(/[^A-z0-9]+/g, '-')
            .replace(/-+/g, '-')
            .replace(/^[_-]+/, '')
            .replace(/[_-]+$/, '');
        name = '-' + name;
    } else {
        name = '';
    }
    name = 'screencapture' + name + '.png';

    function onwriteend() {
        // open the file that now contains the blob
        window.open('filesystem:chrome-extension://' + chrome.i18n.getMessage('@@extension_id') + '/temporary/' + name);
    }

    function errorHandler() {
        console.log('uh-oh');
    }

    // create a blob for writing to a file
    window.webkitRequestFileSystem(TEMPORARY, 1024*1024, function(fs){
        fs.root.getFile(name, {create:true}, function(fileEntry) {
            fileEntry.createWriter(function(fileWriter) {
                fileWriter.onwriteend = onwriteend;
                fileWriter.write(blob);
            }, errorHandler);
        }, errorHandler);
    }, errorHandler);
}

content.js

chrome.runtime.onMessage.addListener(gotMessage);

function gotMessage(request, sender, sendResponse) {
    console.log('got message');
    if (request.type == "start-screenshots")
        startScreenshot();

    sendResponse({});
}

function startScreenshot() {
    var iframe = $('#iframeContent'),
    offset = iframe.offset(),
    coords = {
        w: iframe.outerWidth(),
        h: iframe.outerHeight(),
        x: offset.left,
        y: offset.top
    };

    console.log(iframe.contents()); // error!!!

    endScreenshot(coords);  
}

function endScreenshot(coords) {    
    sendMessage({type: 'coords', coords: coords});
}

function sendMessage(msg) {
    chrome.runtime.sendMessage(msg, function(response) {});
};