Files
RouterOS/RouterOSAssistantTests/NetworkToolsServiceTests.swift
T
KayandClaude Sonnet 5 04325e3bbd M20: LAN-Scanner umbenannt + Netzwerk-Tools (Ping/Traceroute/DNS/Port-Scan)
Tab "Geräte" -> "LAN-Scanner", Refresh-Button "Neu scannen" + prominenter
Stil. Neues Netzwerk-Tools-Menü: Ping/Traceroute/DNS-Auflösung über
NetworkToolsService (eigene SSH-Verbindung, wie Backup/InterfaceTraffic-
Monitor), mit Zeichen-Validierung gegen Command-Injection ueber einen
boeswilligen DHCP-Hostnamen. Port-Scan laeuft direkt von diesem Mac ueber
Network.framework (RouterOS hat kein eingebautes Portscan-Tool) - dabei
einen echten NWConnection-Bug gefunden (verweigerte Verbindung meldet sich
ueber .waiting, nicht .failed) und per Unit-Test gegen einen Loopback-Port
aufgedeckt und gefixt.

Zusaetzlich: Warnhinweis bei "Feste IP zuweisen" erklaert jetzt den
Rueckweg. DE/EN-Umschalter zeigt Landesflaggen statt Text.

92 Tests gruen. HANDOFF.md/README.md (inkl. Mermaid-Diagramm)/Manual.md/
CHATLOG.md aktualisiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
2026-09-15 22:41:23 +02:00

35 lines
1.4 KiB
Swift

import XCTest
@testable import RouterOSAssistant
/// A LAN device's IP/hostname ultimately comes from its own DHCP request — attacker-controllable
/// by a rogue device on the network — and gets interpolated into a RouterOS console command
/// string for ping/traceroute/resolve. RouterOS' console treats ";" as a command separator, so an
/// unsanitized value could inject a second command; these tests lock in the allow-list that
/// prevents that.
final class NetworkToolsServiceTests: XCTestCase {
func testAcceptsValidIPv4Address() throws {
XCTAssertEqual(try NetworkToolsService.sanitized("192.168.88.10"), "192.168.88.10")
}
func testAcceptsValidIPv6Address() throws {
XCTAssertEqual(try NetworkToolsService.sanitized("fe80::1"), "fe80::1")
}
func testAcceptsValidHostname() throws {
XCTAssertEqual(try NetworkToolsService.sanitized("my-laptop.local"), "my-laptop.local")
}
func testRejectsCommandInjectionViaSemicolon() {
XCTAssertThrowsError(try NetworkToolsService.sanitized("8.8.8.8; /system reset-configuration"))
}
func testRejectsWhitespaceAndQuotes() {
XCTAssertThrowsError(try NetworkToolsService.sanitized("8.8.8.8 count=1000000"))
XCTAssertThrowsError(try NetworkToolsService.sanitized("\"; malicious"))
}
func testRejectsEmptyValue() {
XCTAssertThrowsError(try NetworkToolsService.sanitized(""))
}
}