Detects remote, message, or persisted user-data payloads that reach JavaScript execution APIs. This rule is focused on code strings that can be evaluated at runtime.
- Remote request results from
fetch,axios,http,https,got, orsuperagentflow into execution sinks. - Message event callback data from windows, HTTP streams, WebSockets, workers, or Joplin webview messages flows into execution sinks.
joplin.data.userDataGet()payloads flow into execution sinks.- Execution sinks include
eval,Function, string-basedsetTimeout, string-basedsetInterval, andvmexecution APIs.
- Remote data flows to dynamic code execution. Verify if the endpoint is a trusted Joplin service or a remote server.
Detects sensitive Joplin settings that flow into external or untrusted sinks. It covers credential, sync, encryption, API token, client ID, and user identity settings.
joplin.settings.globalValue()orglobalValues()for sensitive keys flows into network request data or URLs.- Sensitive settings flow into file paths or file contents being written.
- Sensitive settings flow into command execution sinks.
- Sensitive settings flow into Joplin data writes, hidden user data, or webview HTML sinks.
- Critical Security Alert: Sensitive configuration data (such as a master password, sync cache, encryption keys, or API tokens) is flowing directly to an external or untrusted sink. This is highly suspicious behavior. Confirm whether the plugin has a legitimate, fully disclosed reason to touch credentials.
Detects direct reads of highly sensitive settings even when no exfiltration flow is proven. It is a manual-review signal for suspicious credential access patterns.
- Code reads
sync.*.password,api.token,encryption.cachedPpk, orencryption.passwordCache. - Code reads both
encryption.masterPasswordandsyncInfoCachein the same codebase.
- MANUAL REVIEW REQUIRED: Trying to access a highly sensitive credential.
- MANUAL REVIEW REQUIRED: Combined access of BOTH masterPassword and syncInfoCache detected in this codebase.
Detects ordinary filesystem operations that use path sources outside the plugin data directory. Archive extraction destinations are handled exclusively by Rule 17b.
__dirname,process.cwd(), Electron app paths,os.homedir(), oros.tmpdir()flows into filesystem path sinks.- Native filesystem and
fs-extrapath arguments are treated as sinks for writes, moves, copies, deletes, renames, chmods, and directory operations. - Paths based only on
joplin.plugins.dataDir()remain safe, while paths mixed with unsafe sources or explicit parent-directory traversal are reported.
- Temporary Directory Access: The plugin is writing to
os.tmpdir(). Check if this is a temporary file creation. If it is used for persistent writes, move it tojoplin.plugins.dataDir(). - Unauthorized File System Access: The plugin is using path-revealing variables (like
__dirnameorprocess.cwd) to write, modify, or delete files outside of the safe Joplin sandbox. Plugins must exclusively usejoplin.plugins.dataDir()for persistent file storage.
Detects plugins that attempt to modify their own installed package files. It distinguishes a path being changed from a path that is only read or mentioned as file content.
__filenameflows into a filesystem mutation target.joplin.plugins.installationDir()and a protected package filename (index.js,main.js,plugin.js,manifest.json, orpackage.json) flow into the same mutation target.- Files that are only copied from the installation directory are not treated as modified, and archive destinations are handled by Rule 17b.
- Plugin Self-Modification: The plugin is attempting to overwrite or delete its own installation files. A plugin should never modify its own packaged files.
Detects hardcoded filesystem operations against sensitive local configuration paths. It flags reads and mutations of Joplin profile files and SSH credential locations.
- A hardcoded
.config/joplin-desktoppath flows into a filesystem read or mutation target, including itsdatabase.sqlitefile. - A hardcoded
.sshpath or completeid_rsaorauthorized_keysfilename flows into a filesystem read or mutation target. - Similar-looking filenames, unrelated
database.sqlitefiles, and sensitive text used only as file content are not reported. - Archive extraction destinations are handled exclusively by Rule 17b.
- Sensitive Path Targeting: The plugin contains a hardcoded operation targeting a sensitive user configuration or credential path. This is a severe threat indicator for data theft or tampering. Verify this immediately.
Detects code that creates a server or socket and starts listening for inbound connections. It covers Node networking modules and common web server frameworks.
net,http,https,tls, ordgramserver/socket creation flows intolisten,bind, orstart.wsorsocket.ioserver creation flows intolisten,bind, orstart.express,koa, orfastifyapp creation flows intolisten,bind, orstart.- WebSocket servers with a constructor
portand Socket.IO servers with a numeric constructor port are detected without requiring a laterlisten()call. - Positional and option-object
hostoraddressvalues recognizelocalhost,127.0.0.1, and::1as loopback-only binds. - Localhost-only binds are still reported with a dedicated manual-review message; server objects that never begin listening are not reported.
- Localhost Bind Detected: The plugin is opening a local listening port restricted to localhost. Check if the plugin explicitly advertises running a local server.
- Network Backdoor: The plugin is opening a listening port that may be accessible externally. This is a severe threat indicator. Verify whether this is strictly required and heavily authenticated.
Detects data being written back into the user's clipboard from risky sources. It covers text, HTML, and image replacement using either remote data or existing clipboard content.
joplin.clipboard.readText(),readHtml(), orreadImage()flows into a clipboard write operation.- Remote request results flow into
writeText(),writeHtml(),writeImage(), orwrite().
- Clipboard Hijacking Risk: The plugin is writing remote data or existing clipboard content back to the user's clipboard. Verify that this is triggered by a deliberate user action (like clicking a "Copy" button). If this happens silently in the background, it may be attempting to replace copied content.
Detects text, HTML, or image clipboard contents being sent over the network. It tracks reads from Joplin's clipboard API to outbound request sinks.
joplin.clipboard.readText(),readHtml(), orreadImage()flows into network request data.joplin.clipboard.readText(),readHtml(), orreadImage()flows into network request URLs.
- Clipboard Exfiltration Risk: The plugin is reading the user's clipboard and sending the contents over the network.
Detects text or HTML clipboard contents being executed as code or commands. It tracks clipboard reads into JavaScript execution and terminal execution sinks.
joplin.clipboard.readText()orreadHtml()flows into child process or system command execution.- Clipboard text or HTML flows into the global
eval,Function, string-basedsetTimeout, or string-basedsetIntervalAPIs. - Clipboard text or HTML flows into Node
vmexecution APIs such asrunInThisContext,runInNewContext,runInContext,compileFunction, orScript.
- Clipboard Execution Risk: The plugin is reading the user's clipboard and passing its contents into a code evaluation or terminal command sink.
Detects repeated or background clipboard access. It is a structural rule for clipboard reads or writes inside loops, iteration callbacks, and recurring timers.
readText(),readHtml(),readImage(),writeText(),writeHtml(),writeImage(), orwrite()appears inside a loop.- Clipboard access appears inside a
setIntervalcallback. - Clipboard access appears inside a directly or wrapper-recursive
setTimeoutcallback. - Clipboard access appears inside
forEachormapcallbacks. - Clipboard access in helpers called by those repeated callbacks is included; nested helpers that are only declared and never invoked are excluded.
- Repeated Clipboard Access: The plugin is reading or writing the clipboard inside a loop, iteration callback, or recurring timer. Verify that this repeated access is explicitly initiated and expected by the user.
Detects remote payloads or cryptocurrency-mining indicators reaching operating-system command execution. It covers both direct command construction and a downloaded payload that is written to a file and then executed.
- Results from the shared
fetch, Axios, Got, Superagent, and Node HTTP response model flow into an executable command or its argument list. - Downloaded data written to a file taints that file path, so executing the resulting file is detected.
- Strings containing miner indicators such as
xmrig,minerd,ethminer,cgminer,t-rex,nsfminer,pool.,stratum+tcp, ornicehashflow into a command or its argument list. - Shell-interpreted inputs, including
exec()andspawn()withshell: true, receive a stronger warning. - Remote or miner-related values used only as unrelated options or ordinary data are not treated as executable command input.
- The plugin is passing remote data or a cryptocurrency-mining indicator to a shell-interpreted command. Shell interpretation can treat metacharacters as additional commands. Verify the command input for malware or resource hijacking.
- The plugin is passing remote data or a cryptocurrency-mining indicator to an operating-system command or its argument list. Verify that it is not executing a downloaded payload or hijacking system resources.
Detects Joplin-controlled or user-controlled data reaching terminal command execution. It excludes sensitive settings handled by the dedicated secret theft rule.
- Statically known non-sensitive
joplin.settings.globalValue()orglobalValues()results flow into command execution; mixed or sensitive key reads remain owned by Rule 2. joplin.data.get(),joplin.data.userDataGet(), orjoplin.workspace.selectedNote()flows into command execution.- Parameters from supported workspace and editor lifecycle callbacks flow into command execution.
- Panel, editor, or content-script messages and user-entered results returned by
joplin.views.dialogs.open()flow into command execution. - Joplin or user-controlled executable values are always reported. Argument lists are reported only when a shell interprets them or a fixed code interpreter such as Node, Python, a system shell, or PowerShell receives them.
- Ordinary file paths passed as separate arguments to fixed non-shell utilities such as
execFile("cp", ...)orexecFile("mv", ...)are not command-execution findings.
- Command Execution: Joplin or user-controlled data reaches an operating-system command or its argument list. Verify that the command is expected and cannot be manipulated into executing unintended programs or options.
Detects hardcoded command strings passed to operating-system command APIs. It is a structural command-execution indicator that does not require a taint source.
- A string literal, constant concatenation, or locally assigned constant is used as an executable or shell command.
- Node child-process APIs and other command APIs represented by CodeQL's
SystemCommandExecutionmodel, including Execa, are covered. - Fixed
cpandmvexecutions are excluded only when they use a non-shell API. Shell-interpreted forms remain reportable. - An execution containing a hardcoded miner indicator in either its command or literal argument list is excluded because Rule 6 owns that finding.
- Dynamic commands and hardcoded strings used only as ordinary data are not reported by this structural rule.
- Terminal Command Execution (Hardcoded): A hardcoded operating-system command is executed. Review the command and its arguments to confirm that invoking native processes is required and safe.
Detects note, folder, or resource data being sent to external network endpoints. It covers bulk Joplin data reads and the currently selected note.
joplin.data.get(["notes", ...])flows into network request data or URLs.joplin.data.get(["folders", ...])flows into network request data or URLs.joplin.data.get(["resources", ...])flows into network request data or URLs.- Search results and notes returned through a tag's linked
notesroute flow into network request data or URLs. joplin.workspace.selectedNote()flows into non-loopback network request data or URLs.- Only exact loopback hosts (
localhost,127.0.0.1, and[::1]) are excluded.
- Data Exfiltration Warning: The plugin is reading notes, folders, or resources and sending that data to an external network endpoint. Check if the plugin is a legitimate sync/export tool. If not, this is a massive privacy breach. Verify exactly what data is being sent in the payload.
Detects note data being encrypted and written back over the original note. It models a multi-stage ransomware pattern rather than a single sink.
- Joplin note data from
joplin.data.get(["notes", ...])orselectedNote()flows into a cipherupdate()or anencrypt()call. - Encryption output flows specifically into the
bodywritten byjoplin.data.put(["notes", id], ...). - The ID read from Joplin must match or flow into the exact write ID, including IDs derived from bulk note reads.
- Writes executed repeatedly through loops, iteration callbacks, timers, or their helper functions are marked as bulk activity.
- Ransomware Pattern Detected: The plugin is reading Joplin notes, passing them through an encryption cipher, and overwriting the original notes. Unless this plugin is explicitly designed as an end-to-end encryption tool, this behavior mimics ransomware. Verify that the user holds the decryption keys locally and that this action is the actual behavior of plugin.
- Ransomware Pattern Detected [BULK LOOP DETECTED]: The plugin is reading Joplin notes, passing them through an encryption cipher, and overwriting the original notes. Unless this plugin is explicitly designed as an end-to-end encryption tool, this behavior mimics ransomware. Verify that the user holds the decryption keys locally and that this action is the actual behavior of plugin.
Detects encryption key material being sent over the network. It focuses on keys used for local encryption operations.
- Key arguments to
createCipher()orcreateCipheriv()flow into network request data or URLs. - Key arguments to WebCrypto or CryptoJS
encrypt()operations flow into network request data or URLs. - The key-data argument to WebCrypto
importKey()flows into network request data or URLs; its algorithm metadata is not treated as key material. - Key bytes returned by WebCrypto
exportKey()flow into network request data or URLs.
- Critical Ransomware Indicator: Encryption key material is flowing to an external network endpoint.
Detects export module data flowing into destinations outside the normal export path. It tracks data from registered Joplin export callbacks to dangerous sinks.
registerExportModule()callback parameters fromonInitoronCloseflow into network, command, or unauthorized filesystem sinks.- All
onProcessItemcallback parameters flow into network, command, or unauthorized filesystem sinks. onProcessResourcecallback parameters flow into network, command, or unauthorized filesystem sinks.- Inline objects, factory-returned objects, and class instances registered as export modules are covered.
- File writes and copies under the export destination are excluded, but parent traversal,
dirname(), and absoluteresolve()destinations remain reportable. - Filesystem access through the official
joplin.require("fs-extra")API is covered.
- [High Confidence] Backup Hijacking Alert: Export data is confirmed flowing into a network request, terminal command, or unauthorized file path instead of the legitimate export destination.
Detects dangerous operations inside export module callbacks without requiring proven taint flow. It is a lower-confidence structural companion to Rule 10.
- A network request executes directly or through a helper from
onInit,onProcessItem,onProcessResource, oronClose. - A command execution sink executes directly or through a helper from one of those export callbacks.
- A filesystem operation targets a path outside the allowed export destination; copy, move, and rename operations check their destination argument.
- Inline objects, factory-returned objects, class instances, and
joplin.require("fs-extra")filesystem calls are covered. - The structural result does not require proven export-data flow and may accompany Rule 10's high-confidence result.
- [Structural Review] Backup Hijacking Indicator: A network request, terminal command, or filesystem operation executes from a Joplin export callback. This structural result does not by itself prove that export data leaves the approved destination. \nReviewer Action: Verify that the operation is required by the export format and that filesystem targets remain under
context.destPath.
Detects sensitive data being injected into external URLs inside Joplin webview HTML. It covers URL-based exfiltration through dynamic HTML attributes.
joplin.data.get()results flow into externally hostedscript,iframe,img,link, ormetaURL attributes passed tosetHtml().- Sensitive
joplin.settings.globalValue()results flow into externally hosted URL attributes passed tosetHtml(). - Sensitive
process.envvalues flow into externally hosted URL attributes passed tosetHtml(). - Panel, dialog, and editor
setHtml()calls are covered.
- URL Smuggling: Sensitive Joplin data is being dynamically injected into an external URL attribute (like
<img src="https://...") in a Webview. This can be used to silently exfiltrate sensitive data such as user notes or tokens to an attacker's server without requiring a direct network fetch.
Detects webview HTML that directly references remote external resources. It is a structural rule for literal or embedded HTML passed to Joplin webviews.
setHtml()receives HTML containing externalscriptoriframesrcURLs.setHtml()receives HTML containing externallinkhrefURLs.setHtml()receives HTML containing external meta refresh URLs.setHtml()receives HTML containing external CSSurl(...)references.
- Remote Webview Resource: The plugin directly embeds an external URL in a Webview (via iframe, script, link, meta refresh, or CSS). Confirm the URL points to a trusted, known-good domain.
Detects sensitive Joplin data being hidden in sync metadata or executed after retrieval.
It models abuse of userDataSet() and userDataGet() as an intra-API smuggling channel.
joplin.data.get()fornotes,folders,resources, ormaster_keysflows into the value argument ofjoplin.data.userDataSet(ModelType, itemId, key, value).- Data copied into
userDataSet()is reported when its target model type and item ID do not match the source item. joplin.data.userDataGet()flows into command execution.joplin.data.userDataGet()flows intoeval,Function,setTimeout, orsetInterval.
- Cross-item Sync Smuggling Indicator: Sensitive Joplin item data is being copied into another item's synchronized
userDataSetmetadata. Verify that this cross-item hidden storage is intentional and appropriate. - Sync Smuggling Execution: Hidden
userDataSetcontent is being read out of the database and flowing directly into an execution sink. It indicates the plugin is reading payloads that were smuggled into the sync engine and executing them, serving as a stealthy Remote Code Execution (RCE).
Detects Joplin dialogs or panels containing credential-entry controls whose submitted data leaves over the network. It tracks form or message data from phishing-like UI into network sinks.
- Dialog HTML containing password inputs or credential-labelled form controls is opened and its result flows into network request data or URLs.
- Panel HTML containing password inputs or credential-labelled form controls is paired with
onMessage()and submitted data flows into network request data or URLs. - The rule follows awaited dialog results and
.formDataproperty reads. - Provider or feature names such as GitHub, Dropbox, OneDrive, WebDAV, or sync do not make ordinary UI credential-looking by themselves.
- UI Phishing Indicator: Data submitted through a credential-looking Joplin dialog or panel is being transmitted to an external network. Review the HTML and confirm that the interface and destination are legitimate.
Detects high-volume Joplin data creation or disk writes inside loops. It focuses on resource exhaustion through unbounded or repeated work.
joplin.data.post()to the exacttags,notes,resources, orfolderscollection route, or the exact tag-note link route, appears inside an unbounded loop or recurring timer.- Filesystem write, append, or output-file calls through Node
fs, promise-basedfs,fs-extra, orjoplin.require('fs-extra')appear inside an unbounded loop or recurring timer. - String payloads larger than 10,000 characters or buffers larger than 10,000 bytes are written to disk inside any loop.
- Operations reached through helpers called by the loop or timer are included; ordinary finite creation loops and cleared intervals are not treated as unbounded flooding.
- Resource Exhaustion: The plugin is creating tags, notes, resources, folders, or tag-note links from an unbounded or background loop. Ensure loops have finite execution limits.
- Disk Quota Exhaustion: The plugin is writing to the filesystem inside an unbounded or infinite loop. This will rapidly exhaust disk space. Ensure loops have finite execution limits.
- Disk Quota Exhaustion: The plugin is writing large chunks of data to the filesystem inside a loop. Verify this is intended user-initiated behavior and won't overwhelm local storage.
Detects note mutation performed directly inside Joplin workspace event hooks. It is a structural rule for silent note changes triggered by user activity.
joplin.data.put(["notes", noteId], ..., { body: "static replacement" })appears inside note selection, note change, note content change, or alarm trigger callbacks.- A note update sets an active
deleted_timeoris_conflictvalue inside those callbacks. joplin.data.delete(["notes", noteId])appears inside those workspace callbacks.joplin.commands.execute("insertText", ...)orreplaceSelectionappears inside those workspace callbacks.- Mutations reached through helpers actually called by the workspace callback are included; nested helpers that are declared but never invoked are excluded.
- Computed note bodies, inactive destructive values, note sub-routes, and mutations outside these workspace callbacks are not reported.
- The plugin is mutating or deleting notes directly inside a workspace event hook (e.g.,
onNoteSelectionChange). Modifying a note the exact moment a user views or edits it can mimic "gaslighting" malware. Ensure these modifications are expected, visible formatting changes, not destructive silent edits.
Detects direct access to Electron remote APIs. It flags imports or member access that can expose privileged main-process capabilities when remote access is available.
- Code imports
@electron/remoteor one of its package subpaths, such as@electron/remote/mainor@electron/remote/renderer. - Code accesses
electron.remote. - ES module imports, CommonJS requires, destructuring, namespace variables, and constant property access are covered by CodeQL's module model.
- Critical Violation (Electron Remote Access): The plugin imports or accesses
@electron/remoteorelectron.remote. If remote access is available, it can bypass Joplin's normal plugin API boundary and expose privileged Electron main-process capabilities. This unsupported access must be removed before publishing.
Detects runtime member access on the native Electron module. It flags Electron APIs that bypass the Joplin plugin API surface.
- Code accesses a runtime member from
electron,electron/main,electron/renderer,electron/common, or theirnode:variants. - Specifically classified APIs include windows, dialogs, application paths, clipboard, shell, IPC, display, session, networking, protocol, global shortcuts, desktop capture, safe storage, and utility processes.
- Other runtime Electron properties receive one generic manual-review finding; the import itself does not produce a duplicate finding.
- Type-only imports are excluded, and
electron.remoteis handled exclusively by Rule 16.
- Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Use Joplin panels or dialogs instead of creating native Electron windows.
- Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Use
joplin.views.dialogsinstead ofelectron.dialog. - Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Use supported Joplin APIs such as
joplin.plugins.dataDir()instead of Electron application paths. - Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Use the
joplin.clipboardAPI instead ofelectron.clipboard. - Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Use Joplin's supported link handling instead of
electron.shell. - Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Direct Electron IPC bypasses Joplin's plugin messaging boundary.
- Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Direct display enumeration through
electron.screenis outside the Joplin plugin API. - Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. This Electron networking or web-session API can bypass Joplin's managed application boundary.
- Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. This Electron API can monitor global input or capture desktop content outside Joplin.
- Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. This Electron API exposes privileged native storage or process capabilities outside the Joplin plugin API.
- Unauthorized Native API Usage: The plugin accesses the runtime Electron API directly. Raw
electron.<property>access is unsupported and must be reviewed for an equivalent Joplin API.
Detects remote or webview-controlled archive input being saved or passed to extraction. It focuses on whether the archive source is trusted; Rule 17b exclusively validates the extraction destination.
- Remote request data flows into a file that is later passed to
joplin.fs.archiveExtract(). - Joplin webview message data flows into a file that is later passed to
joplin.fs.archiveExtract(). - Remote or message-controlled data flows directly into the archive path argument of
archiveExtract(). - File writes through Node
fs, promise-basedfs,fs-extra, orjoplin.require('fs-extra')are covered, including common stream and pipeline downloads. - Merely passing data into
hash.update()does not make the archive trusted; authenticity requires comparison with a trusted expected hash or verification of a digital signature. - Trusted local archive paths with no remote or webview-controlled flow are not reported.
- Untrusted Archive Extraction: An archive obtained from a remote or webview-controlled source is being extracted. Confirm its origin and verify it against a trusted expected hash or digital signature before extraction. Destination safety is reviewed separately by the archive-destination rule.
Detects archive extraction destinations derived from unsafe path sources. It exclusively owns archive destination validation for paths outside the plugin data directory.
process.env,process.argv,__dirname,__filename,joplin.plugins.installationDir(),process.cwd(),os.homedir(),os.tmpdir(), plugin settings, or Electron application paths flow into the destination argument ofjoplin.fs.archiveExtract().- Hardcoded absolute paths, working-directory-relative paths, Windows drive or UNC paths, and parent-directory traversal flow into the extraction destination.
- Remote or Joplin webview-controlled input flows into the extraction destination.
joplin.plugins.dataDir()and paths formed from it using only fixed child segments are accepted.- Applying
path.dirname()or parent traversal todataDir()is reported because it escapes the plugin's storage boundary. - The query reports one result per unsafe destination rather than one result for every contributing path fragment.
- Unsafe Extraction Destination: The archive destination is outside
joplin.plugins.dataDir(), escapes it through parent traversal, or is controlled by an untrusted source. UsedataDir()with fixed child path segments and reject destinations that can escape that directory.
Detects destructive Joplin data operations that can wipe or corrupt many records. It is a structural rule for folder deletion, repeated deletion, and repeated destructive updates.
- Any exact folder-item deletion through
joplin.data.delete(["folders", folderId])is reported because deleting a folder cascades to its notes. - Any
joplin.data.delete()reached directly or through a helper from an unbounded loop, uncleared interval, or recursive timeout is reported. joplin.data.put()reached from a loop, recurring timer, or array iteration callback is reported when the payload sets an activedeleted_time, setsis_conflict, or replacesbodywith an empty string.- Explicit inactive values such as
deleted_time: 0,is_conflict: false,null, orundefinedare excluded. - Merely opening a confirmation dialog does not suppress the finding; the reviewer must verify that the destructive action is correctly guarded by the user's response.
- Mass Data Destruction: The plugin is deleting an entire folder (which cascades to all its notes). This can permanently destroy the user's database. Verify this is a legitimate bulk-management feature explicitly initiated by the user.
- Mass Data Destruction: The plugin is looping unboundedly to delete many items at once. This can permanently destroy the user's database. Verify this is a legitimate bulk-management feature explicitly initiated by the user. If a loop is used, ensure it is bounded by finite, safe limits and not attacker-controlled.
- Mass Data Destruction: The plugin is looping to soft-delete, wipe bodies, or flag conflicts on many items at once. This can effectively destroy the user's database. Verify this is a legitimate bulk-management feature explicitly initiated by the user. If a loop is used, ensure it is bounded by finite, safe limits and not attacker-controlled.
Detects live keyboard, input, or Joplin activity data that is sent over the network. It tracks sensitive event parameters and Joplin data reads performed by event callbacks or invoked helpers.
- Keyboard and text-input event parameters from
keydown,keyup,keypress,beforeinput,input, orpastelisteners flow into network request data or URLs. - Sensitive parameters from workspace activity hooks,
settings.onChange,filters.on,editors.onUpdate, or editoronActivationCheckflow into network request data or URLs. selectedNote(),selectedNoteIds(),selectedFolder(), orselectedNoteHash()reads inside monitored callbacks flow into network request data or URLs.joplin.data.get()orjoplin.data.search()reads performed directly or through an invoked helper from monitored callbacks flow into network request data or URLs.- Non-sensitive parameters from
onSyncCompleteand editoronSetupare excluded, although sensitive Joplin reads performed by those callbacks remain covered. - Generic UI messages and uncalled nested helpers are excluded from surveillance tracking.
- Silent Surveillance / Keylogging: Live keyboard, input, Joplin activity, or data captured during an event is flowing to a network request. Verify that this collection and transmission is explicitly disclosed and authorized by the user.
Detects imported file paths or contents flowing from a custom import module into dangerous sinks.
It tracks data originating from the real sourcePath provided to registerImportModule().onExec().
- The
onExeccontext'ssourcePathflows directly into network requests, terminal commands, or unsafe filesystem operations. - Imported contents read through supported Node
fs, promise-basedfs,fs-extra, orjoplin.require('fs-extra')APIs flow into those sinks. - Synchronous, promise, callback, JSON, and common read-stream forms are covered.
- Inline objects, locally defined objects, factory-returned objects, and class instances registered as import modules are covered.
- Writing or copying imported data under
joplin.plugins.dataDir()is allowed; writes outside it and moves or renames of the original import source are reported. - Import options, warnings, unrelated functions named
readFile, and legitimate creation of Joplin records are not treated as imported file contents.
- Malicious Import Processing: An imported file path or its contents are flowing into a network request, terminal command, source-file mutation, or filesystem destination outside
joplin.plugins.dataDir(). Verify that the import remains local and only creates expected Joplin data or files inside the plugin data directory.