Is Right Click Enable safe?

Medium risk

Right Click Enable is medium risk. Reporting a problem through the feedback popup and confirming the prompt makes Right Click Enable include the page URL in the feedback payload, posted to clevermathgames.com. DA didn't trigger this; details come from the shipped code.…

45Risk

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

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

Feedback sends the current page URL to clevermathgames.com

Reporting a problem through the feedback popup and confirming the prompt makes Right Click Enable include the page URL in the feedback payload, posted to clevermathgames.com.

DA didn't trigger this; details come from the shipped code.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You report that the extension did not work on the current page.

The popup asks you to choose a content type and a specific problem before showing a confirmation dialog.

The extension did this

The extension prepares a feedback request that includes the full current page URL.

If you confirm, it posts the JSON feedback request to clevermathgames.com.

02EvidenceFIELD TABLE
Fields prepared for the feedback request
FieldValueWhy it matters
Extension name
Right Click EnableIdentifies which extension generated the report.
Current page URL
https://accounts.example.com/settings/securityShows the exact page you had open when you submitted feedback.
Extension version
0.7.7Ties the feedback report to the installed extension build.
Issue type
textRecords the category you selected in the feedback popup.
Issue description
Cannot copy textRecords the specific problem button you clicked.
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://clevermathgames.com/wp-json/custom/v1/feedback
No response was captured; the endpoint, method, and JSON content type are taken from the shipped fetch() call.
Headers
Content-Typeapplication/json
04EvidenceCODE COMPARE
The code that does this

The feedback path reads the page URL and posts it

What it actually does
Problem choice calls submitFeedbackdeobfuscated/feedback-popup.js
function promptSpecificFeedback(type){const feedbackTypes={text:{question:"What problem occurs with the text?",options:["Text cannot be selected","Menu does not appear","Cannot copy text","Another problem"]},image:{question:"What problem occurs with the image?",options:["Menu does not appear","Cannot save image as","Cannot copy image to clipboard","Another problem"]},video:{question:"What problem occurs with the video?",options:["Menu does not appear","Cannot save video as","Cannot save video frame as","Cannot copy video frame to clipboard","Another problem"]}};const{question,options}=feedbackTypes[type];feedbackPopup.innerHTML=`
            <button id="close-button">&times;</button>
            <h3>${question}</h3>
            ${options.map((option, index) => `<button class="problem-button"data-issue="${option}">${option}</button>`).join('')}
        `;shadowRoot.getElementById('close-button').onclick=cleanupPopup;Array.from(shadowRoot.querySelectorAll('.problem-button')).forEach(button=>{button.onclick=()=>submitFeedback(type,button.getAttribute('data-issue'));});}
