Files
OpenJarvis/tests/security/test_ssrf.py
T
Jon Saad-FalconandClaude Opus 4.6 a4c4081ff4 Add desktop distribution pipeline: rolling releases, auto-updates, code signing
- Rewrite .github/workflows/desktop.yml: 2-job pipeline (validate + build-and-release)
  with rolling desktop-latest pre-release on push to main and stable desktop-v* releases
- Add UpdateChecker component: checks for updates on startup + every 30 min,
  background download with progress bar, one-click relaunch
- Configure Tauri updater: endpoints pointing to desktop-latest release, pubkey placeholder
- Add tauri-plugin-process for relaunch support (Cargo.toml, lib.rs, package.json)
- Add macOS Entitlements.plist for notarization (network + file access, no sandbox)
- Add scripts/bump-desktop-version.sh for atomic version bumps across 3 config files
- Add desktop/README.md with dev setup, auto-update architecture, signing docs
- Update .gitignore for desktop/node_modules, dist, target
- Configure macOS minimumSystemVersion, Windows timestampUrl
- Include all Phase 14-21 work: agent hardening, RBAC, taint tracking, workflows,
  skills, knowledge graph, sessions, A2A, MCP templates, WASM sandbox, TUI dashboard,
  production tools, CLI expansion, API expansion, learning productionization,
  Tauri desktop app, and 10 new channels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:14:05 +00:00

116 lines
4.0 KiB
Python

"""Tests for SSRF protection module."""
from __future__ import annotations
from unittest.mock import patch
from openjarvis.security.ssrf import check_ssrf, is_private_ip
class TestIsPrivateIp:
def test_private_10_network(self):
assert is_private_ip("10.0.0.1") is True
assert is_private_ip("10.255.255.255") is True
def test_private_172_16_network(self):
assert is_private_ip("172.16.0.1") is True
assert is_private_ip("172.31.255.255") is True
def test_private_192_168_network(self):
assert is_private_ip("192.168.0.1") is True
assert is_private_ip("192.168.1.100") is True
def test_loopback(self):
assert is_private_ip("127.0.0.1") is True
assert is_private_ip("127.255.255.255") is True
def test_ipv6_loopback(self):
assert is_private_ip("::1") is True
def test_link_local(self):
assert is_private_ip("169.254.0.1") is True
def test_public_ips(self):
assert is_private_ip("8.8.8.8") is False
assert is_private_ip("1.1.1.1") is False
assert is_private_ip("93.184.216.34") is False
def test_invalid_ip(self):
assert is_private_ip("not-an-ip") is False
def test_empty_string(self):
assert is_private_ip("") is False
class TestCheckSsrf:
def test_blocks_aws_metadata(self):
result = check_ssrf("http://169.254.169.254/latest/meta-data/")
assert result is not None
assert "cloud metadata" in result.lower() or "Blocked host" in result
def test_blocks_google_metadata(self):
result = check_ssrf("http://metadata.google.internal/computeMetadata/v1/")
assert result is not None
assert "Blocked host" in result
def test_blocks_alibaba_metadata(self):
result = check_ssrf("http://100.100.100.200/latest/meta-data/")
assert result is not None
assert "Blocked host" in result
def test_allows_normal_urls(self):
# Mock DNS resolution to return a public IP
with patch("openjarvis.security.ssrf.socket.getaddrinfo") as mock_dns:
mock_dns.return_value = [
(2, 1, 6, "", ("93.184.216.34", 0)),
]
result = check_ssrf("https://example.com")
assert result is None
def test_blocks_localhost_url(self):
with patch("openjarvis.security.ssrf.socket.getaddrinfo") as mock_dns:
mock_dns.return_value = [
(2, 1, 6, "", ("127.0.0.1", 0)),
]
result = check_ssrf("http://localhost:8080/admin")
assert result is not None
assert "private IP" in result
def test_blocks_private_ip_url(self):
with patch("openjarvis.security.ssrf.socket.getaddrinfo") as mock_dns:
mock_dns.return_value = [
(2, 1, 6, "", ("192.168.1.1", 0)),
]
result = check_ssrf("http://internal-service.local/api")
assert result is not None
assert "private IP" in result
def test_no_hostname(self):
result = check_ssrf("not-a-url")
assert result is not None
assert "No hostname" in result
def test_dns_failure_allowed(self):
"""DNS resolution failure should not block — request will fail at HTTP time."""
import socket
with patch(
"openjarvis.security.ssrf.socket.getaddrinfo",
side_effect=socket.gaierror("Name resolution failed"),
):
result = check_ssrf("https://nonexistent.example.com")
assert result is None
def test_blocks_dns_rebinding_to_private(self):
"""Even if hostname looks normal, block if it resolves to private IP."""
with patch("openjarvis.security.ssrf.socket.getaddrinfo") as mock_dns:
mock_dns.return_value = [
(2, 1, 6, "", ("10.0.0.5", 0)),
]
result = check_ssrf("https://evil-rebind.example.com")
assert result is not None
assert "private IP" in result
__all__ = ["TestCheckSsrf", "TestIsPrivateIp"]