Skip to content
Snippets Groups Projects
Unverified Commit 2ef1e5ca authored by Liam Crilly's avatar Liam Crilly Committed by GitHub
Browse files

Merge pull request #96 from tippexs/master

Escape Username in LDAP search filters 
parents 763f23b2 e00e31d9
No related branches found
No related tags found
No related merge requests found
.env
htmlcov
...@@ -2,9 +2,16 @@ ...@@ -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) ...@@ -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): ...@@ -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
......
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 { ...@@ -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 { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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"); ...@@ -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!, ...@@ -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 {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment