Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ You can also override or add rules:

| Name                                          | Description | 💼 | ⚠️ | 🚫 | 🔧 | 💡 |
| :----------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | :----- | :----- | :----- | :- | :- |
| [behavior/clipboard-access](docs/rules/behavior/clipboard-access.md) | Detect access to the system clipboard. | | | ✅ 🇬🇧 | | |
| [behavior/no-electron-ipc](docs/rules/behavior/no-electron-ipc.md) | Detect usage of Electron IPC for privileged inter-process communication. | | | ✅ 🇬🇧 | | |
| [behavior/no-filesystem-access](docs/rules/behavior/no-filesystem-access.md) | Detect usage of the Node.js fs module for direct filesystem access outside the Obsidian vault API. | | | ✅ 🇬🇧 | | |
| [behavior/no-hardware-fingerprinting](docs/rules/behavior/no-hardware-fingerprinting.md) | Detect usage of hardware fingerprinting libraries like node-machine-id. | | | ✅ 🇬🇧 | | |
| [behavior/no-local-storage](docs/rules/behavior/no-local-storage.md) | Detect usage of localStorage or sessionStorage instead of the Obsidian plugin data APIs. | | | ✅ 🇬🇧 | | |
| [behavior/no-periodic-network](docs/rules/behavior/no-periodic-network.md) | Detect periodic network calls via setInterval combined with fetch or requestUrl. | | | ✅ 🇬🇧 | | |
| [behavior/no-self-disable-enable](docs/rules/behavior/no-self-disable-enable.md) | Detect plugins that programmatically disable and re-enable themselves. | | | ✅ 🇬🇧 | | |
| [behavior/no-self-update](docs/rules/behavior/no-self-update.md) | Detect plugins that appear to overwrite their own files by extracting an archive. | | | ✅ 🇬🇧 | | |
| [behavior/no-shell-execution](docs/rules/behavior/no-shell-execution.md) | Detect usage of child_process for shell command execution. | | | ✅ 🇬🇧 | | |
| [behavior/no-system-identity](docs/rules/behavior/no-system-identity.md) | Detect reads of system identity information that could be used for fingerprinting. | | | ✅ 🇬🇧 | | |
| [behavior/vault-enumeration](docs/rules/behavior/vault-enumeration.md) | Detect enumeration of all files in the vault. | | | ✅ 🇬🇧 | | |
| [behavior/vault-read](docs/rules/behavior/vault-read.md) | Detect reads of individual vault files via the Obsidian API. | | | ✅ 🇬🇧 | | |
| [behavior/vault-write](docs/rules/behavior/vault-write.md) | Detect writes or modifications to vault files via the Obsidian API. | | | ✅ 🇬🇧 | | |
| [commands/no-command-in-command-id](docs/rules/commands/no-command-in-command-id.md) | Disallow using the word 'command' in a command ID. | | ✅ 🇬🇧 | | | |
| [commands/no-command-in-command-name](docs/rules/commands/no-command-in-command-name.md) | Disallow using the word 'command' in a command name. | | ✅ 🇬🇧 | | | |
| [commands/no-default-hotkeys](docs/rules/commands/no-default-hotkeys.md) | Discourage providing default hotkeys for commands. | | ✅ 🇬🇧 | | | |
Expand Down
33 changes: 33 additions & 0 deletions docs/rules/behavior/clipboard-access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# obsidianmd/behavior/clipboard-access

📝 Detect access to the system clipboard.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects access to the system clipboard via `navigator.clipboard`, `electron.clipboard`, or `remote.clipboard`. Clipboard access may expose content copied from outside Obsidian.

## Examples

### Invalid

```js
navigator.clipboard.writeText('text');

navigator.clipboard.readText();

electron.clipboard.readText();

remote.clipboard.writeText('text');
```

### Valid

```js
navigator.userAgent;

const clipboard = new MyClipboard();
```
31 changes: 31 additions & 0 deletions docs/rules/behavior/no-electron-ipc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# obsidianmd/behavior/no-electron-ipc

📝 Detect usage of Electron IPC for privileged inter-process communication.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects usage of Electron's IPC modules (`ipcRenderer`, `ipcMain`), which allow privileged inter-process communication outside the normal plugin sandbox.

## Examples

### Invalid

```js
import { ipcRenderer } from 'electron';

import { ipcMain } from 'electron';

electron.ipcRenderer.send('test');
```

### Valid

```js
import { Plugin } from 'obsidian';

const renderer = new Renderer();
```
38 changes: 38 additions & 0 deletions docs/rules/behavior/no-filesystem-access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# obsidianmd/behavior/no-filesystem-access

📝 Detect usage of the Node.js fs module for direct filesystem access outside the Obsidian vault API.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects imports of Node.js `fs`, `node:fs`, `fs/promises`, and `node:fs/promises` modules. Unlike `no-nodejs-modules`, this rule does not respect `Platform.isDesktop` guards — it always reports, since its purpose is behavior classification rather than platform safety.

## Examples

### Invalid

```js
import fs from 'fs';

import { readFile } from 'fs/promises';

const fs = require('fs');

const fs = await import('fs');

// Still reported even with a platform guard
if (Platform.isDesktop) { const fs = await import('fs'); }
```

### Valid

```js
import { Plugin } from 'obsidian';

import path from 'path';

const data = vault.read('test.md');
```
33 changes: 33 additions & 0 deletions docs/rules/behavior/no-hardware-fingerprinting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# obsidianmd/behavior/no-hardware-fingerprinting

