Is it possible for a Chrome extension's content script to ensure that a DOM event was initiated by the user?

One challenge I am facing is ensuring that click events triggered by an extension injecting HTML elements into pages are actually from user actions, rather than being programmatically created and dispatched by JavaScript on the page. Is there a method to distinguish between the two?

Answer №1

In order to determine if a click event was initiated by a user, you can utilize the event.isTrusted property. Unfortunately, this feature has not been implemented yet.

However, there is an alternative approach to detect user-initiated events. The chrome.permissions.request API requires a user gesture for success, otherwise it will fail. While using the chrome.permissions API is restricted in content scripts post Chrome 33, the user gesture state remains preserved when utilizing the messaging API to communicate between a content script and the background page (since Chrome 36). To identify whether a click event was genuinely triggered by a user, you can implement the following logic:

background.js

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message === 'is-user-gesture') {
        chrome.permissions.request({}, function() {
            // Check for errors to determine if the message was user-initiated
            var is_user = !chrome.runtime.lastError;
            sendResponse(is_user);
        });
        return true; // Async
    }
});

contentscript.js

function isUserEvent(callback) {
    chrome.runtime.sendMessage('is-user-gesture', function(is_user) {
        // Take precaution as is_user may be undefined if extension is reloaded
        is_user = is_user === true;
        callback(is_user);
    });
}
document.body.onclick = function() {
     isUserEvent(function(is_user) {
         alert(is_user ? 'Triggered by user' : 'Spoofed event');
     });
};

To test this method, follow these steps within your page or content script:

// Simulate fake event (will show "Spoofed event")
document.body.dispatchEvent(new CustomEvent('click'));
// TODO: Click on the body with your mouse (will display "Triggered by user")

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The res.download() function is not functioning properly when called from within a function, yet it works perfectly when directly called through the API in a browser

I have a button that, when clicked, triggers the downloadFile function which contacts the backend to download a file. async downloadFile(name) { await this.$axios.$get(process.env.API_LINK + '/api/files/' + name) }, app.get('/api/files/ ...

Clicking on the Bootstrap tabs causes them to shift position

I have come across an unusual issue with my website. While on the home page, clicking on a tab functions normally. However, when attempting to switch from one tab to another (such as News to Beats, Beats to News, News to Home, or Beats to Home), the tab co ...

The Date Picker pops up automatically upon opening the page but this feature is only available on IE10

There seems to be an issue with the date picker opening automatically on IE10, while it works fine in Firefox where it only appears when you click on the associated text box. Does anyone have insight into why this might be happening specifically in IE10? ...

I am facing difficulty creating a dropdown menu with nested options that only appear when the user hovers over the main selection

Here are the parent options I have and the code I have attempted to build. I would like to include sub-options such as phones, radios, speakers under the electronics parent option and many more. <select id="category" name="category" class="dropDown"& ...

A collection of JSON objects retrieved from a fetch request

When I send a fetch request to an API, I receive a response that is an array of JSON objects, for example: [ {"key":"val", "k2":"v2"}, {"k3":"v3", "k4":"v4"} ] Currently, I am handling this by using response => response.text() Is there a more efficie ...

Difficulties accessing MongoDb database using Node.js

Having issues when trying to read this data collection using mongoose and Node.js: I have a single JSON object within my Collection and I'm attempting to access it with the following code: materias.find().exec(function(err1,materias){ if(err ...

Unable to retrieve scroll position utilizing 'window.scrollY' or 'window.pageYOffset'

Issue I am facing a problem where I need to determine the scroll position in order to adjust the tooltip position based on it. This is how my tooltip currently appears: However, when I scroll down, I want the tooltip to toggle downwards instead of its c ...

How do I incorporate global typings when adding type definitions to an npm module?

Suppose I create a node module called m. Later on, I decide to enhance it with Typescript typings. Luckily, the module only exports a single function, so the m.d.ts file is as follows: /// <reference path="./typings/globals/node/index.d.ts" /> decl ...

Initiate an Ajax form submission to dynamically update the contents of a

For my project, I've set up a main page specifically for document creation in the DocumentsController. Users have the ability to alter the status of the document on this page. If the status is NEW, users are permitted to add a new device (referred to ...

Vue Component Unit Testing: Resolving "Unexpected Identifier" Error in Jest Setup

Having just started using Jest, I wanted to run a simple unit test to make sure everything was set up correctly. However, I encountered numerous errors during compilation while troubleshooting the issues. When running the test suite, Jest successfully loc ...

Creating an HTML element that can zoom, using dimensions specified in percentages but appearing as if they were specified in pixels

This question may seem simple, but I have been searching for an answer and haven't found one yet. Imagine we have an HTML element with dimensions specified in pixels: <div style="width:750px; height: 250px"></div> We can easily resize i ...

Tips for executing gulp tasks in the command line

As a newcomer to Gulp, I've encountered an issue with executing a task named task1 in my gulp.js file. When I enter "gulp task1" in the command line, it opens the gulp.js file in Brackets editor instead of running the task as expected. Can anyone offe ...

Troubleshooting problems encountered in Nest.js due to modifications made within a service.ts file

I'm currently working on a Nest.js project and here is the content of the automobile.service.ts file: import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Car } from './enti ...

template for displaying data in Vue.js using props

In my application, I have a component that I frequently use to display tables. Now, I want to enhance this component by allowing the customization of table fields (templates) through props in the parent component. This way, I can avoid constant edits to th ...

How can one pass req.validationErrors() from the backend to the frontend with Express Validator?

Hello and thank you for taking the time to read this. I am currently trying to implement express-validator in my project. It's working well as it blocks posts if, for example, the name input is empty. However, I'm struggling to display the error ...

Standardizing the file name in Internet Explorer 11 and generating a new file using JavaScript

While attempting to upload a file and normalize its name, I encountered an issue with IE11 not supporting the 'normalize' method. After some research, I discovered the 'unorm' polyfill which resolved the normalization problem. However, ...

Learn how to personalize your Material UI icon by incorporating a plus symbol

Is it possible to add a plus sign to material ui icons? I currently have the following icon: import ApartmentIcon from '@mui/icons-material/Apartment'; https://i.sstatic.net/FejuX.png I would like to add a plus sign to this icon, similar to t ...

Looking for some help with tweaking this script - it's so close to working perfectly! The images are supposed to show up while

Hey everyone, I'm struggling with a script issue! I currently have a gallery of images where the opacity is set to 0 in my CSS. I want these images to become visible when scrolling down (on view). In this script, I have specified that they should app ...

The magnitude of each new keystroke is squared compared to its predecessor

exploring the relationship between keyboard and console inputs Each subsequent e.key entry is occurring twice as frequently as the previous one. Once it reaches 8-9 characters, the rendering frequency skyrockets to over 1000 times per character. Here&apos ...

The stringByEvaluatingJavaScriptFromString method is essentially ineffective

Currently, I am utilizing goNative.io to execute my web application within a wrapper/native iOS app. In order to enhance the functionality, I have incorporated some additional objective-c code that is responsible for extracting and storing data from HTML5 ...