Back to skill

Security audit

Foam Notes

Security checks for vulnerabilities and agentic risk

Overview

This Foam notes skill is mostly coherent, but review is needed because several scripts can modify, rename, or delete files outside the intended Foam workspace.

Install only if you are comfortable with local scripts editing your notes. Set the Foam root explicitly, keep backups, avoid --force and --auto-apply, and do not use this version on untrusted note names or paths until workspace-containment checks are fixed.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (6)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/create_note.py:176
Finding

Workspace Escape Allows Arbitrary Markdown File Creation

Content
View full analysis

Vulnerability Details

File Location: scripts/create_note.py, lines 176–183 and 277–278
Vulnerability Type: Path traversal and missing workspace containment validation
Risk Level: Medium

Vulnerable Code

python
# Determine output directory
if output_dir is None:
    output_dir = foam_root
elif not output_dir.is_absolute():
    output_dir = foam_root / output_dir

output_dir.mkdir(parents=True, exist_ok=True)

# Generate filename
slug = slugify(title)
date_str = datetime.now().strftime("%Y-%m-%d")
filename = f"{slug}.md"
filepath = output_dir / filename

# Check for existing file
counter = 1
original_filepath = filepath
while filepath.exists():
    filename = f"{slug}-{counter}.md"
    filepath = output_dir / filename
    counter += 1

# Write the file
filepath.write_text(content)
print(f"Created: {filepath.relative_to(foam_root)}")

Technical Analysis

The --dir argument is documented as relative to the Foam workspace, but the implementation accepts both absolute paths and relative paths containing ... Relative paths are joined to foam_root without normalization or a subsequent containment check. Absolute paths bypass the workspace join entirely.

The script creates the destination directory and writes the file before calling relative_to(foam_root). Consequently, the final display operation may raise an exception for an escaped path, but the external file has already been created.

The generated filename is constrained by slugify() and receives a .md extension. Existing files are not overwritten because a numeric suffix is selected. Nevertheless, an attacker can create Markdown files and parent directories at arbitrary writable locations.

Attack Path

  1. Identify a directory writable by the account executing the Skill.
  2. Invoke the script with an absolute or traversal-based output directory, for example:
    bash
    python3 scripts/create_n
    

...[truncated 729 chars]

Remediation
View remediation

Remediation Suggestions

  • Reject absolute values for --dir because the option is documented as workspace-relative.
  • Resolve both the workspace and destination before creating directories:
    python
    root = foam_root.resolve(strict=True)
    destination = (root / output_dir).resolve()
    if not destination.is_relative_to(root):
        raise ValueError("Output directory must remain inside the Foam workspace")
    
  • Repeat containment validation on the final file path immediately before writing.
  • Consider rejecting path components equal to .. for clearer user-facing validation.
  • Avoid following symlinks that lead outside the workspace. Validate the resolved destination after its parent exists.
  • Perform the validation before mkdir() so escaped directories are not created.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/daily_note.py:57
Finding

Unvalidated Daily Note Folder Allows Config-Driven Workspace Escape

Content
View full analysis

Vulnerability Details

File Location: scripts/daily_note.py, lines 57–67 and 133–136
Vulnerability Type: Absolute-path injection and path traversal through configuration
Risk Level: Medium

Vulnerable Code

python
def get_daily_note_path(
    foam_root: Path, date: datetime, daily_folder: str = "journals"
) -> Path:
    """Get the path for a daily note."""
    # Default: journals/yyyy-mm-dd.md or custom folder from config
    journals_dir = foam_root / daily_folder
    if not journals_dir.exists():
        journals_dir = foam_root  # Fallback to root

    filename = date.strftime("%Y-%m-%d") + ".md"
    return journals_dir / filename
python
# Ensure directory exists
filepath.parent.mkdir(parents=True, exist_ok=True)

# Write file
filepath.write_text(content)
return True

Technical Analysis

daily_folder originates from the daily_note_folder configuration setting and is joined directly to foam_root. With pathlib, joining an absolute right-hand path discards the left-hand path. A value containing .. may also resolve outside the workspace.

If an external absolute directory already exists, the existence check succeeds and the fallback to foam_root is not used. The script then writes a date-named Markdown file to that external directory. No resolved-path containment check is performed.