📝 Detect usage of hardware fingerprinting libraries like node-machine-id.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects usage of the `node-machine-id` library and its exported functions (`machineId`, `machineIdSync`), which collect unique hardware identifiers that can be used to fingerprint the user's machine.

## Examples

### Invalid

```js
import { machineIdSync } from 'node-machine-id';

const id = require('node-machine-id');

const id = machineIdSync();

const mod = await import('node-machine-id');
```

### Valid

```js
import { Plugin } from 'obsidian';

const id = generateId();
```
33 changes: 33 additions & 0 deletions docs/rules/behavior/no-local-storage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# obsidianmd/behavior/no-local-storage

📝 Detect usage of localStorage or sessionStorage instead of the Obsidian plugin data APIs.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects usage of `localStorage` and `sessionStorage` for data persistence. Obsidian plugins should use the plugin data APIs (`loadData`/`saveData`) instead.

## Examples

### Invalid

```js
localStorage.setItem('key', 'value');

localStorage.getItem('key');

sessionStorage.setItem('key', 'value');

window.localStorage.setItem('key', 'value');
```

### Valid

```js
this.plugin.loadData();

localStorage.length;
```
35 changes: 35 additions & 0 deletions docs/rules/behavior/no-periodic-network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# obsidianmd/behavior/no-periodic-network

📝 Detect periodic network calls via setInterval combined with fetch or requestUrl.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects when `setInterval` is combined with network calls (`fetch` or `requestUrl`) inside the callback. This pattern may indicate periodic background data transmission.

Note: Named function references passed to `setInterval` are not resolved — this is a documented limitation.

## Examples

### Invalid

```js
setInterval(() => { fetch('/api'); }, 60000);

setInterval(function() { requestUrl({ url: '/api' }); }, 60000);

window.setInterval(() => { fetch('/api'); }, 60000);
```

### Valid

```js
setInterval(() => { console.log('tick'); }, 1000);

fetch('/api/data');

setInterval(pollServer, 1000);
```
30 changes: 30 additions & 0 deletions docs/rules/behavior/no-self-disable-enable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# obsidianmd/behavior/no-self-disable-enable

📝 Detect plugins that programmatically disable and re-enable themselves.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects when a plugin calls both `disablePlugin` and `enablePlugin` in the same file. This pattern is a known technique for executing newly downloaded code without user awareness by restarting the plugin after modifying its own files.

## Examples

### Invalid

```js
app.plugins.disablePlugin(this.manifest.id);
app.plugins.enablePlugin(this.manifest.id);
```

### Valid

```js
// Only disabling is fine
app.plugins.disablePlugin(this.manifest.id);

// Only enabling is fine
app.plugins.enablePlugin('some-id');
```
35 changes: 35 additions & 0 deletions docs/rules/behavior/no-self-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# obsidianmd/behavior/no-self-update

📝 Detect plugins that appear to overwrite their own files by extracting an archive.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule flags plugins that combine references to plugin files (`main.js`, `manifest.json`, `styles.css`), file-write operations, and zip/archive libraries. This combination indicates a self-update mechanism that bypasses Obsidian's official plugin update process.

## Examples

### Invalid

```js
import AdmZip from 'adm-zip';

const f = "main.js";
writeFileSync(f, data);
```

### Valid

```js
// Only referencing a file name is fine
const f = "main.js";

// Only writing files is fine
writeFileSync(path, data);

// Only importing a zip library is fine
import AdmZip from 'adm-zip';
```
40 changes: 40 additions & 0 deletions docs/rules/behavior/no-shell-execution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# obsidianmd/behavior/no-shell-execution

📝 Detect usage of child_process for shell command execution.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects imports of `child_process` and `node:child_process`, as well as standalone calls to `execSync()` and `spawnSync()`. Unlike `no-nodejs-modules`, this rule does not respect `Platform.isDesktop` guards — it always reports, since its purpose is behavior classification rather than platform safety.

## Examples

### Invalid

```js
import { exec } from 'child_process';

const cp = require('child_process');

const cp = await import('child_process');

execSync('ls');

spawnSync('ls');

// Still reported even with a platform guard
if (Platform.isDesktop) { const cp = await import('child_process'); }
```

### Valid

```js
import { Plugin } from 'obsidian';

const result = someFunction();

exec('command');
```
35 changes: 35 additions & 0 deletions docs/rules/behavior/no-system-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# obsidianmd/behavior/no-system-identity

📝 Detect reads of system identity information that could be used for fingerprinting.

🚫 This rule is _disabled_ in the following configs: ✅ `recommended`, 🇬🇧 `recommendedWithLocalesEn`.

<!-- end auto-generated rule header -->

## Rule details

This rule detects reads of system identity information such as `os.hostname()`, `os.userInfo()`, `os.networkInterfaces()`, and identity-related environment variables (`process.env.HOME`, `process.env.USERNAME`, `process.env.USER`, `process.env.USERPROFILE`).

## Examples

### Invalid

```js
const name = os.hostname();

const info = os.userInfo();

const ifaces = os.networkInterfaces();

const home = process.env.HOME;

const user = process.env.USERNAME;
```

### Valid

```js
const cpus = os.cpus();

const env = process.env.NODE_ENV;
```
Loading
Loading