{"record":{"id":"d6785f098a98b979","repo":"Tencent/WeKnora","slug":"connection-blocked-port-s-is-restricted","errorCode":null,"errorMessage":"connection blocked: port %s is restricted","messagePattern":"connection blocked: port (.+?) is restricted","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/utils/security.go","lineNumber":810,"sourceCode":"\t// Parse host and port\n\thost, port, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid address %s: %w\", addr, err)\n\t}\n\n\t// Whitelisted hosts bypass all dial-time SSRF checks, consistent with\n\t// ValidateURLForSSRF which skips isSSRFSafeURL for whitelisted hosts.\n\t// NOTE: This intentionally relaxes DNS-rebinding protection for whitelisted\n\t// hosts. Admins must ensure whitelisted domains are under their control.\n\tif IsSystemProxy(addr) || IsSSRFWhitelisted(host) {\n\t\tdialer := &net.Dialer{\n\t\t\tTimeout:   30 * time.Second,\n\t\t\tKeepAlive: 30 * time.Second,\n\t\t}\n\t\treturn dialer.DialContext(ctx, network, addr)\n\t}\n\tif restrictedPorts[port] {\n\t\treturn nil, fmt.Errorf(\"connection blocked: port %s is restricted\", port)\n\t}\n\n\t// Check if the host is a restricted hostname\n\thostLower := strings.ToLower(host)\n\tfor _, restricted := range restrictedHostnames {\n\t\tif hostLower == restricted {\n\t\t\treturn nil, fmt.Errorf(\"connection blocked: hostname %s is restricted\", host)\n\t\t}\n\t}\n\tfor _, suffix := range restrictedHostSuffixes {\n\t\tif strings.HasSuffix(hostLower, suffix) {\n\t\t\treturn nil, fmt.Errorf(\"connection blocked: hostname suffix %s is restricted\", suffix)\n\t\t}\n\t}\n\n\t// Resolve the hostname once, validate every answer, and then dial one of\n\t// those exact IPs. Dialing the original hostname here would make the\n\t// standard dialer resolve it a second time, leaving a DNS-rebinding window","sourceCodeStart":792,"sourceCodeEnd":828,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/utils/security.go#L792-L828","documentation":"SSRFSafeDialContext refused to open the connection because the destination port is in the library's restrictedPorts set. Certain ports (e.g. SMTP 25 and other services commonly abused for SSRF pivoting) are unconditionally blocked at dial time regardless of the host. This is an intentional security denial, not a connectivity problem.","triggerScenarios":"Dialing via SSRFSafeDialContext / SSRFSafeGRPCDialer (or an http.Transport whose DialContext is SSRFSafeDialContext) to any address whose port maps to true in the restrictedPorts map, after the whitelisted-host bypass is not taken. The test TestSSRFSafeDialContextRejectsRestrictedPortAtFinalSink hits this at the final sink for a restricted port.","commonSituations":"Trying to send email through port 25 of a relay from inside the guarded client; pointing a gRPC/HTTP client at an admin service on a blocked port; migrating a service to a port that happens to be on the restricted list.","solutions":["Move the service to a non-restricted port (e.g. 443/8443 for HTTPS) and update the client configuration.","If the host must stay as is, add it to the SSRF whitelist so dial-time checks are bypassed for that trusted host.","Check the restrictedPorts list in internal/utils/security.go to confirm the port is blocked and pick an allowed alternative.","Use a plain (non-SSRF-guarded) dialer only if you fully control the destination and accept losing the SSRF/DNS-rebinding protection."],"exampleFix":"// before\nconn, err := utils.SSRFSafeDialContext(ctx, \"tcp\", \"mail.example.com:25\")\n\n// after\nconn, err := utils.SSRFSafeDialContext(ctx, \"tcp\", \"mail.example.com:587\") // or whitelist the host","handlingStrategy":"validation","validationCode":"_, port, _ := net.SplitHostPort(addr)\nif n, err := strconv.Atoi(port); err == nil && utils.IsRestrictedPort(n) { // or check against restrictedPorts list\n    return fmt.Errorf(\"port %s is restricted by SSRF policy; choose another port\", port)\n}","typeGuard":null,"tryCatchPattern":"conn, err := utils.SSRFSafeDialContext(ctx, \"tcp\", addr)\nif err != nil && strings.Contains(err.Error(), \"port\") && strings.Contains(err.Error(), \"restricted\") {\n    return nil, fmt.Errorf(\"destination port not allowed by security policy: %w\", err)\n}","preventionTips":["Check the restrictedPorts list before choosing service ports.","Prefer standard allowed ports (80/443/8443) for outbound services.","Whitelist trusted hosts rather than working around port restrictions.","Document any port requirement in deployment config reviews."],"tags":["ssrf","restricted-port","dial","security-policy"],"backgroundTag":"port-blocked","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}