Compare commits
	
		
			5 Commits
		
	
	
		
			763f23b297
			...
			2ef1e5cae4
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 2ef1e5cae4 | |
|  | e00e31d949 | |
|  | 0aab49006d | |
|  | 23d036cb69 | |
|  | c0a43f4800 | 
|  | @ -0,0 +1,2 @@ | ||||||
|  | .env | ||||||
|  | htmlcov | ||||||
|  | @ -2,9 +2,16 @@ | ||||||
| ''''[ -z $LOG ] && export LOG=/dev/stdout # ''' | ''''[ -z $LOG ] && export LOG=/dev/stdout # ''' | ||||||
| ''''which python  >/dev/null && exec python  -u "$0" "$@" >> $LOG 2>&1 # ''' | ''''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: | if sys.version_info.major == 2: | ||||||
|     from Cookie import BaseCookie |     from Cookie import BaseCookie | ||||||
|     from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler |     from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler | ||||||
|  | @ -23,6 +30,7 @@ if not hasattr(__builtins__, "basestring"): basestring = (str, bytes) | ||||||
| # ----------------------------------------------------------------------------- | # ----------------------------------------------------------------------------- | ||||||
| # Requests are processed in separate thread | # Requests are processed in separate thread | ||||||
| import threading | import threading | ||||||
|  | 
 | ||||||
| if sys.version_info.major == 2: | if sys.version_info.major == 2: | ||||||
|     from SocketServer import ThreadingMixIn |     from SocketServer import ThreadingMixIn | ||||||
| elif sys.version_info.major == 3: | elif sys.version_info.major == 3: | ||||||
|  | @ -89,8 +97,8 @@ class AuthHandler(BaseHTTPRequestHandler): | ||||||
|             self.auth_failed(ctx) |             self.auth_failed(ctx) | ||||||
|             return True |             return True | ||||||
|         |         | ||||||
|         ctx['user'] = user |  | ||||||
|         ctx['pass'] = passwd |         ctx['pass'] = passwd | ||||||
|  |         ctx['user'] = ldap.filter.escape_filter_chars(user) | ||||||
| 
 | 
 | ||||||
|         # Continue request processing |         # Continue request processing | ||||||
|         return False |         return False | ||||||
|  |  | ||||||
|  | @ -1,12 +1,16 @@ | ||||||
| To run tests use supplied Dockerfile.test: | To run tests use supplied Dockerfile.test: | ||||||
| 
 | 
 | ||||||
| docker build -f Dockerfile.test -t my-tag | ```shell | ||||||
|  | docker build -t my-tag -f Dockerfile.test . | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| If you desire to use a container with Python3, you can supply an appropriate | If you desire to use a container with Python3, you can supply an appropriate | ||||||
| build argument: | build argument: | ||||||
| 
 | 
 | ||||||
|  | ```shell | ||||||
| docker build -f Dockerfile.test -t my-tag --build-arg PYTHON_VERSION=3 . | docker build -f Dockerfile.test -t my-tag --build-arg PYTHON_VERSION=3 . | ||||||
| docker run my-tag | docker run my-tag | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| To run without Docker: | To run without Docker: | ||||||
| 
 | 
 | ||||||
|  | @ -105,6 +105,15 @@ http { | ||||||
|             proxy_pass http://backend/; |             proxy_pass http://backend/; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         location /query-injection { | ||||||
|  |             auth_request /auth-query-injection; | ||||||
|  | 	     | ||||||
|  | 	    error_page 401 =200 /login; | ||||||
|  | 	     | ||||||
|  | 	    proxy_pass http://backend/; | ||||||
|  |         | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         location /login { |         location /login { | ||||||
|             proxy_pass http://backend/login; |             proxy_pass http://backend/login; | ||||||
| 
 | 
 | ||||||
|  | @ -221,6 +230,24 @@ http { | ||||||
|             proxy_set_header Cookie nginxauth=$cookie_nginxauth; |             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)))'; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -321,7 +348,7 @@ EOF | ||||||
| $t->write_file_expand("initial.ldif", <<'EOF'); | $t->write_file_expand("initial.ldif", <<'EOF'); | ||||||
| dn: dc=test,dc=local | dn: dc=test,dc=local | ||||||
| dc: test | dc: test | ||||||
| description: BlaBlaBla | description: Test-OU | ||||||
| objectClass: dcObject | objectClass: dcObject | ||||||
| objectClass: organization | objectClass: organization | ||||||
| o: Example, Inc. | o: Example, Inc. | ||||||
|  | @ -333,7 +360,7 @@ objectclass: organizationalunit | ||||||
| 
 | 
 | ||||||
| dn: cn=user1,ou=Users,dc=test,dc=local | dn: cn=user1,ou=Users,dc=test,dc=local | ||||||
| objectclass: inetOrgPerson | objectclass: inetOrgPerson | ||||||
| cn: User number one | cn: User1 | ||||||
| sn: u1 | sn: u1 | ||||||
| uid: user1 | uid: user1 | ||||||
| userpassword: user1secret | userpassword: user1secret | ||||||
|  | @ -343,7 +370,7 @@ ou: Users | ||||||
| 
 | 
 | ||||||
| dn: cn=user2,ou=Users,dc=test,dc=local | dn: cn=user2,ou=Users,dc=test,dc=local | ||||||
| objectclass: inetOrgPerson | objectclass: inetOrgPerson | ||||||
| cn: User number one | cn: User2 | ||||||
| sn: u2 | sn: u2 | ||||||
| uid: user2 | uid: user2 | ||||||
| userpassword: user2secret | userpassword: user2secret | ||||||
|  | @ -353,7 +380,7 @@ ou: Users | ||||||
| 
 | 
 | ||||||
| dn: cn=user3,ou=Users,dc=test,dc=local | dn: cn=user3,ou=Users,dc=test,dc=local | ||||||
| objectclass: inetOrgPerson | objectclass: inetOrgPerson | ||||||
| cn: User number one | cn: User3 | ||||||
| sn: u3 | sn: u3 | ||||||
| uid: user3 | uid: user3 | ||||||
| userpassword: user3secret | userpassword: user3secret | ||||||
|  | @ -378,13 +405,13 @@ objectclass: organizationalunit | ||||||
| 
 | 
 | ||||||
| dn: ou=more,ou=Users,dc=test,dc=local | dn: ou=more,ou=Users,dc=test,dc=local | ||||||
| dc: test | dc: test | ||||||
| description: BlaBlaBla | description: Test-OU | ||||||
| objectClass: dcObject | objectClass: dcObject | ||||||
| objectClass: organizationalUnit | objectClass: organizationalUnit | ||||||
| 
 | 
 | ||||||
| dn: cn=user4, ou=more, ou=Users,dc=test,dc=local | dn: cn=user4, ou=more, ou=Users,dc=test,dc=local | ||||||
| objectclass: inetOrgPerson | objectclass: inetOrgPerson | ||||||
| cn: User number one | cn: User4 | ||||||
| sn: u4 | sn: u4 | ||||||
| uid: user4 | uid: user4 | ||||||
| userpassword: user4secret | userpassword: user4secret | ||||||
|  | @ -441,7 +468,7 @@ $t->run_daemon('/bin/sh', "$d/auth_daemon.sh"); | ||||||
| $t->waitforsocket('127.0.0.1:' . port(8888)) | $t->waitforsocket('127.0.0.1:' . port(8888)) | ||||||
| 	or die "Can't start auth daemon"; | 	or die "Can't start auth daemon"; | ||||||
| 
 | 
 | ||||||
| $t->plan(21); | $t->plan(22); | ||||||
| 
 | 
 | ||||||
| $t->run(); | $t->run(); | ||||||
| 
 | 
 | ||||||
|  | @ -500,10 +527,17 @@ like(http_get_auth('/ref1', 'user4', 'user4secret'), qr!LOGIN PAGE!, | ||||||
| 	'server2 user via referral on server1'); | 	'server2 user via referral on server1'); | ||||||
| 
 | 
 | ||||||
| # unknown user on referred server, result is empty dn | # 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'); | 	'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 { | sub http_get_auth { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue