What is the @grant Directive in Userscripts?
The @grant directive is a crucial header element in
userscript metadata that controls access to specialized, elevated APIs
provided by script managers like Tampermonkey, Violentmonkey, and
Greasemonkey. By explicitly declaring the privileges a script requires,
@grant acts as a security barrier between the webpage
environment and your custom code. It determines whether your script
operates in a restricted sandbox with access to enhanced browser
capabilities or in a standard JavaScript execution context.
Why the
@grant Directive is Essential
Userscripts run on top of third-party websites, which creates inherent security risks. If a userscript has unrestricted access to sensitive browser APIs while running alongside untrusted web pages, malicious scripts on those pages could potentially hijack those privileges.
The @grant directive solves this issue through a strict
permission model:
- Security Sandboxing: It isolates the userscript’s execution context from the page’s native scripts, preventing page-level JavaScript from tampering with the userscript or accessing its privileges.
- Explicit Permissions: It requires developers to declare exactly which enhanced features (like cross-domain HTTP requests or persistent storage) the script needs before execution.
- API Unlocking: It gives the script access to
special
GM_*orGM.*functions that standard page JavaScript cannot use due to same-origin policies and browser security restrictions.
Common @grant
Values and Functions
Depending on what your script needs to accomplish, you will specify different values in the metadata block.
1. Requesting Specific GM APIs
When your script needs specific elevated privileges, you list each function name individually:
// ==UserScript==
// @name Custom Data Saver
// @namespace http://tampermonkey.net/
// @version 1.0
// @match https://example.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// ==/UserScript==Key APIs unlocked by these grants include:
GM_setValue/GM_getValue: Allows the script to store and retrieve data persistently across different browsing sessions and web domains.GM_xmlhttpRequest: Bypasses standard same-origin policy limitations, enabling cross-domain AJAX requests to external APIs.GM_addStyle: Inject custom CSS styles directly into the target document safely.GM_registerMenuCommand: Adds custom interactive entries to the extension’s browser popup menu.
2. @grant none
Setting @grant none tells the script manager that your
script does not require any special privileges.
// ==UserScript==
// @name Simple DOM Modifier
// @match https://example.com/*
// @grant none
// ==/UserScript==When @grant none is used:
- The script runs directly in the context of the target webpage rather than a sandbox.
- Execution performance is slightly faster because context-bridging overhead is eliminated.
- The script can directly access and modify global window variables
(
window.myVariable) created by the host page.
3.
@grant window.close or
@grant window.focus
Some script managers allow specific browser window capabilities to be granted directly, enabling functionality that standard web pages normally restrict for security reasons.
Security Implications of Privileged Grants
Using @grant directives that unlock powerful APIs comes
with a responsibility to write safe code.
For instance, granting GM_xmlhttpRequest alongside
dynamic input handling can expose users to security risks if data
fetched from external sources is injected directly into the DOM without
sanitization. Script managers enforce the @grant model
specifically so users can inspect a script’s requested permissions
before installing it, ensuring full transparency regarding what the
script can do behind the scenes.