{"id":13521372,"url":"https://github.com/dispatchrun/netjail","last_synced_at":"2025-10-07T17:32:34.175Z","repository":{"id":220406589,"uuid":"751214506","full_name":"dispatchrun/netjail","owner":"dispatchrun","description":"Go library providing network access controls for dial functions and http transports","archived":false,"fork":false,"pushed_at":"2024-03-06T04:45:46.000Z","size":62,"stargazers_count":32,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-20T08:39:13.285Z","etag":null,"topics":["golang","http","network","security"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dispatchrun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"security.go","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-01T06:45:02.000Z","updated_at":"2024-09-16T02:22:36.000Z","dependencies_parsed_at":"2024-05-03T01:15:45.843Z","dependency_job_id":"97c82c19-c8c1-4590-858a-46761e94064f","html_url":"https://github.com/dispatchrun/netjail","commit_stats":null,"previous_names":["stealthrocket/netjail","dispatchrun/netjail"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dispatchrun%2Fnetjail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dispatchrun%2Fnetjail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dispatchrun%2Fnetjail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dispatchrun%2Fnetjail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dispatchrun","download_url":"https://codeload.github.com/dispatchrun/netjail/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222459962,"owners_count":16987954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","http","network","security"],"created_at":"2024-08-01T06:00:33.488Z","updated_at":"2025-10-07T17:32:29.143Z","avatar_url":"https://github.com/dispatchrun.png","language":"Go","readme":"# netjail\n\n[![Build](https://github.com/stealthrocket/netjail/actions/workflows/test.yml/badge.svg)](https://github.com/stealthrocket/netjail/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/stealthrocket/netjail)](https://goreportcard.com/report/github.com/stealthrocket/netjail)\n[![Go Reference](https://pkg.go.dev/badge/github.com/stealthrocket/netjail.svg)](https://pkg.go.dev/github.com/stealthrocket/netjail)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nGo library providing network access controls for dial functions and http transports\n\n## Motivation\n\nModern production systems are becoming increasingly complex, and often need to\nperform actions that are controlled by user input. For example, users may be\ngiven the option to define a Webhook URL to send data to, sometimes as part of\na larger workflow. Applications that give users the ability to control network\nrequests are exposed to the security risks of seeing those functionalities\nexploited to perform unintended actions. Attackers can use these features to\nforge network requests to internal systems, either to access private information\nor perform actions they should not be permitted to.\n\nClassic network access controls are effective measures to lock down access to\nprotected systems; however, they are not enough.\n\nConsider the case of deploying an application as an AWS Lambda Function. Lambda\noffers very strong isolation guarantees thanks to Firecracker,\nand the execution model guaranteeing that each instance of the function serves\nat most one concurrent invocation. However, the protocol used by AWS Lambda to\nreceive function invocations uses a *long-poll* http request to a localhost\nendpoint. Security groups implemented by the network cannot prevent the program\nfrom connecting to the loopback interface, and a malicious input could forge\nrequests to the local endpoint that the program was not supposed to make.\n\nLambda is one example, but there are many others, like an application invoking\nitself on unprotected internal endpoints, or sending requests to sidecar\ncontainers. Programs that have the ability to open connections to addresses\nextracted from user input must implement protections that the network layer\ncannot provide, which is what this package solves for.\n\n## Installation\n\nThis package is a library, it is intended to be used as a dependency in another\napplication:\n```\ngo get github.com/stealthrocket/netjail\n```\n\n## Usage\n\nThe library covers tow main use cases: controlling network access at the HTTP\nand TCP layers.\n\nPrograms can import the package with:\n```go\nimport \"github.com/stealthrocket/netjail\"\n```\n\n### Declaring rules for network access controls\n\nPrograms configure the set of networks that the application can connect to by\ndeclaring lists of **allowed** and **blocked** network ranges. An empty rule set\ndenies access to all networks. The list of allowed prefixes opens access to\nnetworks, and subnets can be restricted further by the list of blocked prefixes.\n\nThis example shows how to declare rules that allow connecting to all networks\nexcept loopback interfaces:\n```go\nallIPv4 := netip.MustParsePrefix(\"0.0.0.0/0\")\nallIPv6 := netip.MustParsePrefix(\"::/0\")\n\nlocalhostIPv4 := netip.MustParsePrefix(\"127.0.0.0/8\")\nlocalhostIPv6 := netip.MustParsePrefix(\"::1/128\")\n\nrules := \u0026netjail.Rules{\n    Allow: []netip.Prefix{\n        allIPv4,\n        allIPv6,\n    },\n    Block: []netip.Prefix{\n        localhostIPv4,\n        localhostIPv6,\n    },\n}\n```\n\nNetwork access controls often need to be propagated through the call stack of an\napplication, which can be done by embedding the rules in a\n[`context.Context`](https://pkg.go.dev/context#Context) using this function:\n```go\nctx = netjail.ContextWithRules(ctx, rules)\n```\nThe rules can later be retrieved by this function:\n```go\nrules := netjail.ContextRules(ctx)\n```\nIf the context does not contain any rules, the returned value is `nil`, which\nbehaves like an empty rule set, and denies all network access. This is critical\nto **fail closed** in the presence of application misconfiguration or errors.\n\n### Network access controls for HTTP transports\n\nThe package provides an implementation of\n[`http.RoundTripper`][httpRoundTripper] that extracts the set of network access\ncontrol rules from the context of an [`http.Request`][httpRequest], and applies\nthe rules to the connection used to serve the request.\n\nThe HTTP transport works by dynamically creating instances of\n[`http.Transport`][httpTransport], and overriding the dial function to apply\nnetwork access controls.\n\nThe following examples shows how to construct a secured client that applies a\nset of rules to the requests it serves:\n```go\nsecureClient := \u0026http.Client{\n    Transport: \u0026netjail.Transport{\n        New: func() *http.Transport{\n            // We must return a different instance each time the\n            // function is called, the transport would otherwise\n            // panic if it sees the same value more than once.\n            return http.DefaultTransport.(*http.Transport).Clone()\n        },\n    },\n}\n\n...\n\n// The context used to construct the request contains the network access\n// control rules that will be applied when passed to the client.\nctx = netjail.ContextWithRules(ctx, \u0026netjail.Rules{\n    ...\n})\n\nreq, err := http.NewRequestWithContext(ctx, \"GET\", userProvidedURL, nil)\n...\n\nres, err := secureClient.Do(req)\nif err != nil {\n    if errors.Is(err, netjail.ErrDenied) {\n        // The request was intended for a forbidden address\n        ...\n    }\n    ...\n}\n```\n\n[httpRoundTripper]: https://pkg.go.dev/net/http#RoundTripper\n[httpRequest]:      https://pkg.go.dev/net/http#Request.Context\n[httpTransport]:    https://pkg.go.dev/net/http#Transport\n\n### Network access controls for TCP connections\n\nWhile most applications use HTTP or protocols that are based on HTTP, some may\nneed to apply network access controls to clients of other protocols\n(e.g., MySQL, Redis, Kafka, etc...).\n\nLibraries that provide clients for these protocols will often allow configuring\na dial function to customize how network connections are opened. This dial\nfunction is the bottom-most hook that the `netjail` package can integrate with\nto apply security rules to any client.\n\nThe [`netjail.(*Rules).DialFunc`][dialFunc] method is the low-level wrapper that\ndecorates dial functions to apply network access controls defined in the\noriginating rules.\n\n[dialFunc]: https://pkg.go.dev/github.com/stealthrocket/netjail#Rules.DialFunc\n\n## Security Considerations\n\n### Protection against DNS rebinding attacks\n\nDNS rebinding attacks occur when an attacker attempts to forge the DNS responses\nreceived by an application, to route connections to addresses of their choosing.\nFor example, they could cause the DNS resolution for *example.com* to resolve to\n*127.0.0.1*, resulting in the application unknowningly connecting to localhost\ninstead of a remote server.\n\nTo prevent these types of attacks, the `netjail` package takes over the entire\nconnection process. It first resolves hostnames to a set of network addresses,\nthen validates those addresses against the allow and block lists, and only opens\nconnection to an address that passed the checks. With this process, there is no\nrisk of confusion between the validation and connection phases, effectively\nprotecting the application against DNS rebinding attacks that would attempt to\nbypass network access controls.\n\n### Protection against software defects and supplychain attacks\n\nSoftware security threats come in many forms, each dependency of a program can\nbecome the target of an attacker, and beyond that, even the process by which the\nsoftware is built and delivered can become the target of attackers. Producing\nsecure software requires the combination of multiple mitigation strategies to\ndefend against the variety of risks that the system is exposed to.\n\nTo limit exposure to those risks, the `netjail` package is designed to have no\ndependencies besides the Go standard library, and will remain dependency-free.\nThe package has a well-defined scope, if new features are added, it will always\nbe preferable to bring the code *in-house* than take a dependency on a third\nparty.\n\nWe used design decisions that reduce the risk of seeing security exploits arise\nin buggy software. We limit the use of interface types, because abstractions\nmake it more difficult to validate how the software will behave when components\nare replaced at run time. The use of concrete types offer stronger guarantees,\nand reduce the scope that tests need to cover. In addition, the library applies\nextensive validations against the inputs that it receives, and always defaults\nto **failing closed** or **failing loud** (e.g., blocking network connections,\npanicking in the presence of invalid state).\n","funding_links":[],"categories":["Members"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdispatchrun%2Fnetjail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdispatchrun%2Fnetjail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdispatchrun%2Fnetjail/lists"}