From ce7f9f6b781c90ce316408ca34de20cd59f36881 Mon Sep 17 00:00:00 2001 From: Jose Coelho Date: Mon, 29 Oct 2018 11:46:57 +0000 Subject: [PATCH 01/13] [ldap-case-insensitive-group] ldap groups should be case insensitive --- ldap_proxy.go | 8 ++++---- ldap_proxy_test.go | 10 ++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ldap_proxy.go b/ldap_proxy.go index 3b49ca1..d24c687 100644 --- a/ldap_proxy.go +++ b/ldap_proxy.go @@ -464,7 +464,7 @@ func (p *LdapProxy) SignIn(rw http.ResponseWriter, req *http.Request) { } if len(p.LdapGroups) > 0 { - if sliceContains(p.LdapGroups, groups) { + if sliceContainsString(p.LdapGroups, groups) { if err := p.SaveSession(rw, req, session); err != nil { log.Printf("failed to save session %v", err) } @@ -637,11 +637,11 @@ func (p *LdapProxy) CheckBasicAuth(req *http.Request) (*SessionState, error) { return nil, fmt.Errorf("%s not in HtpasswdFile", pair[0]) } -// sliceContains returns true if a and b contains any common string -func sliceContains(a, b []string) bool { +// sliceContainsString returns true if a and b contains any common string ignoring case +func sliceContainsString(a, b []string) bool { for _, aItem := range a { for _, bItem := range b { - if aItem == bItem { + if strings.ToLower(aItem) == strings.ToLower(bItem) { return true } } diff --git a/ldap_proxy_test.go b/ldap_proxy_test.go index a3b7e0f..feac4d7 100644 --- a/ldap_proxy_test.go +++ b/ldap_proxy_test.go @@ -120,7 +120,7 @@ func (fnc *fakeNetConn) Read(p []byte) (n int, err error) { return 0, io.EOF } -func TestSliceContains(t *testing.T) { +func TestSliceContainsString(t *testing.T) { testCases := []struct { desc string a []string @@ -133,6 +133,12 @@ func TestSliceContains(t *testing.T) { b: []string{"b"}, expect: true, }, + { + desc: "happy path case insensitive", + a: []string{"a", "B", "c"}, + b: []string{"b"}, + expect: true, + }, { desc: "empty", a: []string{}, @@ -149,7 +155,7 @@ func TestSliceContains(t *testing.T) { for _, tC := range testCases { t.Run(tC.desc, func(t *testing.T) { - if res := sliceContains(tC.a, tC.b); res != tC.expect { + if res := sliceContainsString(tC.a, tC.b); res != tC.expect { t.Errorf("with a %+v and b %+v, expected %+v, got %v", tC.a, tC.b, tC.expect, res) } }) From f426c12ab3b2ac8cfe641da452df645ec413b137 Mon Sep 17 00:00:00 2001 From: Richard Mitchell Date: Mon, 29 Oct 2018 11:50:42 +0000 Subject: [PATCH 02/13] Cut 0.3.4 --- CHANGELOG.md | 4 ++++ version.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e87998..b0d6480 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +0.3.4 (2018-10-29) +================== +* Make LDAP group comparisons case-insensitive + 0.3.3 (2018-06-21) ================== * Refactor LDAP connection code and use connections more efficiently diff --git a/version.go b/version.go index 9b05097..7d6a9d1 100644 --- a/version.go +++ b/version.go @@ -1,4 +1,4 @@ package main // VERSION released -const VERSION = "0.3.3" +const VERSION = "0.3.4" From 48a1214b61fdbe8d066bfd3cdeb2a87d6fd37147 Mon Sep 17 00:00:00 2001 From: Jose Coelho Date: Mon, 29 Oct 2018 12:39:54 +0000 Subject: [PATCH 03/13] [ldap-case-insensitive-group] fixing an issue validating user --- ldap_connection.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ldap_connection.go b/ldap_connection.go index eff630c..6c09672 100644 --- a/ldap_connection.go +++ b/ldap_connection.go @@ -66,6 +66,9 @@ func (c *LDAPClient) Close() { // Authenticate authenticates the user against the ldap backend. func (c *LDAPClient) Authenticate(username, password string) (bool, map[string]string, error) { + if username == "" || password == "" { + return false, nil, errors.New("invalid user or password") + } // First bind with a read only user if c.cfg.BindDN != "" && c.cfg.BindPassword != "" { @@ -116,7 +119,7 @@ func (c *LDAPClient) Authenticate(username, password string) (bool, map[string]s if c.cfg.BindDN != "" && c.cfg.BindPassword != "" { err = c.conn.Bind(c.cfg.BindDN, c.cfg.BindPassword) if err != nil { - return true, user, err + return false, user, err } } From 790a036d94e4383cefb1388df9f3bafa4b602303 Mon Sep 17 00:00:00 2001 From: Jose Coelho Date: Fri, 2 Nov 2018 14:37:21 +0000 Subject: [PATCH 04/13] [headers] set hsts, frame-options and cache headers --- http.go | 30 ++++++++++++++++++++++++++++-- ldap_proxy.go | 14 +++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/http.go b/http.go index d8049f0..206177e 100644 --- a/http.go +++ b/http.go @@ -48,7 +48,7 @@ func (s *Server) ServeHTTP() { } log.Printf("HTTP: listening on %s", listenAddr) - server := &http.Server{Handler: s.Handler} + server := &http.Server{Handler: XFrameOptionsMiddleware(s.Handler)} err = server.Serve(listener) if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { log.Printf("ERROR: http.Serve() - %s", err) @@ -83,7 +83,7 @@ func (s *Server) ServeHTTPS() { log.Printf("HTTPS: listening on %s", ln.Addr()) tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config) - srv := &http.Server{Handler: s.Handler} + srv := &http.Server{Handler: HSTSMiddleware(XFrameOptionsMiddleware(s.Handler))} err = srv.Serve(tlsListener) if err != nil && !strings.Contains(err.Error(), "use of closed network connection") { @@ -110,3 +110,29 @@ func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) { tc.SetKeepAlivePeriod(3 * time.Minute) return tc, nil } + +// HSTSMiddleware sets Strict-Transport-Security header +func HSTSMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains") + next.ServeHTTP(w, r) + }) +} + +// XFrameOptionsMiddleware sets Strict-Transport-Security header +func XFrameOptionsMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("X-Frame-Options", "deny") + next.ServeHTTP(w, r) + }) +} + +// NoCache sets no cache headers +func NoCache(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Cache-control", "no-store") + w.Header().Add("Pragma", "no-cache") + + next(w, r) + } +} diff --git a/ldap_proxy.go b/ldap_proxy.go index d24c687..6ba3ac7 100644 --- a/ldap_proxy.go +++ b/ldap_proxy.go @@ -220,12 +220,12 @@ func (p *LdapProxy) makeCookie(req *http.Request, name string, value string, exp } } -func (p *LdapProxy) RobotsTxt(rw http.ResponseWriter) { +func (p *LdapProxy) RobotsTxt(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusOK) fmt.Fprintf(rw, "User-agent: *\nDisallow: /") } -func (p *LdapProxy) PingPage(rw http.ResponseWriter) { +func (p *LdapProxy) PingPage(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusOK) fmt.Fprintf(rw, "OK") } @@ -396,17 +396,17 @@ func (p *LdapProxy) getRemoteAddrStr(req *http.Request) (s string) { func (p *LdapProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { switch path := req.URL.Path; { case path == p.RobotsPath: - p.RobotsTxt(rw) + NoCache(p.RobotsTxt)(rw, req) case path == p.PingPath: - p.PingPage(rw) + NoCache(p.PingPage)(rw, req) case p.IsWhitelistedRequest(req): p.serveMux.ServeHTTP(rw, req) case path == p.SignInPath: - p.SignIn(rw, req) + NoCache(p.SignIn)(rw, req) case path == p.SignOutPath: - p.SignOut(rw, req) + NoCache(p.SignOut)(rw, req) case path == p.AuthOnlyPath: - p.AuthenticateOnly(rw, req) + NoCache(p.AuthenticateOnly)(rw, req) default: p.Proxy(rw, req) } From 5df970ce4829a2823d50b08878d39befd122ec7a Mon Sep 17 00:00:00 2001 From: Jose Coelho Date: Mon, 5 Nov 2018 09:25:02 +0000 Subject: [PATCH 05/13] [headers] fix comment --- http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http.go b/http.go index 206177e..d759234 100644 --- a/http.go +++ b/http.go @@ -119,7 +119,7 @@ func HSTSMiddleware(next http.Handler) http.Handler { }) } -// XFrameOptionsMiddleware sets Strict-Transport-Security header +// XFrameOptionsMiddleware sets X-Frame-Options header func XFrameOptionsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Frame-Options", "deny") From 61137287e0eb51615c4e78be978effb856dd4c06 Mon Sep 17 00:00:00 2001 From: Richard Mitchell Date: Fri, 23 Nov 2018 08:14:38 +0000 Subject: [PATCH 06/13] Cut 0.4.0 --- CHANGELOG.md | 11 +++++++++++ version.go | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0d6480..8cc5a72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +0.4.0 (2018-11-23) +================== +* URGENT SECURITY FIX: authentication bypass via LDAP passwordless auth LDAP permits passwordless Bind operations by clients - this application verified authentication without checking specifically for an empty password, thus allowing authentication as any valid user by leaving the password field blank. This issue has been present since the first release of this application. + + See also: + * https://github.com/go-ldap/ldap/pull/126 + * https://github.com/pinepain/ldap-auth-proxy/issues/8 + * https://github.com/go-ldap/ldap/issues/93 + +* Added HTTP security headers and prevent caching of proxy pages + 0.3.4 (2018-10-29) ================== * Make LDAP group comparisons case-insensitive diff --git a/version.go b/version.go index 7d6a9d1..4972ad9 100644 --- a/version.go +++ b/version.go @@ -1,4 +1,4 @@ package main // VERSION released -const VERSION = "0.3.4" +const VERSION = "0.4.0" From 62057791a881607fa0a5b063b68895f6d67ae406 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 13:43:41 +0000 Subject: [PATCH 07/13] Pass LDAP scope name configuration through to template properly --- ldap_proxy.go | 3 +++ templates.go | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ldap_proxy.go b/ldap_proxy.go index 6ba3ac7..4754a5d 100644 --- a/ldap_proxy.go +++ b/ldap_proxy.go @@ -52,6 +52,7 @@ type LdapProxy struct { AuthOnlyPath string ProxyPrefix string + LdapScopeName string SignInMessage string HtpasswdFile *HtpasswdFile serveMux http.Handler @@ -175,6 +176,7 @@ func NewLdapProxy(opts *Options, validator func(string) bool) *LdapProxy { LdapConfiguration: ldapCfg, LdapGroups: opts.LdapGroups, + LdapScopeName: opts.LdapScopeName, skipAuthRegex: opts.SkipAuthRegex, skipAuthIPs: opts.skipIPs, @@ -267,6 +269,7 @@ func (p *LdapProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code i ProxyPrefix string Footer template.HTML }{ + LdapScopeName: p.LdapScopeName, SignInMessage: p.SignInMessage, Failed: failed, Redirect: redirectURL, diff --git a/templates.go b/templates.go index 5147dcd..8efa67c 100644 --- a/templates.go +++ b/templates.go @@ -118,7 +118,7 @@ func getTemplates() *template.Template { {{ if .SignInMessage }}

{{.SignInMessage}}

{{ end}} -

Sign in with a {{.LdapScopeName}} Account

+

Sign in with your {{.LdapScopeName}} account

{{ if .Failed }} From 53d3047c7fe56554d82a345426d6a65630887712 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 14:04:47 +0000 Subject: [PATCH 08/13] Bump version --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 4972ad9..0a58c40 100644 --- a/version.go +++ b/version.go @@ -1,4 +1,4 @@ package main // VERSION released -const VERSION = "0.4.0" +const VERSION = "0.5.0" From 454148ac9a3822c488af1c28cc718aef7b9e8dd4 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 14:37:18 +0000 Subject: [PATCH 09/13] Changelog for 0.5.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cc5a72..8c024bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +0.5.0 (2021-02-08) +================== +* Fix support for ldap_scope_name + 0.4.0 (2018-11-23) ================== * URGENT SECURITY FIX: authentication bypass via LDAP passwordless auth LDAP permits passwordless Bind operations by clients - this application verified authentication without checking specifically for an empty password, thus allowing authentication as any valid user by leaving the password field blank. This issue has been present since the first release of this application. From 7ca53f439487723c7d6c546952c538e5728791ef Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 15:21:31 +0000 Subject: [PATCH 10/13] Update screenshot for readme --- docs/screenshot.png | Bin 26435 -> 21795 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/screenshot.png b/docs/screenshot.png index b06a68fa7238f234ab481bab00da64de4cfbb0d8..0d77b11871a2c89fd79638194a9adffb63169f3a 100644 GIT binary patch literal 21795 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 Nc)I$ztaD0e0szS?QY!!e literal 26435 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νb?rWcCX8 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 From 7a09eddbc1a880e8a51024198973f31f41ee5775 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 15:24:11 +0000 Subject: [PATCH 11/13] Remove outdated release version from readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e54ade7..c69a742 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Strongly inspired by [bitly/oauth2_proxy](https://github.com/bitly/oauth2_proxy) ## Installation -1. Download [Prebuilt Binary](https://github.com/skybet/ldap_proxy/releases) (current release is `v2.2`) or build with `$ go get github.com/skybet/ldap_proxy` which will put the binary in `$GOROOT/bin` +1. Download [Prebuilt Binary](https://github.com/skybet/ldap_proxy/releases) or build with `$ go get github.com/skybet/ldap_proxy` which will put the binary in `$GOROOT/bin` 3. Configure Ldap Proxy using config file, command line options, or environment variables 4. Configure SSL or Deploy behind a SSL endpoint (example provided for Nginx) @@ -149,7 +149,7 @@ would be `https://internal.yourcompany.com/`. An example Nginx config follows. Note the use of `Strict-Transport-Security` header to pin requests to SSL via [HSTS](http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security): -``` +```nginx server { listen 443 default ssl; server_name internal.yourcompany.com; From 4b6f6120736adb9049778314af325c3e14e1e4f6 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 15:27:20 +0000 Subject: [PATCH 12/13] Fix build status Travis link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c69a742..954a535 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A reverse proxy and static file server that provides authentication using LDAP. Strongly inspired by [bitly/oauth2_proxy](https://github.com/bitly/oauth2_proxy). -[![Build Status](https://secure.travis-ci.org/ant1441/ldap_proxy.png?branch=master)](http://travis-ci.org/ant1441/ldap_proxy) +[![Build Status](https://travis-ci.com/skybet/ldap_proxy.svg?branch=master)](https://travis-ci.com/skybet/ldap_proxy) ![Screenshot](docs/screenshot.png) From 9c336a6a1dfce7e50d17f889ff893bc39be5e407 Mon Sep 17 00:00:00 2001 From: Chris Buckley Date: Mon, 8 Feb 2021 15:37:40 +0000 Subject: [PATCH 13/13] Update go version in travis builds --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8c830da..605ae9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,8 @@ language: go go: - - 1.7.5 - - 1.8.1 + - 1.10.x + - 1.11.x + - 1.12.x script: - curl -s https://raw.githubusercontent.com/pote/gpm/v1.4.0/bin/gpm > gpm - chmod +x gpm