Attack Path

  1. Modify the Skill's config.json so daily_note_folder points to an existing external directory:
    json
    {
      "daily_note_folder": "/tmp/external-notes"
    }
    
  2. Ensure /tmp/external-notes exists.
  3. Invoke:
    bash
    python3 scripts/daily_note.py --foam-root /home/user/foam
    
  4. The absolute configured path supersedes foam_root.
  5. The script creates a file such as /tmp/external-notes/2026-09-10.md.

Impact Assessment

The operation runs with the privileges of the current user. It can create date- ...[truncated 257 chars]

Remediation
View remediation

Remediation Suggestions

  • Require daily_note_folder to be a relative path.
  • Reject absolute paths and any resolved path outside foam_root.
  • Resolve and validate the final daily-note path before checking existence or creating directories:
    python
    root = foam_root.resolve(strict=True)
    folder = Path(daily_folder)
    if folder.is_absolute():
        raise ValueError("daily_note_folder must be relative")
    
    filepath = (root / folder / filename).resolve()
    if not filepath.is_relative_to(root):
        raise ValueError("Daily note path escapes the Foam workspace")
    
  • Validate symlink-resolved parents to prevent a workspace symlink from redirecting writes externally.
  • Report invalid configuration instead of silently falling back to another directory.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/suggest_tags.py:442
Finding

Tag Suggestions Can Modify Arbitrary Files Outside the Workspace

Content
View full analysis

Vulnerability Details

File Location: scripts/suggest_tags.py, lines 346–394 and 442–449
Vulnerability Type: Unrestricted file path used for content modification
Risk Level: Medium

Vulnerable Code

python
def apply_tags(note_path: Path, tags_to_add: list, mode: str = "inline") -> bool:
    """Add tags to note."""
    if not tags_to_add:
        return False

    content = note_path.read_text()

    # Clean up tags (remove # if present)
    clean_tags = [t.lstrip("#") for t in tags_to_add]

    if mode == "frontmatter":
        # Add to frontmatter
        if content.startswith("---"):
            # Has frontmatter
            end = content.find("---", 3)
            if end > 0:
                # Check if tags field exists
                fm = content[3:end]
                if "tags:" in fm:
                    mode = "inline"
                else:
                    new_fm = fm.rstrip() + f"\ntags: [{', '.join(clean_tags)}]\n"
                    content = "---" + new_fm + content[end:]
        else:
            fm = f"---\ntags: [{', '.join(clean_tags)}]\n---\n\n"
            content = fm + content

    if mode == "inline":
        if content.startswith("---"):
            end = content.find("---", 3)
            if end > 0:
                insert_pos = end + 3
                if not content[insert_pos:].startswith("\n"):
                    insert_pos = content.find("\n", insert_pos) + 1
            else:
                insert_pos = 0
        else:
            insert_pos = 0

        tag_line = " ".join(f"#{t}" for t in clean_tags) + "\n\n"
        content = content[:insert_pos] + tag_line + content[insert_pos:]

    note_path.write_text(content)
    return True
python
# Resolve note path
note_path = Path(args.note)
if not note_path.is_absolute():
    note_path = foam_root / note_path

