Claude-Obsidian URL Safety Validation Rules: How the Tool Validates URLs Before Capture
Claude-Obsidian validates every URL before capture to prevent credential leaks, block unsafe schemes like javascript:, and reject private network addresses, aborting the operation with a URLSafetyIssue if any check fails.
The URL safety validation rules in Claude-Obsidian ensure that only clean, secure links enter your knowledge vault. These rules are enforced by the url_safety.py module and are automatically invoked during the capture workflow via claude_obsidian/capture.py and claude_obsidian/ledgers.py to protect against accidental secret exposure and malicious content injection.
The Three Core Validation Layers
The validation logic in claude_obsidian/url_safety.py performs three distinct security checks before allowing a URL to be captured. If any check fails, the system raises a URLSafetyIssue exception and aborts the capture process.
Credential Detection in the Netloc Component
The parser examines the netloc component of the URL for embedded user-info strings (e.g., username:password@host). The function url_credential_issue specifically checks for this pattern and returns a URLSafetyIssue describing the leak when credentials are detected. This prevents secret keys, API tokens, or passwords from being stored in your Obsidian vault.
Unsafe Scheme Filtering
Only a whitelist of safe URL schemes is permitted. Safe schemes include http, https, ftp, and ftps. Schemes such as javascript:, data:, or custom protocols are flagged as unsafe because they can execute arbitrary code or embed malicious payloads. Any URL using a non-approved scheme is rejected immediately by the validator.
Private Network and Loopback Protection
URLs that resolve to private IP ranges or localhost are blocked unless explicitly allowed. This includes addresses in the 127.0.0.1 loopback range, 10.*.*.* private networks, and 192.168.*.* local subnets. This guardrail prevents accidental capture of internal services that should not be part of a public knowledge base.
Implementation Across the Codebase
The safety validation is integrated into multiple entry points across the repository:
claude_obsidian/capture.py– The central capture routine calls the safety validator before storing any link, ensuring no unsafe URLs reach the vault.claude_obsidian/ledgers.py– Records provenance and links to evidence, invoking URL safety checks to maintain integrity of the knowledge graph.claude_obsidian/cli.py– Provides the command-line interface (claude-obsidian capture …) that triggers the validation pipeline before any write operations.tests/test_capture.py– Contains the test suite verifying that the URL safety rules correctly reject credentials, unsafe schemes, and private IPs.
Practical Code Example
Here is how the validation logic can be implemented using the Claude-Obsidian safety utilities:
from claude_obsidian.url_safety import url_credential_issue
from urllib.parse import urlparse
def is_url_safe(url: str) -> bool:
parsed = urlparse(url)
# Reject if credentials are embedded
if url_credential_issue(parsed):
return False
# Reject unsafe schemes
if parsed.scheme not in {"http", "https", "ftp", "ftps"}:
return False
# Reject private network addresses
host = parsed.hostname or ""
if host.startswith("127.") or host.startswith("10.") or host.startswith("192.168."):
return False
return True
# Example usage:
print(is_url_safe("https://example.com/resource")) # → True
print(is_url_safe("https://user:pass@example.com")) # → False (credential leak)
print(is_url_safe("http://192.168.1.5/internal")) # → False (private IP)
print(is_url_safe("javascript:alert(1)")) # → False (unsafe scheme)
Summary
- Credential Detection in
claude_obsidian/url_safety.pyrejects URLs containinguser:pass@hostpatterns via theurl_credential_issuefunction. - Scheme Filtering permits only
http,https,ftp, andftps, blocking executable protocols likejavascript:anddata:. - Network Protection prevents capture of private IPs (
127.x.x.x,10.x.x.x,192.168.x.x) and internal services. - Error Handling raises
URLSafetyIssueto abort capture and surface clear error messages when validation fails. - The validation is invoked by
capture.py,ledgers.py, andcli.pyto ensure comprehensive protection across all entry points.
Frequently Asked Questions
What happens if a URL contains embedded credentials?
If url_credential_issue detects a username and password in the netloc component (e.g., https://token:secret@api.example.com), it returns a URLSafetyIssue describing the credential leak. The capture process aborts immediately, and the user receives an error message instructing them to remove the sensitive information from the URL before retrying.
Why does Claude-Obsidian block private IP addresses?
Private IP ranges—including 127.0.0.1, 10.x.x.x, and 192.168.x.x—are blocked to prevent accidental documentation of internal services, development endpoints, or local network resources that should remain isolated from a shared knowledge vault. This guardrail ensures that captured content refers to stable, publicly resolvable resources unless explicitly configured otherwise.
Which URL schemes are considered safe in Claude-Obsidian?
The validator explicitly permits http, https, ftp, and ftps. Schemes such as javascript:, data:, file:, or custom application protocols are rejected because they can execute code, embed arbitrary binary data, or access the local filesystem. This restriction in claude_obsidian/url_safety.py prevents injection attacks and ensures link portability.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →