Skip to content

Commit 1599be1

Browse files
feat: block disallowed HTTP requests
1 parent 69da434 commit 1599be1

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

proxy/proxy.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import (
55
"crypto/tls"
66
"errors"
77
"fmt"
8+
"io"
89
"log"
910
"log/slog"
1011
"net"
1112
"net/http"
13+
"strings"
1214
"sync/atomic"
1315

1416
"github.com/coder/boundary/audit"
@@ -163,6 +165,22 @@ func (p *Server) handleHTTPConnection(conn net.Conn) {
163165
log.Printf(" Host: %s", req.Host)
164166
log.Printf(" User-Agent: %s", req.Header.Get("User-Agent"))
165167

168+
// Check if request should be allowed
169+
result := p.ruleEngine.Evaluate(req.Method, req.Host)
170+
171+
// Audit the request
172+
//p.auditor.AuditRequest(audit.Request{
173+
// Method: req.Method,
174+
// URL: req.URL.String(),
175+
// Allowed: result.Allowed,
176+
// Rule: result.Rule,
177+
//})
178+
179+
if !result.Allowed {
180+
p.writeBlockedResponse(conn, req)
181+
return
182+
}
183+
166184
// Forward HTTP request to destination
167185
p.forwardHTTPRequest(conn, req)
168186
}
@@ -267,6 +285,48 @@ func (p *Server) forwardHTTPSRequest(conn net.Conn, req *http.Request) {
267285
resp.Write(conn)
268286
}
269287

288+
func (p *Server) writeBlockedResponse(conn net.Conn, req *http.Request) {
289+
// Create a response object
290+
resp := &http.Response{
291+
Status: "403 Forbidden",
292+
StatusCode: http.StatusForbidden,
293+
Proto: "HTTP/1.1",
294+
ProtoMajor: 1,
295+
ProtoMinor: 1,
296+
Header: make(http.Header),
297+
Body: nil,
298+
ContentLength: 0,
299+
}
300+
301+
// Set headers
302+
resp.Header.Set("Content-Type", "text/plain")
303+
304+
// Create the response body
305+
host := req.URL.Host
306+
if host == "" {
307+
host = req.Host
308+
}
309+
310+
body := fmt.Sprintf(`🚫 Request Blocked by Boundary
311+
312+
Request: %s %s
313+
Host: %s
314+
315+
To allow this request, restart boundary with:
316+
--allow "%s" # Allow all methods to this host
317+
--allow "%s %s" # Allow only %s requests to this host
318+
319+
For more help: https://github.com/coder/boundary
320+
`,
321+
req.Method, req.URL.Path, host, host, req.Method, host, req.Method)
322+
323+
resp.Body = io.NopCloser(strings.NewReader(body))
324+
resp.ContentLength = int64(len(body))
325+
326+
// Write to connection
327+
resp.Write(conn)
328+
}
329+
270330
// connectionWrapper lets us "unread" the peeked byte
271331
type connectionWrapper struct {
272332
net.Conn

0 commit comments

Comments
 (0)