submitFeedback includes currentLocation.href in the JSON POSTdeobfuscated/feedback-popup.js
function submitFeedback(issueType,issueDescription){const currentUrl=currentLocation.href;const dataToSend=`Extension: ${extensionName} v${extensionVersion}\nURL: ${currentUrl}\nProblem: ${issueDescription}`;const userConfirmed=window.confirm(`This feedback will be sent to developers:\n\n${dataToSend}\n\n`+"Ensure no sensitive data is included.\n\n"+"Continue sending?");if(userConfirmed){const data={name:extensionName,URL:currentUrl,version:extensionVersion,issueType:issueType,issueDescription:issueDescription};fetch('https://clevermathgames.com/wp-json/custom/v1/feedback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(data)}).then(response=>response.json()).then(data=>{console.log('Feedback sent successfully:',data);}).catch((error)=>{console.error('Error sending feedback:',error);});}
cleanupPopup();}
05EvidenceTHIRD PARTY LIST
External hosts involved in this feedback path
  • clevermathgames.com

    Receives the feedback POST containing the extension name, current page URL, extension version, issue type, and issue description.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-506
SourceAI SANDBOX

Seven-day timer injects an onlineapp.pro paywall

Right Click Enable stores an install timestamp and, seven days later for new users, injects paywall scripts on activation.

Scripts load an onlineapp.pro iframe and call it to check paywall status before opening the subscription page.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You activate the extension after it has been installed for more than seven days.

The service worker checks the stored install date before deciding which scripts to inject.

The extension did this

The extension injects paywall code into the active tab and checks payment status online.

If the returned status requires payment, the worker opens the extension's subscription page.

02EvidenceTEMPORAL PATTERN
When this fires
Every 7 days

The paywall path becomes eligible only after the stored install date is more than seven days old.

03EvidenceFIELD TABLE
Concrete values used by the paywall logic
FieldValueWhy it matters
Trial window
7 daysDetermines when the extension switches from normal activation to the paywall check.
Install timestamp
1720828800000Records when the extension was installed on your browser profile.
Paywall ID
237Identifies the onlineapp.pro paywall flow loaded by the extension.
Payment status request
https://onlineapp.pro/api/v1/paywall/237/userChecks whether the paywall service considers this browser session paid or unpaid.
04EvidenceNETWORK CAPTURE
Captured request
GEThttps://onlineapp.pro/api/v1/paywall/237/user
No response body was recorded; the URL and method come from the injected paywall.getUser() code path using the default fetch/request options.
05EvidenceNETWORK CAPTURE
Captured request
GEThttps://onlineapp.pro/paywall/237?v=2
The injected wall.js code creates an iframe for this paywall URL; no captured response body was recorded.
06EvidenceCODE COMPARE
The code that does this

The worker waits seven days, injects scripts, then checks paywall status

What it actually does
Install date is stored on first installdeobfuscated/worker.js
function setInstallDate() {
  const installDate = new Date().getTime();
  chrome.storage.local.set({
    installDate: installDate,
    newUser: true
  }, () => {
    console.log('Install date:', installDate, 'newUser:', true);
  });
}
Expired trial injects paywall scriptsdeobfuscated/worker.js
const injectionCheck = await chrome.scripting.executeScript({
  target: {
    tabId
  },
  function: checkInjection
});
const isAlreadyInjected = injectionCheck?.[0]?.result || false;
if (!isAlreadyInjected) {
  const trialOver = await new Promise((resolve) => {
    const TRIAL_IN_MS = 7 * 24 * 60 * 60 * 1000;
    chrome.storage.local.get(['installDate', 'newUser'], (data) => {
      const {
        installDate,
        newUser
      } = data;
      if (!newUser) {
        resolve(false);
        return;
      }
      if (installDate) {
        const currentDate = new Date().getTime();
        const trialPeriodOver = ((currentDate - installDate) > TRIAL_IN_MS);
        const installDateObj = new Date(installDate);
        const currentDateObj = new Date(currentDate);
        console.log('isTrialPeriodOver: ', 'trialPeriodOver:', trialPeriodOver, 'currentDate:', currentDateObj.toLocaleString(), 'installDate:', installDateObj.toLocaleString(), 'Time difference:', formatTimeDifference(currentDate - installDate));
        resolve(trialPeriodOver);
      } else {
        setInstallDate();
        resolve(false);
      }
    });
  });
  if (trialOver && !isPaywallGetUserRunning) {
    isPaywallGetUserRunning = true;
    try {
      await chrome.scripting.executeScript({
        target: {
          tabId,
          ...properties,
          allFrames: false
        },
        injectImmediately: true,
        files: ['wall.js', '/data/inject/check-payment.js']
      });
    } catch (error) {
      console.warn(error);
      notify(error.message);
      isPaywallGetUserRunning = false;
    }
  }
}
Injected payment check opens paywall when unpaiddeobfuscated/data/inject/check-payment.js
async function isPaymentRequired(callback){try{const userData=await paywall.getUser();console.log('User Data:',userData);chrome.runtime.sendMessage({method:"paywall-getuser-completed"});if(userData.countryMatch!==true){return;}
if(userData.error==='Unauthorized'){callback();return;}
if(userData.paid!==true){callback();}}catch(error){console.error('Error fetching user data:',error);}}
function checkPayment(){if(window.pointers.status==='ready'){isPaymentRequired(()=>{chrome.runtime.sendMessage({method:"openPayWallTab"});});}else{chrome.runtime.sendMessage({method:"paywall-getuser-completed"});}}
checkPayment();
07EvidenceCODE COMPARE
The code that does this

The injected paywall library loads onlineapp.pro

What it actually does
wall.js creates the iframe and user-status requestdeobfuscated/wall.js
_createAndAppendIframe: function() {
  window.requestAnimationFrame(() => {
    let e = () => {
      let e = this._paywallDocumentRoot.createElement("iframe");
      e.src = "https://onlineapp.pro/paywall/".concat(this.paywallId, "?v=2"), e.id = "paywall-".concat(this.paywallId), e.style.display = "none";
      let a = this._paywallDocumentRoot.body || this._paywallDocumentRoot;
      a ? a.appendChild(e) : console.warn("[PAYWALL ERROR] Paywall container not found")
    };
    "loading" === this._paywallDocumentRoot.readyState ? this._paywallDocumentRoot.addEventListener("DOMContentLoaded", e) : e()
  })
},
getUser: async function() {
  return await this._ensureInitialized(), this.makeRequest("https://onlineapp.pro/api/v1/paywall/".concat(this.paywallId, "/user"))
}
}, paywall.init("237")
08EvidenceTHIRD PARTY LIST
External host used by the paywall path
  • onlineapp.pro

    Hosts the paywall iframe and receives the paywall user-status request for paywall ID 237.

Updated 21 September 2026aegpaehcnpbhdmnghlnbnngogbfelnno