if not note_path.exists():
    print(f"Er
...[truncated 1793 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove support for absolute note paths unless external editing is an explicit, separately authorized feature.
  • Resolve the workspace and target, then require the target to be contained within the workspace.
  • Require note_path.is_file() and a .md suffix.
  • Validate the resolved path immediately before reading and again before writing to reduce symlink and race-condition exposure.
  • Write through a temporary file located in the same validated directory and use an atomic replacement only after successful processing.
  • Ensure status formatting occurs before mutation or safely handles external paths without masking a completed write.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/suggest_wikilinks.py:442
Finding

Wikilink Suggestions Can Rewrite Arbitrary Files Outside the Workspace

Content
View full analysis

Vulnerability Details

File Location: scripts/suggest_wikilinks.py, lines 354–390 and 442–449
Vulnerability Type: Unrestricted file modification and missing path containment
Risk Level: Medium

Vulnerable Code

python
def apply_wikilinks(
    note_path: Path, candidates: list, selections: list, with_aliases: bool = False
) -> bool:
    """Apply selected wikilinks to the note."""
    if not selections:
        return False

    content = note_path.read_text()
    lines = content.split("\n")

    to_apply = sorted(
        [(i, candidates[i - 1]) for i in selections if 1 <= i <= len(candidates)],
        key=lambda x: (-x[1]["line"], -x[1]["column"]),
    )

    for _, candidate in to_apply:
        line_idx = candidate["line"] - 1
        col_idx = candidate["column"] - 1
        text = candidate["text"]
        target = candidate["target"]

        line = lines[line_idx]
        before = line[:col_idx]
        after = line[col_idx + len(text) :]

        if with_aliases:
            lines[line_idx] = before + f"[[{target}|{text}]]" + after
        else:
            lines[line_idx] = before + f"[[{target}]]" + after

    # Write back
    note_path.write_text("\n".join(lines))
    return True
python
# Resolve note path
note_path = Path(args.note)
if not note_path.is_absolute():
    note_path = foam_root / note_path

if not note_path.exists():
    print(f"Error: Note not found: {note_path}", file=sys.stderr)
    sys.exit(1)

Technical Analysis

The target path can be absolute or can escape through ... The only gate is an existence check. There is no workspace-containment check, regular-file validation, extension validation, or symlink-target validation.

--auto-apply makes exploitation noninteractive: every generated candidate is inserted into the selected external file. The script writes the modified content before attempting to rend ...[truncated 947 chars]

Remediation
View remediation

Remediation Suggestions

  • Limit input to Markdown files contained in foam_root.
  • Resolve and compare paths before scanning or applying suggestions:
    python
    root = foam_root.resolve(strict=True)
    target = (root / args.note).resolve() if not Path(args.note).is_absolute() else Path(args.note).resolve()
    if not target.is_relative_to(root):
        raise ValueError("Note must be inside the Foam workspace")
    
  • Require a regular .md file and reject external symlink targets.
  • Revalidate immediately before write_text().
  • Keep --auto-apply disabled unless the validated target is unambiguously inside the workspace.
  • Consider atomic writes and backups for automated bulk modifications.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/delete_note.py:27
Finding

Path Traversal Allows Deletion of Markdown Files Outside the Workspace

Content
View full analysis

Vulnerability Details

File Location: scripts/delete_note.py, lines 27–34 and 175–179
Vulnerability Type: Path traversal leading to arbitrary file deletion
Risk Level: High

Vulnerable Code

python
def find_note(target: str, foam_root: Path) -> Path:
    """Find a note by name or filename."""
    target_stem = target.replace(".md", "")
    target_slug = slugify(target_stem)

    # Try exact match first
    exact_path = foam_root / f"{target_stem}.md"
    if exact_path.exists():
        return exact_path
python
# Delete or backup
if backup:
    backup_path = backup_note(note_path, foam_root)
    print(f"Backed up to: {backup_path.relative_to(foam_root)}")
else:
    note_path.unlink()

print(f"Deleted: {note_path.relative_to(foam_root)}")

Technical Analysis

target is treated as a note name, but path separators and .. components are not prohibited. The exact-path lookup directly appends the attacker-controlled value to foam_root. If an external Markdown file exists at the resulting traversal path, it is accepted as the note.

When --force is supplied, the confirmation block—which would call relative_to() and potentially fail for an external path—is skipped. The script reaches unlink() and permanently deletes the external file. The final display operation occurs only after deletion.

The attack is restricted to paths that become .md files because the function removes occurrences of .md and appends .md again. However, deletion of arbitrary writable Markdown files outside the workspace remains possible.

Attack Path

  1. Assume /home/user/victim.md exists and the Foam root is /home/user/foam.
  2. Invoke:
    bash
    python3 scripts/delete_note.py ../victim \
      --foam-root /home/user/foam \
      --force
    
  3. find_note() constructs /home/user/foam/../victim.md.
  4. Because the file exists, it is returned as the selected ...[truncated 631 chars]
Remediation
View remediation

Remediation Suggestions

  • Treat target strictly as a note name and reject /, \, absolute paths, . components, and .. components.
  • Resolve every candidate returned by find_note() and require it to remain under the resolved workspace.
  • Require the target to be a regular .md file and define an explicit policy for symlinks.
  • Perform containment validation immediately before unlink() or shutil.move(), not only during initial lookup.
  • Do not rely on relative_to() used for display as a security check.
  • Consider making backup deletion the default and requiring an explicit option for permanent deletion.
  • Add regression tests for ../victim, absolute paths, nested traversal, and external symlinks.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/rename_note.py:22
Finding

Path Traversal Allows Renaming Markdown Files Outside the Workspace

Content
View full analysis

Vulnerability Details

File Location: scripts/rename_note.py, lines 22–27 and 146–154
Vulnerability Type: Path traversal leading to unauthorized external file rename
Risk Level: High

Vulnerable Code

python
def find_note(target: str, foam_root: Path) -> Path:
    """Find a note by name or filename."""
    target_stem = target.replace(".md", "")

    # Try exact match first
    exact_path = foam_root / f"{target_stem}.md"
    if exact_path.exists():
        return exact_path
python
# Update wikilinks in other notes
if backlinks:
    count = update_wikilinks(old_stem, new_stem, foam_root, backlinks)
    print(f"Updated wikilinks in {count} note(s).")

# Rename the file
old_path.rename(new_path)
print(
    f"Renamed: {old_path.relative_to(foam_root)} → {new_path.relative_to(foam_root)}"
)

Technical Analysis

The old note name is concatenated directly with foam_root and may contain .. or path separators. An external Markdown file can therefore be selected as the source. The destination is constructed beside that source:

python
old_stem = old_path.stem
new_stem = slugify(new_name)
new_path = old_path.parent / f"{new_stem}.md"

With --force, pre-operation calls to relative_to(foam_root) are skipped. The external source file is renamed before the final display operation attempts relative-path conversion.

The new name is slugified, so the attacker cannot independently choose an arbitrary destination directory. Nevertheless, the attacker can rename a writable external Markdown file within its current directory, effectively removing its original path and disrupting unrelated projects.

Attack Path

  1. Assume /home/user/victim.md exists and the Foam root is /home/user/foam.
  2. Invoke:
    bash
    python3 scripts/rename_note.py ../victim displaced \
      --foam-root /home/user/foam \
      --force
    
  3. find_note() sele ...[truncated 621 chars]
Remediation
View remediation

Remediation Suggestions

  • Reject path separators, absolute paths, and traversal components in old_name.
  • Resolve old_path and require it to be under the resolved Foam root.
  • Resolve and validate both source and destination immediately before calling rename().
  • Require both paths to remain in the same authorized workspace.
  • Reject symlink sources or explicitly validate their resolved targets.
  • Preserve confirmation as a usability safeguard, but do not treat it as a replacement for path authorization.
  • Add tests covering --force with traversal, absolute source paths, external symlinks, and destination collisions.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code chunk is narrowly focused on note creation from templates within a Foam workspace. It does support part of the declared description: creating notes, daily notes, and templates. However, it does not implement editing, linking, tagging operations beyond inserting empty/default tags in frontmatter, intelligent wikilink or tag suggestions, backlinks discovery, graph visualization, deletion, renaming, or documentation querying. Because the declared purpose presents a much broader multifunction Foam skill than the code actually provides, the description does not accurately represent this chunk's behavior.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 40)May include surrounding context.

md
**Location**: `config.json` in the skill directory (next to `SKILL.md`).

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill documents capabilities that require reading environment variables and reading/writing workspace files, but it does not declare any explicit tool scope or permission boundaries. That creates an authorization ambiguity where an agent may exercise broader file or env access than a reviewer expects, increasing the chance of unintended workspace modification or disclosure of sensitive local data.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

The documented --force option allows destructive deletion to bypass confirmation, which is risky in an agentic context where commands may be constructed or invoked without sufficient human review. If used on the wrong target or workspace, it can cause immediate data loss or loss of important notes.

Content

Scanner excerpt · SKILL.md (reported line 208)May include surrounding context.

bash
python3 scripts/delete_note.py "Old Note"                    # Interactive deletion
python3 scripts/delete_note.py "Old Note" --force          # Skip confirmation
python3 scripts/delete_note.py "Old Note" --backup         # Move to .foam/trash/
python3 scripts/delete_note.py "Old Note" --fix-links      # Remove wikilinks from other notes

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Automatic backlink fixing during deletion modifies other notes without requiring per-change review, which can propagate unintended content changes across the workspace. In an agent setting, this increases the blast radius of a mistaken delete operation from one file to many files.

Content

Scanner excerpt · SKILL.md (reported line 216)May include surrounding context.

md
**Features:**
- **Backup mode**: Moves note to `.foam/trash/` instead of permanent deletion
- **Backlink detection**: Shows which notes link to the one being deleted
- **Link fixing**: Automatically removes wikilinks from other notes
- **Confirmation**: Prompts before deletion (skip with `--force`)

### rename_note.py

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

A forced rename that skips confirmation can automatically update many wikilinks and rename a file without human validation of the affected references. While less destructive than deletion, it can still corrupt note organization or introduce widespread link errors if the wrong note is targeted.

Content

Scanner excerpt · SKILL.md (reported line 225)May include surrounding context.

bash
python3 scripts/rename_note.py "Old Name" "New Name"       # Interactive rename
python3 scripts/rename_note.py "Old Name" "New Name" --force  # Skip confirmation

Features:

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/foam_config.py (reported line 87)May include surrounding context.

python
except (json.JSONDecodeError, IOError) as e:
            print(
                f"Warning: Could not load config.json: {e}",
                file=__import__("sys").stderr,
            )
            return default_config

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/foam_config.py (reported line 137)May include surrounding context.

python
except (json.JSONDecodeError, IOError) as e:
            print(
                f"Warning: Could not load config.json: {e}",
                file=__import__("sys").stderr,
            )
            return default_config

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/foam_config.py (reported line 103)May include surrounding context.

python
with open(config_path, "w") as f:
            json.dump(config, f, indent=2)
    except IOError as e:
        print(f"Error: Could not save config.json: {e}", file=__import__("sys").stderr)


def find_foam_root_auto(start_dir: Path = None) -> Path:

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/delete_note.py (reported line 12)May include surrounding context.

python
Examples:
    python3 rename_note.py "My Note" "My Better Note"     # Interactive rename
    python3 rename_note.py "My Note" "My Better Note" --force  # Skip confirmation
"""

import argparse

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/delete_note.py (reported line 198)May include surrounding context.

python
Examples:
    python3 rename_note.py "My Note" "My Better Note"     # Interactive rename
    python3 rename_note.py "My Note" "My Better Note" --force  # Skip confirmation
"""

import argparse

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/rename_note.py (reported line 11)May include surrounding context.

python
Examples:
    python3 rename_note.py "My Note" "My Better Note"     # Interactive rename
    python3 rename_note.py "My Note" "My Better Note" --force  # Skip confirmation
"""

import argparse

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · scripts/rename_note.py (reported line 166)May include surrounding context.

python
Examples:
    python3 rename_note.py "My Note" "My Better Note"     # Interactive rename
    python3 rename_note.py "My Note" "My Better Note" --force  # Skip confirmation
"""

import argparse

Tainted flow: 'content' from pathlib.Path.read_text (line 392, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/suggest_tags.py (reported line 394)May include surrounding context.

python
tag_line = " ".join(f"#{t}" for t in clean_tags) + "\n\n"
        content = content[:insert_pos] + tag_line + content[insert_pos:]

    note_path.write_text(content)
    return True

Tainted flow: 'lines' from pathlib.Path.read_text (line 362, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/suggest_wikilinks.py (reported line 390)May include surrounding context.

python
lines[line_idx] = before + f"[[{target}]]" + after

    # Write back
    note_path.write_text("\n".join(lines))
    return True

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The manifest describes working with Foam note repositories by creating, editing, linking, tagging, and suggesting links/tags. This file documents support for executable JavaScript templates that implement arbitrary logic for note creation, which is a broader programmable capability not clearly justified by the stated purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code file supports a non-interactive --apply mode that ultimately writes modified content back to the note file. Although the script reports changes after writing, it does not provide a user-facing warning at the point the auto-apply option is defined that using this flag will modify the note contents immediately.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.