Skip to content

Commit ce946ef

Browse files
author
Maria Korlotian
authored
Update allowlist and readme (#70)
* Rename blacklist to denylist and whitelist to allowlist
1 parent 0b1653e commit ce946ef

File tree

7 files changed

+84
-65
lines changed

7 files changed

+84
-65
lines changed
File renamed without changes.

README.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import and configure the library with your Castle API secret.
2121

2222
.. code:: python
2323
24-
from castle.configuration import configuration, WHITELISTED
24+
from castle.configuration import configuration, DEFAULT_ALLOWLIST
2525
2626
# Same as setting it through Castle.api_secret
2727
configuration.api_secret = ':YOUR-API-SECRET'
@@ -32,16 +32,17 @@ import and configure the library with your Castle API secret.
3232
# Castle::RequestError is raised when timing out in milliseconds (default: 500 milliseconds)
3333
configuration.request_timeout = 1000
3434
35-
# Whitelisted and Blacklisted headers are case insensitive and allow to use _ and - as a separator, http prefixes are removed
35+
# Allowlisted and Denylisted headers are case insensitive
36+
# and allow to use _ and - as a separator, http prefixes are removed
3637
# By default all headers are passed, but some are automatically scrubbed.
37-
# If you need to apply a whitelist, we recommend using the minimum set of
38-
# standard headers that we've exposed in the `WHITELISTED` constant.
39-
# Whitelisted headers
40-
configuration.whitelisted = WHITELISTED + ['X_HEADER']
38+
# If you need to apply an allowlist, we recommend using the minimum set of
39+
# standard headers that we've exposed in the `DEFAULT_ALLOWLIST` constant.
40+
# Allowlisted headers
41+
configuration.allowlisted = DEFAULT_ALLOWLIST + ['X_HEADER']
4142
42-
# Blacklisted headers take advantage over whitelisted elements. Note that
43+
# Denylisted headers take advantage over allowlisted elements. Note that
4344
# some headers are always scrubbed, for security reasons.
44-
configuration.blacklisted = ['HTTP-X-header']
45+
configuration.denylisted = ['HTTP-X-header']
4546
4647
# Castle needs the original IP of the client, not the IP of your proxy or load balancer.
4748
# The SDK will only trust the proxy chain as defined in the configuration.

castle/configuration.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from castle.exceptions import ConfigurationError
22
from castle.headers_formatter import HeadersFormatter
33

4-
DEFAULT_WHITELIST = [
4+
DEFAULT_ALLOWLIST = [
55
"Accept",
66
"Accept-Charset",
77
"Accept-Datetime",
@@ -11,11 +11,15 @@
1111
"Connection",
1212
"Content-Length",
1313
"Content-Type",
14-
"Cookie",
14+
"Dnt",
1515
"Host",
1616
"Origin",
1717
"Pragma",
1818
"Referer",
19+
"Sec-Fetch-Dest",
20+
"Sec-Fetch-Mode",
21+
"Sec-Fetch-Site",
22+
"Sec-Fetch-User",
1923
"TE",
2024
"Upgrade-Insecure-Requests",
2125
"User-Agent",
@@ -44,8 +48,8 @@ def __init__(self):
4448
self.host = HOST
4549
self.port = PORT
4650
self.url_prefix = URL_PREFIX
47-
self.whitelisted = []
48-
self.blacklisted = []
51+
self.allowlisted = []
52+
self.denylisted = []
4953
self.request_timeout = REQUEST_TIMEOUT
5054
self.failover_strategy = FAILOVER_STRATEGY
5155
self.ip_headers = []
@@ -89,26 +93,26 @@ def url_prefix(self, value):
8993
self.__url_prefix = value
9094

9195
@property
92-
def whitelisted(self):
93-
return self.__whitelisted
96+
def allowlisted(self):
97+
return self.__allowlisted
9498

95-
@whitelisted.setter
96-
def whitelisted(self, value):
99+
@allowlisted.setter
100+
def allowlisted(self, value):
97101
if value:
98-
self.__whitelisted = [HeadersFormatter.call(v) for v in value]
102+
self.__allowlisted = [HeadersFormatter.call(v) for v in value]
99103
else:
100-
self.__whitelisted = []
104+
self.__allowlisted = []
101105

102106
@property
103-
def blacklisted(self):
104-
return self.__blacklisted
107+
def denylisted(self):
108+
return self.__denylisted
105109

106-
@blacklisted.setter
107-
def blacklisted(self, value):
110+
@denylisted.setter
111+
def denylisted(self, value):
108112
if value:
109-
self.__blacklisted = [HeadersFormatter.call(v) for v in value]
113+
self.__denylisted = [HeadersFormatter.call(v) for v in value]
110114
else:
111-
self.__blacklisted = []
115+
self.__denylisted = []
112116

113117
@property
114118
def request_timeout(self):
@@ -173,5 +177,6 @@ def trusted_proxy_depth(self, value):
173177
else:
174178
raise ConfigurationError
175179

180+
176181
# pylint: disable=invalid-name
177182
configuration = Configuration()

castle/extractors/headers.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
from castle.configuration import configuration
22

3-
ALWAYS_BLACKLISTED = ['Cookie', 'Authorization']
4-
ALWAYS_WHITELISTED = ['User-Agent']
3+
ALWAYS_DENYLISTED = ['Cookie', 'Authorization']
4+
ALWAYS_ALLOWLISTED = ['User-Agent']
55

66

77
class ExtractorsHeaders(object):
88
def __init__(self, headers):
99
self.headers = headers
10-
self.no_whitelist = len(configuration.whitelisted) == 0
10+
self.no_whitelist = len(configuration.allowlisted) == 0
1111

1212
def call(self):
1313
result = dict()
@@ -18,13 +18,13 @@ def call(self):
1818
return result
1919

2020
def _header_value(self, name, value):
21-
if name in ALWAYS_BLACKLISTED:
21+
if name in ALWAYS_DENYLISTED:
2222
return True
23-
if name in ALWAYS_WHITELISTED:
23+
if name in ALWAYS_ALLOWLISTED:
2424
return value
25-
if name in configuration.blacklisted:
25+
if name in configuration.denylisted:
2626
return True
27-
if self.no_whitelist or (name in configuration.whitelisted):
27+
if self.no_whitelist or (name in configuration.allowlisted):
2828
return value
2929

3030
return True

castle/extractors/ip.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# list of header which are used with proxy depth setting
88
DEPTH_RELATED = ['X-Forwarded-For']
99

10+
1011
class ExtractorsIp(object):
1112
def __init__(self, headers):
1213
self.headers = headers

castle/test/configuration_test.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ def test_default_values(self):
1010
self.assertEqual(config.host, 'api.castle.io')
1111
self.assertEqual(config.port, 443)
1212
self.assertEqual(config.url_prefix, '/v1')
13-
self.assertEqual(config.whitelisted, [])
14-
self.assertEqual(config.blacklisted, [])
13+
self.assertEqual(config.allowlisted, [])
14+
self.assertEqual(config.denylisted, [])
1515
self.assertEqual(config.request_timeout, 500)
1616
self.assertEqual(config.failover_strategy, 'allow')
1717
self.assertEqual(config.ip_headers, [])
@@ -37,35 +37,35 @@ def test_url_prefix_setter(self):
3737
config.url_prefix = '/v2'
3838
self.assertEqual(config.url_prefix, '/v2')
3939

40-
def test_whitelisted_setter_list(self):
40+
def test_allowlisted_setter_list(self):
4141
config = Configuration()
42-
config.whitelisted = ['test']
43-
self.assertEqual(config.whitelisted, ['Test'])
42+
config.allowlisted = ['test']
43+
self.assertEqual(config.allowlisted, ['Test'])
4444

45-
def test_whitelisted_setter_none(self):
45+
def test_allowlisted_setter_none(self):
4646
config = Configuration()
47-
config.whitelisted = None
48-
self.assertEqual(config.whitelisted, [])
47+
config.allowlisted = None
48+
self.assertEqual(config.allowlisted, [])
4949

50-
def test_whitelisted_setter_empty(self):
50+
def test_allowlisted_setter_empty(self):
5151
config = Configuration()
52-
config.whitelisted = ''
53-
self.assertEqual(config.whitelisted, [])
52+
config.allowlisted = ''
53+
self.assertEqual(config.allowlisted, [])
5454

55-
def test_blacklisted_setter_list(self):
55+
def test_denylisted_setter_list(self):
5656
config = Configuration()
57-
config.blacklisted = ['test']
58-
self.assertEqual(config.blacklisted, ['Test'])
57+
config.denylisted = ['test']
58+
self.assertEqual(config.denylisted, ['Test'])
5959

60-
def test_blacklisted_setter_none(self):
60+
def test_denylisted_setter_none(self):
6161
config = Configuration()
62-
config.blacklisted = None
63-
self.assertEqual(config.blacklisted, [])
62+
config.denylisted = None
63+
self.assertEqual(config.denylisted, [])
6464

65-
def test_blacklisted_setter_empty(self):
65+
def test_denylisted_setter_empty(self):
6666
config = Configuration()
67-
config.blacklisted = ''
68-
self.assertEqual(config.blacklisted, [])
67+
config.denylisted = ''
68+
self.assertEqual(config.denylisted, [])
6969

7070
def test_request_timeout_setter(self):
7171
config = Configuration()

castle/test/extractors/headers_test.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from castle.test import unittest
2-
from castle.configuration import configuration
2+
from castle.configuration import configuration, DEFAULT_ALLOWLIST
33
from castle.extractors.headers import ExtractorsHeaders
44

55

@@ -18,8 +18,8 @@ def formatted_headers():
1818
class ExtractorsHeadersTestCase(unittest.TestCase):
1919

2020
def tearDown(self):
21-
configuration.whitelisted = []
22-
configuration.blacklisted = []
21+
configuration.allowlisted = []
22+
configuration.denylisted = []
2323

2424
def test_extract_headers(self):
2525
self.assertEqual(ExtractorsHeaders(formatted_headers()).call(),
@@ -32,8 +32,8 @@ def test_extract_headers(self):
3232
'X-Forwarded-For': '1.2.3.4'
3333
})
3434

35-
def test_whitelisted_headers(self):
36-
configuration.whitelisted = ['Accept', 'OK']
35+
def test_allowlisted_headers(self):
36+
configuration.allowlisted = ['Accept', 'OK']
3737
self.assertEqual(
3838
ExtractorsHeaders(formatted_headers()).call(),
3939
{'Accept': 'application/json',
@@ -45,10 +45,23 @@ def test_whitelisted_headers(self):
4545
'X-Forwarded-For': True
4646
}
4747
)
48-
#
4948

50-
def test_restricted_blacklisted_headers(self):
51-
configuration.blacklisted = ['User-Agent']
49+
def test_only_default_allowlisted_headers(self):
50+
configuration.allowlisted = DEFAULT_ALLOWLIST
51+
self.assertEqual(
52+
ExtractorsHeaders(formatted_headers()).call(),
53+
{'Accept': 'application/json',
54+
'Authorization': True,
55+
'Cookie': True,
56+
'Ok': True,
57+
'Content-Length': '0',
58+
'User-Agent': 'Mozilla 1234',
59+
'X-Forwarded-For': True
60+
}
61+
)
62+
63+
def test_restricted_denylisted_headers(self):
64+
configuration.denylisted = ['User-Agent']
5265
self.assertEqual(
5366
ExtractorsHeaders(formatted_headers()).call(),
5467
{'Accept': 'application/json',
@@ -61,8 +74,8 @@ def test_restricted_blacklisted_headers(self):
6174
}
6275
)
6376

64-
def test_blacklisted_headers(self):
65-
configuration.blacklisted = ['Accept']
77+
def test_denylisted_headers(self):
78+
configuration.denylisted = ['Accept']
6679
self.assertEqual(
6780
ExtractorsHeaders(formatted_headers()).call(),
6881
{'Accept': True,
@@ -74,11 +87,10 @@ def test_blacklisted_headers(self):
7487
'X-Forwarded-For': '1.2.3.4'
7588
}
7689
)
77-
#
7890

79-
def test_blacklisted_and_whitelisted_headers(self):
80-
configuration.blacklisted = ['Accept']
81-
configuration.whitelisted = ['Accept']
91+
def test_denylisted_and_allowlisted_headers(self):
92+
configuration.denylisted = ['Accept']
93+
configuration.allowlisted = ['Accept']
8294
self.assertEqual(
8395
ExtractorsHeaders(formatted_headers()).call()['Accept'], True
8496
)

0 commit comments

Comments
 (0)