-
Notifications
You must be signed in to change notification settings - Fork 5
/
credentialfilter
executable file
·168 lines (152 loc) · 6.26 KB
/
credentialfilter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/bin/env python3
# -*- coding: utf-8 -*-
"""credential_filter - standalone script for calling credentialfilter.py
"""
##
## credential_filter
##
## Stand-alone script for using the credentialfilter.py module from
## non python scripts that do proxy requests on behalf of a user.
##
## Author: J. Kahan (6/August/2024)
##
##################################################################
##
## The behavior of the credentialfilter module depends on the info
## stored in an associated configuration file. The configuration file
## states which hosts are considered trusted, which domains are
## considered safe, as well as which cookie names are considered
## trusted and which ones safe. Please check
## credential_filter.conf.dist for a sample file.
##
## The default location for the configuration file is
## /usr/local/etc/credential_filter.conf. A script argument lets you
## choose an alternate location of the configuration file.
##
## credential_filter -host target_hostname | -url target_url
## [-cookies HTTP Cookie header value]
## [-config alternate_path_to_the_configuration_file]
##
## Either -host or -url should be used to tell the script what is
## the target_host the caller script wants to access. If both
## parameters are given, -url will take precedence over -host
##
## If -cookies is not used, the script will only return the trust
## level for the target host by means of the exit code (see here below).
##
## If --cookies is used, the script may return a number of lines that
## are equivalent to HTTP Set-Cookie header values that can be used to
## fill up a temporary cookie jar associated with the caller script.
## These lines are generated by combining the target host trust level
## with the trust level of the cookies.
##
## The script recognizes three trust levels for a target host:
##
## - Trusted: the target host can receive security credentials (like
## Basic Auth) and sensitive cookies.
##
## - Safe: the target host can only receive non sensitive cookies.
## It should not receive any security credentials.
##
## - Unsafe: the target host can't receive any security information or
## any kind of cookie.
##
## All target hosts that are considered trusted are also considered
## safe and will also receive all the cookies available for safe
## target hosts.
##
## The configuration file states which cookies names are considered
## trusted, which cookie names are considered safe, as well as which
## hosts are considered trusted and safe. See credential_filter.conf.dist
## for a sample configuration file.
##
## For trusted target hosts, for each trusted cookie (according to the
## configuration file), the script will generate one output line,
## equivalent to the value of an HTTP Set-Cookie header, using the
## trusted cookie name and value, the target host as domain. and path '/'.
## In addition, if thetrusted
## target
##
## The script returns the trust level for the target code using the
## scripts' exit code:
##
## - if the script returns 2, a host is considered trusted to accept
## security credentials (basic auth, sensitive cookies)
##
## - if the script returns 1, a host is considered safe, that is it can't
## receive security credentials, but can receive some cookies
## (according to the configuration)
##
## - if the script returns 0, a host is considered unsafe, that is, it
## shouldn't receive any cookies
##
## - in case of errors, the script will abort and return -1 (255)
##
## The script will take care of filtering out the cookies according to the
## hosts trust level.
#3
## It is the responsibility of the caller script to use the returned
## target_host trust level to decide on whether it should forward any
## Basic Authentication or other sensitive headers to a target host.
##
import os.path
import sys
import argparse
from urllib.error import URLError
from urllib.parse import urlparse
from credentialfilter import CredentialFilter, HostTrustLevels
def print_cookies(filtered_cookies=None):
for cookie in filtered_cookies:
print(f'{cookie}')
def main():
parser = argparse.ArgumentParser(description='Returns the trust level of a target host as well as a list of cookies that can be forwarded to that host')
parser.add_argument('-u', '--url', type=str, required=False,
help='url pointing to target host', default=None)
parser.add_argument('-th', '--host', type=str, required=False,
help="FQDN of the target", default=None)
parser.add_argument('-c', '--cookies', type=str, required=False,
help='value of HTTP cookie header that script wants to filter',
default=None)
parser.add_argument('-l', '--list-trusted', action='store_true')
parser.add_argument('-cf', '--conf', type=str, required=False,
help='path to a non-default configuration file for the credentialfilter module',
default=None)
args = parser.parse_args()
target_url = args.url
target_host = args.host
cookies = args.cookies
config_file = args.conf
do_list = args.list_trusted
if target_url is None and target_host is None and not do_list:
print(f"You didn't use either -u or -h or -l",
file=sys.stderr)
parser.print_help()
sys.exit(-1)
if config_file and not os.path.isfile(config_file):
print(f"configuration file {config_file} doesn't exist or is unreadable",
file=sys.stderr)
parser.print_help()
sys.exit(-1)
try:
cf = CredentialFilter(config_file)
if do_list:
for trusted_host in cf.get_trusted_hosts():
print(f'{trusted_host}')
rv = 0
elif cookies:
trust_level, filtered_cookies = cf.credential_filter(
cookies = cookies,
url = target_url,
target_host = target_host)
if filtered_cookies:
print_cookies(filtered_cookies)
rv = trust_level
else:
trust_level = cf.host_trust_level(url=target_url,
target_host = target_host)
rv = trust_level
except:
rv = -1
sys.exit(rv)
if __name__ == "__main__":
main()