D
D
dollar2018-09-25 00:12:09
Google
dollar, 2018-09-25 00:12:09

How to make a Chrome extension less suspicious?

I wrote a simple extension that shows if the site is blocked by Roskomnadzor. But Google rejected it for publication, explaining that the extension is suspicious. How to be?

Email text from Google
Dear Developer,
Your Google Chrome item, "BlockListCheck", with ID:
mdbffnnpjhnfmnenfkffjohdgjfeiodn did not comply with our policies and was
removed from the Google Chrome Web Store.
We routinely review items in the Chrome Web Store for compliance with our
Program policies to ensure a safe and trusted experience for our users. Per
our policies, where possible, make as much of your code visible in the
package as you can. If some of your app's logic is hidden and it appears to
be suspicious, we may remove it. During the course of a review, your item
was found to be suspicious
and has one or more file(s) that contain
minified or obfuscated code which is not human readable.
To have your item reinstated, please make any necessary changes to ensure
that all of the files and code are included in the item’s package and are
human readable.
If you'd like to re-submit your item, please make appropriate changes to
the item so that it complies with our policies, then re-publish it in your
developer dashboard. Please reply to this email for issues regarding this
item removal.
*Please keep in mind that your re-submitted item will not be immediately
published live in the store. All re-submitted items undergo a strict
compliance review and will be re-published if the item passes review.
*Important Note- Repeated or egregious violations in the store may result
in your developer account being banned from the store. This may also result
in the suspension of related Google services associated with your Google
account. All re-submitted items will continue to be subject to Chrome Web
Store policies and terms of service.
Thank you for your cooperation,
Google Chrome Web Store team

The code is simple:
popup.js - 8 lines
let time_str = chrome.extension.getBackgroundPage().temp_domain_blocked;

document.addEventListener('DOMContentLoaded', function () {
  if (time_str && time_str != "?")
    document.getElementById('time').innerHTML = "Дата блокировки: " + time_str;
  else 
    document.getElementById('time').innerHTML = "В реестре отсутствует";
})
background.js - 86 lines
function extractHostname(url) {
    var hostname;
    if (url.indexOf("//") > -1) {
        hostname = url.split('/')[2];
    }
    else {
        hostname = url.split('/')[0];
    }
    hostname = hostname.split(':')[0];
    hostname = hostname.split('?')[0];
    return hostname;
}

function extractRootDomain(url) {
    var domain = extractHostname(url),
        splitArr = domain.split('.'),
        arrLen = splitArr.length;

    if (arrLen > 2) {
        domain = splitArr[arrLen - 2] + '.' + splitArr[arrLen - 1];
        if (splitArr[arrLen - 2].length == 2 && splitArr[arrLen - 1].length == 2) {
            domain = splitArr[arrLen - 3] + '.' + domain;
        }
    }
    return domain;
}

var data_updated = "?";
var data_blocked_ip = {};
var data_blocked_domain = {};

var temp_domain_blocked = "?";

function updateIcon(url) {
  //chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0, canvas.width,canvas.height)});
  temp_domain_blocked = "?";
  //console.log("url:",url);
  if (!url)
    chrome.browserAction.setIcon({path: "images/circ_gray_gray_16.png"});
  else if (url.substr(0,4) != "http" && url.substr(0,5) != "https") {
    chrome.browserAction.setIcon({path: "images/circ_gray_gray_16.png"});
  }
  else if (temp_domain_blocked = data_blocked_domain[extractHostname(url)] || data_blocked_domain[extractRootDomain(url)] ) {
    chrome.browserAction.setIcon({path: "images/circ_pink_red_16.png"});
  }
  else
    chrome.browserAction.setIcon({path: "images/circ_green_green_16.png"});
}

function addDomain(domain, date) {
  data_blocked_domain[domain] = date;
}

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    let data = JSON.parse(xhttp.responseText);
    console.log('rules loaded');
    data_updated = Object.keys(data)[0];
    data = data[data_updated];
     
    for(let i=0,len=data.length;i<len;i++){
      let row = data[i];
      for(let j=0;j<row.ip.length;j++) data_blocked_ip[row.ip[j]] = true;
      if (row.page) addDomain(row.page, row.date);
    }
    console.log('done');
    }
};
xhttp.open("GET", "testdata.txt", true);
xhttp.send();

chrome.tabs.onActivated.addListener(function(activeInfo) {
  //console.log([activeInfo.tabId, activeInfo.windowId]);
  chrome.tabs.get(activeInfo.tabId, function( tab) {
    console.log("onActivated",tab.url,tab)
    updateIcon(tab.url)
  })
});

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (changeInfo.url && tab.active) {
    console.log("onUpdated",changeInfo.url,changeInfo,tab);
    updateIcon(changeInfo.url)
  }
})
Permissions - only access to tabs
{
  "manifest_version": 2,
 
  "name": "BlockListCheck",
  "short_name": "BlockListCheck",
  "description": "Показывает в виде иконки, внесён ли сайт в реестр, и как именно.",
  "version": "0.11",
  "icons": {
      "16": "images/logo_16.png",
      "32": "images/logo_32.png",
      "48": "images/logo_48.png"
  },
 
  "permissions": [
    "tabs"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": true
  },
  "options_page": "options.html",
  "browser_action": {
      "default_icon": {
      "16": "images/logo_16.png",
      "32": "images/logo_32.png",
      "48": "images/logo_48.png"
      },
      "default_title": "BlockListCheck",
      "default_popup": "popup/popup.html"
  }
}

That is, the extension does not even have access to the content of the pages. Can only read tab URL. Does not access external resources! That is, a priori (according to the code) it cannot send or receive anything from other sites. The code is not obfuscated and extremely simple.
Roskomnadzor registry database downloaded from Roskomsvoboda (json 20 megabytes). And saved in the local extension file as a json file. (In the future, of course, I wanted to fasten the auto update).
What could be suspicion, and how to prove to Google that everything is clean?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Y
Yuri, 2018-09-25
@dollar

most likely due to the large size of Jason.
try to submit first with a truncated file to 1mb for example.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question