Loading nginx-ldap-auth-daemon.py +13 −5 Original line number Diff line number Diff line Loading @@ -2,9 +2,16 @@ ''''[ -z $LOG ] && export LOG=/dev/stdout # ''' ''''which python >/dev/null && exec python -u "$0" "$@" >> $LOG 2>&1 # ''' # Copyright (C) 2014-2015 Nginx, Inc. # Copyright (C) 2014-2022 Nginx, Inc. import sys import os import signal import base64 import ldap from ldap.filter import escape_filter_chars import argparse import sys, os, signal, base64, ldap, argparse if sys.version_info.major == 2: from Cookie import BaseCookie from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler Loading @@ -23,6 +30,7 @@ if not hasattr(__builtins__, "basestring"): basestring = (str, bytes) # ----------------------------------------------------------------------------- # Requests are processed in separate thread import threading if sys.version_info.major == 2: from SocketServer import ThreadingMixIn elif sys.version_info.major == 3: Loading Loading @@ -89,8 +97,8 @@ class AuthHandler(BaseHTTPRequestHandler): self.auth_failed(ctx) return True ctx['user'] = user ctx['pass'] = passwd ctx['user'] = ldap.filter.escape_filter_chars(user) # Continue request processing return False Loading t/ldap-auth.t +42 −8 Original line number Diff line number Diff line Loading @@ -105,6 +105,15 @@ http { proxy_pass http://backend/; } location /query-injection { auth_request /auth-query-injection; error_page 401 =200 /login; proxy_pass http://backend/; } location /login { proxy_pass http://backend/login; Loading Loading @@ -221,6 +230,24 @@ http { proxy_set_header Cookie nginxauth=$cookie_nginxauth; } location = /auth-query-injection { internal; proxy_pass http://127.0.0.1:8888; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Ldap-URL "ldap://127.0.0.1:8083"; proxy_set_header X-Ldap-BaseDN "ou=Users,dc=test,dc=local"; proxy_set_header X-Ldap-BindDN "cn=root,dc=test,dc=local"; proxy_set_header X-Ldap-BindPass "secret"; proxy_set_header X-CookieName "nginxauth"; proxy_set_header Cookie nginxauth=$cookie_nginxauth; proxy_set_header X-Ldap-Template '(|(&(memberOf=superadmin)(cn=%(username)s))(&(memberOf=admin)(cn=%(username)s)))'; } } } Loading Loading @@ -321,7 +348,7 @@ EOF $t->write_file_expand("initial.ldif", <<'EOF'); dn: dc=test,dc=local dc: test description: BlaBlaBla description: Test-OU objectClass: dcObject objectClass: organization o: Example, Inc. Loading @@ -333,7 +360,7 @@ objectclass: organizationalunit dn: cn=user1,ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User1 sn: u1 uid: user1 userpassword: user1secret Loading @@ -343,7 +370,7 @@ ou: Users dn: cn=user2,ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User2 sn: u2 uid: user2 userpassword: user2secret Loading @@ -353,7 +380,7 @@ ou: Users dn: cn=user3,ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User3 sn: u3 uid: user3 userpassword: user3secret Loading @@ -378,13 +405,13 @@ objectclass: organizationalunit dn: ou=more,ou=Users,dc=test,dc=local dc: test description: BlaBlaBla description: Test-OU objectClass: dcObject objectClass: organizationalUnit dn: cn=user4, ou=more, ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User4 sn: u4 uid: user4 userpassword: user4secret Loading Loading @@ -441,7 +468,7 @@ $t->run_daemon('/bin/sh', "$d/auth_daemon.sh"); $t->waitforsocket('127.0.0.1:' . port(8888)) or die "Can't start auth daemon"; $t->plan(21); $t->plan(22); $t->run(); Loading Loading @@ -500,10 +527,17 @@ like(http_get_auth('/ref1', 'user4', 'user4secret'), qr!LOGIN PAGE!, 'server2 user via referral on server1'); # unknown user on referred server, result is empty dn like(http_get_auth('/ref1', 'userx', 'blah'), qr!LOGIN PAGE!, like(http_get_auth('/ref1', 'unknow_user', 'unknowpassword'), qr!LOGIN PAGE!, 'unknown user with referral on server1'); # LDAP Query Injection result in 401 like(http_get_auth('/query-injection', 'user1))(|(cn=user1', 'user1secret'), qr!LOGIN PAGE!, 'Injection Attempt in Username will be escaped and blocked.'); ############################################################################### sub http_get_auth { Loading Loading
nginx-ldap-auth-daemon.py +13 −5 Original line number Diff line number Diff line Loading @@ -2,9 +2,16 @@ ''''[ -z $LOG ] && export LOG=/dev/stdout # ''' ''''which python >/dev/null && exec python -u "$0" "$@" >> $LOG 2>&1 # ''' # Copyright (C) 2014-2015 Nginx, Inc. # Copyright (C) 2014-2022 Nginx, Inc. import sys import os import signal import base64 import ldap from ldap.filter import escape_filter_chars import argparse import sys, os, signal, base64, ldap, argparse if sys.version_info.major == 2: from Cookie import BaseCookie from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler Loading @@ -23,6 +30,7 @@ if not hasattr(__builtins__, "basestring"): basestring = (str, bytes) # ----------------------------------------------------------------------------- # Requests are processed in separate thread import threading if sys.version_info.major == 2: from SocketServer import ThreadingMixIn elif sys.version_info.major == 3: Loading Loading @@ -89,8 +97,8 @@ class AuthHandler(BaseHTTPRequestHandler): self.auth_failed(ctx) return True ctx['user'] = user ctx['pass'] = passwd ctx['user'] = ldap.filter.escape_filter_chars(user) # Continue request processing return False Loading
t/ldap-auth.t +42 −8 Original line number Diff line number Diff line Loading @@ -105,6 +105,15 @@ http { proxy_pass http://backend/; } location /query-injection { auth_request /auth-query-injection; error_page 401 =200 /login; proxy_pass http://backend/; } location /login { proxy_pass http://backend/login; Loading Loading @@ -221,6 +230,24 @@ http { proxy_set_header Cookie nginxauth=$cookie_nginxauth; } location = /auth-query-injection { internal; proxy_pass http://127.0.0.1:8888; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Ldap-URL "ldap://127.0.0.1:8083"; proxy_set_header X-Ldap-BaseDN "ou=Users,dc=test,dc=local"; proxy_set_header X-Ldap-BindDN "cn=root,dc=test,dc=local"; proxy_set_header X-Ldap-BindPass "secret"; proxy_set_header X-CookieName "nginxauth"; proxy_set_header Cookie nginxauth=$cookie_nginxauth; proxy_set_header X-Ldap-Template '(|(&(memberOf=superadmin)(cn=%(username)s))(&(memberOf=admin)(cn=%(username)s)))'; } } } Loading Loading @@ -321,7 +348,7 @@ EOF $t->write_file_expand("initial.ldif", <<'EOF'); dn: dc=test,dc=local dc: test description: BlaBlaBla description: Test-OU objectClass: dcObject objectClass: organization o: Example, Inc. Loading @@ -333,7 +360,7 @@ objectclass: organizationalunit dn: cn=user1,ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User1 sn: u1 uid: user1 userpassword: user1secret Loading @@ -343,7 +370,7 @@ ou: Users dn: cn=user2,ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User2 sn: u2 uid: user2 userpassword: user2secret Loading @@ -353,7 +380,7 @@ ou: Users dn: cn=user3,ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User3 sn: u3 uid: user3 userpassword: user3secret Loading @@ -378,13 +405,13 @@ objectclass: organizationalunit dn: ou=more,ou=Users,dc=test,dc=local dc: test description: BlaBlaBla description: Test-OU objectClass: dcObject objectClass: organizationalUnit dn: cn=user4, ou=more, ou=Users,dc=test,dc=local objectclass: inetOrgPerson cn: User number one cn: User4 sn: u4 uid: user4 userpassword: user4secret Loading Loading @@ -441,7 +468,7 @@ $t->run_daemon('/bin/sh', "$d/auth_daemon.sh"); $t->waitforsocket('127.0.0.1:' . port(8888)) or die "Can't start auth daemon"; $t->plan(21); $t->plan(22); $t->run(); Loading Loading @@ -500,10 +527,17 @@ like(http_get_auth('/ref1', 'user4', 'user4secret'), qr!LOGIN PAGE!, 'server2 user via referral on server1'); # unknown user on referred server, result is empty dn like(http_get_auth('/ref1', 'userx', 'blah'), qr!LOGIN PAGE!, like(http_get_auth('/ref1', 'unknow_user', 'unknowpassword'), qr!LOGIN PAGE!, 'unknown user with referral on server1'); # LDAP Query Injection result in 401 like(http_get_auth('/query-injection', 'user1))(|(cn=user1', 'user1secret'), qr!LOGIN PAGE!, 'Injection Attempt in Username will be escaped and blocked.'); ############################################################################### sub http_get_auth { Loading