Files
bal-server/tests/ssrf_tests.rs
svatantrya 4fc0790fe7 security: fix audit points 5-9 + optimize echo_push/info endpoints
- Point 5 (SSRF): Add URL validation for WELIST_SERVER_URL (src/validation.rs)
- Point 6 (DB Access): Add DB path validation, symlink check, WAL mode (open_db)
- Point 8 (HTTPS): Extract nginx config, add deployment checklist, bind warnings
- Point 9 (Input Validation): Add NETWORKS check (404 for unknown), txid 64-hex validation
- Optimize echo_push: parse transactions outside DB lock, batch duplicate check, N+1 xpub lookup eliminated via HashSet cache
- Optimize echo_info: derive BIP32 address outside DB lock, minimize lock duration
- Fix echo_stats SQL injection via parameter binding + add idx_stats_chain index
- New regression tests: ssrf_tests, db_path_validation, input_validation_tests
2026-07-16 18:59:30 -04:00

111 lines
2.9 KiB
Rust

use bal_server::validation::is_valid_welist_url;
#[test]
fn test_ssrf_blocks_internal_urls() {
// Blocked: internal loopback
assert!(
!is_valid_welist_url("https://127.0.0.1"),
"IPv4 loopback should be blocked"
);
assert!(
!is_valid_welist_url("https://localhost"),
"localhost hostname should be blocked"
);
assert!(
!is_valid_welist_url("https://[::1]"),
"IPv6 loopback should be blocked"
);
// Blocked: private RFC1918 ranges
assert!(
!is_valid_welist_url("https://192.168.1.1"),
"RFC1918 private IP should be blocked"
);
assert!(
!is_valid_welist_url("https://10.0.0.1"),
"RFC1918 private IP should be blocked"
);
assert!(
!is_valid_welist_url("https://172.16.0.1"),
"RFC1918 private IP should be blocked"
);
// Blocked: AWS metadata link-local
assert!(
!is_valid_welist_url("https://169.254.169.254"),
"AWS metadata link-local IP should be blocked"
);
// Blocked: non-HTTPS schemes
assert!(
!is_valid_welist_url("http://welist.bitcoin-after.life"),
"HTTP plaintext should be blocked"
);
assert!(
!is_valid_welist_url("ftp://welist.bitcoin-after.life"),
"FTP scheme should be blocked"
);
// Blocked: malformed URLs
assert!(
!is_valid_welist_url("not a url"),
"Malformed URL should be blocked"
);
assert!(
!is_valid_welist_url("welist.bitcoin-after.life"),
"URL missing scheme should be blocked"
);
// Allowed: valid public domain on HTTPS
assert!(
is_valid_welist_url("https://welist.bitcoin-after.life"),
"Known production domain should be allowed"
);
assert!(
is_valid_welist_url("https://example.com/ping"),
"Public domain on HTTPS should be allowed"
);
// Allowed: valid public IP on HTTPS
assert!(
is_valid_welist_url("https://8.8.8.8"),
"Public IP on HTTPS should be allowed"
);
assert!(
is_valid_welist_url("https://1.2.3.4"),
"Public IP on HTTPS should be allowed"
);
}
#[test]
fn test_ssrf_case_insensitive_localhost() {
assert!(
!is_valid_welist_url("https://LOCALHOST"),
"Uppercase localhost should be blocked"
);
assert!(
!is_valid_welist_url("https://LocalHost"),
"Mixed case localhost should be blocked"
);
}
#[test]
fn test_ssrf_ipv6_unique_local() {
assert!(
!is_valid_welist_url("https://[fc00::1]"),
"IPv6 unique local fc00 should be blocked"
);
assert!(
!is_valid_welist_url("https://[fd00::1]"),
"IPv6 unique local fd00 should be blocked"
);
}
#[test]
fn test_ssrf_port_presence_ok() {
assert!(
is_valid_welist_url("https://welist.bitcoin-after.life:443"),
"HTTPS with explicit port should be allowed"
);
}