diff --git a/README.md b/README.md
index 91227a0095f6d43527ce5039653fc0dcc3c89cfd..9d3d9a576ca0ba3738c65c8f344ff90846d7ed0c 100644
--- a/README.md
+++ b/README.md
@@ -91,6 +91,7 @@ variables (or a combination of the two):
 | `-max-duration` | `MAX_DURATION` | Maximum duration a response may take | 10s |
 | `-port` | `PORT` | Port to listen on | 8080 |
 | `-use-real-hostname` | `USE_REAL_HOSTNAME` | Expose real hostname as reported by os.Hostname() in the /hostname endpoint | false |
+| `-exclude-headers` | `EXCLUDE_HEADERS` | Drop platform-specific headers. Comma-separated list of headers key to drop, supporting wildcard suffix matching. For example: `"foo,bar,x-fc-*"` | - |
 
 **Notes:**
 - Command line arguments take precedence over environment variables.
@@ -159,6 +160,13 @@ public internet, consider tuning it appropriately:
      logging using [zerolog] and further hardens the HTTP server against
      malicious clients by tuning lower-level timeouts and limits.
 
+5. **Prevent leaking sensitive headers**
+
+  By default, go-httpbin will return any headers sent by the client in the response.
+  But if you want to deploy go-httpbin in some serverless environment, you may want to drop some headers.
+  You can use the `-exclude-headers` CLI argument or the `EXCLUDE_HEADERS` env var to configure an appropriate allowlist.
+  For example, Alibaba Cloud Function Compute will [add some headers like `x-fc-*` to the request](https://www.alibabacloud.com/help/en/fc/user-guide/specification-details). if you want to drop these `x-fc-*` headers, you can set `EXCLUDE_HEADERS=x-fc-*`.
+
 ## Development
 
 ```bash
diff --git a/httpbin/cmd/cmd.go b/httpbin/cmd/cmd.go
index c006dc018ebe8ff7c18c89181fd156e8f799cf45..1a1b7098f4d5d6df31b7b86dff5553044e7ab9e0 100644
--- a/httpbin/cmd/cmd.go
+++ b/httpbin/cmd/cmd.go
@@ -69,6 +69,7 @@ func mainImpl(args []string, getEnv func(string) string, getHostname func() (str
 		httpbin.WithMaxBodySize(cfg.MaxBodySize),
 		httpbin.WithMaxDuration(cfg.MaxDuration),
 		httpbin.WithObserver(httpbin.StdLogObserver(logger)),
+		httpbin.WithExcludeHeaders(cfg.ExcludeHeaders),
 	}
 	if cfg.RealHostname != "" {
 		opts = append(opts, httpbin.WithHostname(cfg.RealHostname))
@@ -99,6 +100,7 @@ func mainImpl(args []string, getEnv func(string) string, getHostname func() (str
 type config struct {
 	AllowedRedirectDomains []string
 	ListenHost             string
+	ExcludeHeaders         string
 	ListenPort             int
 	MaxBodySize            int64
 	MaxDuration            time.Duration
@@ -140,6 +142,7 @@ func loadConfig(args []string, getEnv func(string) string, getHostname func() (s
 	fs.StringVar(&cfg.ListenHost, "host", defaultListenHost, "Host to listen on")
 	fs.StringVar(&cfg.TLSCertFile, "https-cert-file", "", "HTTPS Server certificate file")
 	fs.StringVar(&cfg.TLSKeyFile, "https-key-file", "", "HTTPS Server private key file")
+	fs.StringVar(&cfg.ExcludeHeaders, "exclude-headers", "", "Drop platform-specific headers. Comma-separated list of headers key to drop, supporting wildcard matching.")
 
 	// in order to fully control error output whether CLI arguments or env vars
 	// are used to configure the app, we need to take control away from the
@@ -189,6 +192,9 @@ func loadConfig(args []string, getEnv func(string) string, getHostname func() (s
 	if cfg.ListenHost == defaultListenHost && getEnv("HOST") != "" {
 		cfg.ListenHost = getEnv("HOST")
 	}
+	if cfg.ExcludeHeaders == "" && getEnv("EXCLUDE_HEADERS") != "" {
+		cfg.ExcludeHeaders = getEnv("EXCLUDE_HEADERS")
+	}
 	if cfg.ListenPort == defaultListenPort && getEnv("PORT") != "" {
 		cfg.ListenPort, err = strconv.Atoi(getEnv("PORT"))
 		if err != nil {
diff --git a/httpbin/cmd/cmd_test.go b/httpbin/cmd/cmd_test.go
index 5ce96cd315cd89540f741978413b1f79705a73e8..78af9a4094a9510e8da46080e03b52c044caa72f 100644
--- a/httpbin/cmd/cmd_test.go
+++ b/httpbin/cmd/cmd_test.go
@@ -17,6 +17,8 @@ import (
 const usage = `Usage of go-httpbin:
   -allowed-redirect-domains string
     	Comma-separated list of domains the /redirect-to endpoint will allow
+  -exclude-headers string
+    	Drop platform-specific headers. Comma-separated list of headers key to drop, supporting wildcard matching.
   -host string
     	Host to listen on (default "0.0.0.0")
   -https-cert-file string
diff --git a/httpbin/handlers.go b/httpbin/handlers.go
index f7cfea71ffd138f67594612a644c741599054797..0755a83d188bed7204f79042ef619a742271c6ed 100644
--- a/httpbin/handlers.go
+++ b/httpbin/handlers.go
@@ -47,7 +47,7 @@ func (h *HTTPBin) UTF8(w http.ResponseWriter, r *http.Request) {
 func (h *HTTPBin) Get(w http.ResponseWriter, r *http.Request) {
 	writeJSON(http.StatusOK, w, &noBodyResponse{
 		Args:    r.URL.Query(),
-		Headers: getRequestHeaders(r),
+		Headers: getRequestHeaders(r, h.excludeHeadersProcessor),
 		Method:  r.Method,
 		Origin:  getClientIP(r),
 		URL:     getURL(r).String(),
@@ -74,7 +74,7 @@ func (h *HTTPBin) RequestWithBody(w http.ResponseWriter, r *http.Request) {
 		Args:    r.URL.Query(),
 		Files:   nilValues,
 		Form:    nilValues,
-		Headers: getRequestHeaders(r),
+		Headers: getRequestHeaders(r, h.excludeHeadersProcessor),
 		Method:  r.Method,
 		Origin:  getClientIP(r),
 		URL:     getURL(r).String(),
@@ -96,7 +96,7 @@ func (h *HTTPBin) Gzip(w http.ResponseWriter, r *http.Request) {
 	)
 	mustMarshalJSON(gzw, &noBodyResponse{
 		Args:    r.URL.Query(),
-		Headers: getRequestHeaders(r),
+		Headers: getRequestHeaders(r, h.excludeHeadersProcessor),
 		Method:  r.Method,
 		Origin:  getClientIP(r),
 		Gzipped: true,
@@ -119,7 +119,7 @@ func (h *HTTPBin) Deflate(w http.ResponseWriter, r *http.Request) {
 	)
 	mustMarshalJSON(zw, &noBodyResponse{
 		Args:     r.URL.Query(),
-		Headers:  getRequestHeaders(r),
+		Headers:  getRequestHeaders(r, h.excludeHeadersProcessor),
 		Method:   r.Method,
 		Origin:   getClientIP(r),
 		Deflated: true,
@@ -151,7 +151,7 @@ func (h *HTTPBin) UserAgent(w http.ResponseWriter, r *http.Request) {
 // Headers echoes the incoming request headers
 func (h *HTTPBin) Headers(w http.ResponseWriter, r *http.Request) {
 	writeJSON(http.StatusOK, w, &headersResponse{
-		Headers: getRequestHeaders(r),
+		Headers: getRequestHeaders(r, h.excludeHeadersProcessor),
 	})
 }
 
@@ -538,7 +538,7 @@ func (h *HTTPBin) Stream(w http.ResponseWriter, r *http.Request) {
 
 	resp := &streamResponse{
 		Args:    r.URL.Query(),
-		Headers: getRequestHeaders(r),
+		Headers: getRequestHeaders(r, h.excludeHeadersProcessor),
 		Origin:  getClientIP(r),
 		URL:     getURL(r).String(),
 	}
@@ -783,7 +783,7 @@ func (h *HTTPBin) ETag(w http.ResponseWriter, r *http.Request) {
 	var buf bytes.Buffer
 	mustMarshalJSON(&buf, noBodyResponse{
 		Args:    r.URL.Query(),
-		Headers: getRequestHeaders(r),
+		Headers: getRequestHeaders(r, h.excludeHeadersProcessor),
 		Method:  r.Method,
 		Origin:  getClientIP(r),
 		URL:     getURL(r).String(),
diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go
index bef3d5f313acbfc45e206fb0d0a0dcd7f6ff7756..716dd697187742177d16ff5d100357e5e3a7f6c9 100644
--- a/httpbin/handlers_test.go
+++ b/httpbin/handlers_test.go
@@ -61,6 +61,7 @@ func TestMain(m *testing.M) {
 		WithMaxBodySize(maxBodySize),
 		WithMaxDuration(maxDuration),
 		WithObserver(StdLogObserver(log.New(io.Discard, "", 0))),
+		WithExcludeHeaders("x-ignore-*,x-info-this-key"),
 	)
 	srv, client = newTestServer(app)
 	defer srv.Close()
@@ -167,6 +168,28 @@ func TestGet(t *testing.T) {
 		assert.Equal(t, result.Method, "GET", "method mismatch")
 	})
 
+	t.Run("will ignore specific headers", func(t *testing.T) {
+		t.Parallel()
+
+		params := url.Values{}
+		params.Set("foo", "foo")
+		params.Add("bar", "bar1")
+		params.Add("bar", "bar2")
+
+		header := http.Header{}
+
+		header.Set("X-Ignore-Foo", "foo")
+		header.Set("X-Info-Foo", "bar")
+		header.Set("x-info-this-key", "baz")
+
+		result := doGetRequest(t, "/get", params, header)
+		assert.Equal(t, result.Args.Encode(), params.Encode(), "args mismatch")
+		assert.Equal(t, result.Method, "GET", "method mismatch")
+		assertHeaderEqual(t, &result.Headers, "X-Ignore-Foo", "")
+		assertHeaderEqual(t, &result.Headers, "x-info-this-key", "")
+		assertHeaderEqual(t, &result.Headers, "X-Info-Foo", "bar")
+	})
+
 	t.Run("only_allows_gets", func(t *testing.T) {
 		t.Parallel()
 
@@ -2920,3 +2943,11 @@ func consumeAndCloseBody(resp *http.Response) {
 	_, _ = io.Copy(io.Discard, resp.Body)
 	resp.Body.Close()
 }
+
+func assertHeaderEqual(t *testing.T, header *http.Header, key, want string) {
+	t.Helper()
+	got := header.Get(key)
+	if want != got {
+		t.Fatalf("expected header %s=%#v, got %#v", key, want, got)
+	}
+}
diff --git a/httpbin/helpers.go b/httpbin/helpers.go
index 76db70b36081d48383eb57cf7fde8a7535ec9569..8b04ca6a1388c7a5c02c90b2643ed3fe0012c4fe 100644
--- a/httpbin/helpers.go
+++ b/httpbin/helpers.go
@@ -13,6 +13,7 @@ import (
 	"mime/multipart"
 	"net/http"
 	"net/url"
+	"regexp"
 	"strconv"
 	"strings"
 	"sync"
@@ -28,12 +29,15 @@ const Base64MaxLen = 2000
 // This is necessary to ensure that the incoming Host and Transfer-Encoding
 // headers are included, because golang only exposes those values on the
 // http.Request struct itself.
-func getRequestHeaders(r *http.Request) http.Header {
+func getRequestHeaders(r *http.Request, fn headersProcessorFunc) http.Header {
 	h := r.Header
 	h.Set("Host", r.Host)
 	if len(r.TransferEncoding) > 0 {
 		h.Set("Transfer-Encoding", strings.Join(r.TransferEncoding, ","))
 	}
+	if fn != nil {
+		return fn(h)
+	}
 	return h
 }
 
@@ -433,3 +437,62 @@ func (b *base64Helper) Encode() ([]byte, error) {
 func (b *base64Helper) Decode() ([]byte, error) {
 	return base64.URLEncoding.DecodeString(b.data)
 }
+
+func wildCardToRegexp(pattern string) string {
+	components := strings.Split(pattern, "*")
+	if len(components) == 1 {
+		// if len is 1, there are no *'s, return exact match pattern
+		return "^" + pattern + "$"
+	}
+	var result strings.Builder
+	for i, literal := range components {
+
+		// Replace * with .*
+		if i > 0 {
+			result.WriteString(".*")
+		}
+
+		// Quote any regular expression meta characters in the
+		// literal text.
+		result.WriteString(regexp.QuoteMeta(literal))
+	}
+	return "^" + result.String() + "$"
+}
+
+func createExcludeHeadersProcessor(excludeRegex *regexp.Regexp) headersProcessorFunc {
+	return func(headers http.Header) http.Header {
+		result := make(http.Header)
+		for k, v := range headers {
+			matched := excludeRegex.Match([]byte(k))
+			if matched {
+				continue
+			}
+			result[k] = v
+		}
+
+		return result
+	}
+}
+
+func createFullExcludeRegex(excludeHeaders string) *regexp.Regexp {
+	// comma separated list of headers to exclude from response
+	tmp := strings.Split(excludeHeaders, ",")
+
+	tmpRegexStrings := make([]string, 0)
+	for _, v := range tmp {
+		s := strings.TrimSpace(v)
+		if len(s) == 0 {
+			continue
+		}
+		pattern := wildCardToRegexp(s)
+		tmpRegexStrings = append(tmpRegexStrings, pattern)
+	}
+
+	if len(tmpRegexStrings) > 0 {
+		tmpRegexStr := strings.Join(tmpRegexStrings, "|")
+		result := regexp.MustCompile("(?i)" + "(" + tmpRegexStr + ")")
+		return result
+	}
+
+	return nil
+}
diff --git a/httpbin/helpers_test.go b/httpbin/helpers_test.go
index a3f7bce40226a31d147d10c283b9ae91adae60db..71525c6638970bfcec4f1a9b5db17a313e0ee866 100644
--- a/httpbin/helpers_test.go
+++ b/httpbin/helpers_test.go
@@ -8,6 +8,7 @@ import (
 	"mime/multipart"
 	"net/http"
 	"net/url"
+	"regexp"
 	"testing"
 	"time"
 
@@ -276,3 +277,111 @@ func TestParseFileDoesntExist(t *testing.T) {
 		t.Fatalf("Open(nonexist): error is %T, want *PathError", err)
 	}
 }
+
+func TestWildcardHelpers(t *testing.T) {
+	tests := []struct {
+		pattern  string
+		name     string
+		input    string
+		expected bool
+	}{
+		{
+			"info-*",
+			"basic test",
+			"info-foo",
+			true,
+		},
+		{
+			"info-*",
+			"basic test case insensitive",
+			"INFO-bar",
+			true,
+		},
+		{
+			"info-*-foo",
+			"a single wildcard in the middle of the string",
+			"INFO-bar-foo",
+			true,
+		},
+		{
+			"info-*-foo",
+			"a single wildcard in the middle of the string",
+			"INFO-bar-baz",
+			false,
+		},
+		{
+			"info-*-foo-*-bar",
+			"multiple wildcards in the string",
+			"info-aaa-foo--bar",
+			true,
+		},
+		{
+			"info-*-foo-*-bar",
+			"multiple wildcards in the string",
+			"info-aaa-foo-a-bar",
+			true,
+		},
+		{
+			"info-*-foo-*-bar",
+			"multiple wildcards in the string",
+			"info-aaa-foo--bar123",
+			false,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			tmpRegexStr := wildCardToRegexp(test.pattern)
+			regex := regexp.MustCompile("(?i)" + "(" + tmpRegexStr + ")")
+			matched := regex.Match([]byte(test.input))
+			assert.Equal(t, matched, test.expected, "incorrect match")
+		})
+	}
+}
+
+func TestCreateFullExcludeRegex(t *testing.T) {
+	// tolerate unused comma
+	excludeHeaders := "x-ignore-*,x-info-this-key,,"
+	regex := createFullExcludeRegex(excludeHeaders)
+	tests := []struct {
+		name     string
+		input    string
+		expected bool
+	}{
+		{
+			"basic test",
+			"x-ignore-foo",
+			true,
+		},
+		{
+			"basic test case insensitive",
+			"X-IGNORE-bar",
+			true,
+		},
+		{
+			"basic test 3",
+			"x-info-this-key",
+			true,
+		},
+		{
+			"basic test 4",
+			"foo-bar",
+			false,
+		},
+		{
+			"basic test 5",
+			"x-info-this-key-foo",
+			false,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			matched := regex.Match([]byte(test.input))
+			assert.Equal(t, matched, test.expected, "incorrect match")
+		})
+	}
+
+	nilReturn := createFullExcludeRegex("")
+	assert.Equal(t, nilReturn, nil, "incorrect match")
+}
diff --git a/httpbin/httpbin.go b/httpbin/httpbin.go
index db73b66499d85aefed958d741c8173e2985c185a..81315fb60aa730995be335c980386348558ef783 100644
--- a/httpbin/httpbin.go
+++ b/httpbin/httpbin.go
@@ -27,6 +27,8 @@ var DefaultDefaultParams = DefaultParams{
 	DripNumBytes: 10,
 }
 
+type headersProcessorFunc func(h http.Header) http.Header
+
 // HTTPBin contains the business logic
 type HTTPBin struct {
 	// Max size of an incoming request generated response body, in bytes
@@ -44,6 +46,7 @@ type HTTPBin struct {
 
 	// Set of hosts to which the /redirect-to endpoint will allow redirects
 	AllowedRedirectDomains map[string]struct{}
+
 	forbiddenRedirectError string
 
 	// The hostname to expose via /hostname.
@@ -51,6 +54,8 @@ type HTTPBin struct {
 
 	// The app's http handler
 	handler http.Handler
+
+	excludeHeadersProcessor headersProcessorFunc
 }
 
 // New creates a new HTTPBin instance
@@ -179,3 +184,10 @@ func (h *HTTPBin) Handler() http.Handler {
 
 	return handler
 }
+
+func (h *HTTPBin) setExcludeHeaders(excludeHeaders string) {
+	regex := createFullExcludeRegex(excludeHeaders)
+	if regex != nil {
+		h.excludeHeadersProcessor = createExcludeHeadersProcessor(regex)
+	}
+}
diff --git a/httpbin/options.go b/httpbin/options.go
index 37fb270409c304d77cea889480c55acb042f4383..0fa5976205ebf3f5a8f62f8a085758871594a90b 100644
--- a/httpbin/options.go
+++ b/httpbin/options.go
@@ -46,6 +46,12 @@ func WithObserver(o Observer) OptionFunc {
 	}
 }
 
+func WithExcludeHeaders(excludeHeaders string) OptionFunc {
+	return func(h *HTTPBin) {
+		h.setExcludeHeaders(excludeHeaders)
+	}
+}
+
 // WithAllowedRedirectDomains limits the domains to which the /redirect-to
 // endpoint will redirect traffic.
 func WithAllowedRedirectDomains(hosts []string) OptionFunc {