|
1 | 1 | from plain.exceptions import ImproperlyConfigured |
2 | 2 | from plain.runtime import settings |
3 | 3 |
|
4 | | -from .. import Error, Warning, register |
5 | | - |
6 | | -CROSS_ORIGIN_OPENER_POLICY_VALUES = { |
7 | | - "same-origin", |
8 | | - "same-origin-allow-popups", |
9 | | - "unsafe-none", |
10 | | -} |
11 | | -REFERRER_POLICY_VALUES = { |
12 | | - "no-referrer", |
13 | | - "no-referrer-when-downgrade", |
14 | | - "origin", |
15 | | - "origin-when-cross-origin", |
16 | | - "same-origin", |
17 | | - "strict-origin", |
18 | | - "strict-origin-when-cross-origin", |
19 | | - "unsafe-url", |
20 | | -} |
| 4 | +from .. import Warning, register |
21 | 5 |
|
22 | 6 | SECRET_KEY_INSECURE_PREFIX = "plain-insecure-" |
23 | 7 | SECRET_KEY_MIN_LENGTH = 50 |
|
41 | 25 | id="security.W001", |
42 | 26 | ) |
43 | 27 |
|
44 | | -W002 = Warning( |
45 | | - "You do not have " |
46 | | - "'plain.middleware.clickjacking.XFrameOptionsMiddleware' in your " |
47 | | - "MIDDLEWARE, so your pages will not be served with an " |
48 | | - "'x-frame-options' header. Unless there is a good reason for your " |
49 | | - "site to be served in a frame, you should consider enabling this " |
50 | | - "header to help prevent clickjacking attacks.", |
51 | | - id="security.W002", |
52 | | -) |
53 | | - |
54 | | -W004 = Warning( |
55 | | - "You have not set a value for the SECURE_HSTS_SECONDS setting. " |
56 | | - "If your entire site is served only over SSL, you may want to consider " |
57 | | - "setting a value and enabling HTTP Strict Transport Security. " |
58 | | - "Be sure to read the documentation first; enabling HSTS carelessly " |
59 | | - "can cause serious, irreversible problems.", |
60 | | - id="security.W004", |
61 | | -) |
62 | | - |
63 | | -W005 = Warning( |
64 | | - "You have not set the SECURE_HSTS_INCLUDE_SUBDOMAINS setting to True. " |
65 | | - "Without this, your site is potentially vulnerable to attack " |
66 | | - "via an insecure connection to a subdomain. Only set this to True if " |
67 | | - "you are certain that all subdomains of your domain should be served " |
68 | | - "exclusively via SSL.", |
69 | | - id="security.W005", |
70 | | -) |
71 | | - |
72 | | -W006 = Warning( |
73 | | - "Your SECURE_CONTENT_TYPE_NOSNIFF setting is not set to True, " |
74 | | - "so your pages will not be served with an " |
75 | | - "'X-Content-Type-Options: nosniff' header. " |
76 | | - "You should consider enabling this header to prevent the " |
77 | | - "browser from identifying content types incorrectly.", |
78 | | - id="security.W006", |
79 | | -) |
80 | | - |
81 | 28 | W008 = Warning( |
82 | 29 | "Your SECURE_SSL_REDIRECT setting is not set to True. " |
83 | 30 | "Unless your site should be available over both SSL and non-SSL " |
|
102 | 49 | id="security.W020", |
103 | 50 | ) |
104 | 51 |
|
105 | | -W021 = Warning( |
106 | | - "You have not set the SECURE_HSTS_PRELOAD setting to True. Without this, " |
107 | | - "your site cannot be submitted to the browser preload list.", |
108 | | - id="security.W021", |
109 | | -) |
110 | | - |
111 | | -W022 = Warning( |
112 | | - "You have not set the SECURE_REFERRER_POLICY setting. Without this, your " |
113 | | - "site will not send a Referrer-Policy header. You should consider " |
114 | | - "enabling this header to protect user privacy.", |
115 | | - id="security.W022", |
116 | | -) |
117 | | - |
118 | | -E023 = Error( |
119 | | - "You have set the SECURE_REFERRER_POLICY setting to an invalid value.", |
120 | | - hint="Valid values are: {}.".format(", ".join(sorted(REFERRER_POLICY_VALUES))), |
121 | | - id="security.E023", |
122 | | -) |
123 | | - |
124 | | -E024 = Error( |
125 | | - "You have set the SECURE_CROSS_ORIGIN_OPENER_POLICY setting to an invalid " |
126 | | - "value.", |
127 | | - hint="Valid values are: {}.".format( |
128 | | - ", ".join(sorted(CROSS_ORIGIN_OPENER_POLICY_VALUES)), |
129 | | - ), |
130 | | - id="security.E024", |
131 | | -) |
132 | | - |
133 | 52 | W025 = Warning(SECRET_KEY_WARNING_MSG, id="security.W025") |
134 | 53 |
|
135 | 54 |
|
136 | 55 | def _security_middleware(): |
137 | 56 | return "plain.middleware.security.SecurityMiddleware" in settings.MIDDLEWARE |
138 | 57 |
|
139 | 58 |
|
140 | | -def _xframe_middleware(): |
141 | | - return ( |
142 | | - "plain.middleware.clickjacking.XFrameOptionsMiddleware" in settings.MIDDLEWARE |
143 | | - ) |
144 | | - |
145 | | - |
146 | 59 | @register(deploy=True) |
147 | 60 | def check_security_middleware(package_configs, **kwargs): |
148 | 61 | passed_check = _security_middleware() |
149 | 62 | return [] if passed_check else [W001] |
150 | 63 |
|
151 | 64 |
|
152 | | -@register(deploy=True) |
153 | | -def check_xframe_options_middleware(package_configs, **kwargs): |
154 | | - passed_check = _xframe_middleware() |
155 | | - return [] if passed_check else [W002] |
156 | | - |
157 | | - |
158 | | -@register(deploy=True) |
159 | | -def check_sts(package_configs, **kwargs): |
160 | | - passed_check = not _security_middleware() or settings.SECURE_HSTS_SECONDS |
161 | | - return [] if passed_check else [W004] |
162 | | - |
163 | | - |
164 | | -@register(deploy=True) |
165 | | -def check_sts_include_subdomains(package_configs, **kwargs): |
166 | | - passed_check = ( |
167 | | - not _security_middleware() |
168 | | - or not settings.SECURE_HSTS_SECONDS |
169 | | - or settings.SECURE_HSTS_INCLUDE_SUBDOMAINS is True |
170 | | - ) |
171 | | - return [] if passed_check else [W005] |
172 | | - |
173 | | - |
174 | | -@register(deploy=True) |
175 | | -def check_sts_preload(package_configs, **kwargs): |
176 | | - passed_check = ( |
177 | | - not _security_middleware() |
178 | | - or not settings.SECURE_HSTS_SECONDS |
179 | | - or settings.SECURE_HSTS_PRELOAD is True |
180 | | - ) |
181 | | - return [] if passed_check else [W021] |
182 | | - |
183 | | - |
184 | | -@register(deploy=True) |
185 | | -def check_content_type_nosniff(package_configs, **kwargs): |
186 | | - passed_check = ( |
187 | | - not _security_middleware() or settings.SECURE_CONTENT_TYPE_NOSNIFF is True |
188 | | - ) |
189 | | - return [] if passed_check else [W006] |
190 | | - |
191 | | - |
192 | 65 | @register(deploy=True) |
193 | 66 | def check_ssl_redirect(package_configs, **kwargs): |
194 | 67 | passed_check = not _security_middleware() or settings.SECURE_SSL_REDIRECT is True |
@@ -239,30 +112,3 @@ def check_debug(package_configs, **kwargs): |
239 | 112 | @register(deploy=True) |
240 | 113 | def check_allowed_hosts(package_configs, **kwargs): |
241 | 114 | return [] if settings.ALLOWED_HOSTS else [W020] |
242 | | - |
243 | | - |
244 | | -@register(deploy=True) |
245 | | -def check_referrer_policy(package_configs, **kwargs): |
246 | | - if _security_middleware(): |
247 | | - if settings.SECURE_REFERRER_POLICY is None: |
248 | | - return [W022] |
249 | | - # Support a comma-separated string or iterable of values to allow fallback. |
250 | | - if isinstance(settings.SECURE_REFERRER_POLICY, str): |
251 | | - values = {v.strip() for v in settings.SECURE_REFERRER_POLICY.split(",")} |
252 | | - else: |
253 | | - values = set(settings.SECURE_REFERRER_POLICY) |
254 | | - if not values <= REFERRER_POLICY_VALUES: |
255 | | - return [E023] |
256 | | - return [] |
257 | | - |
258 | | - |
259 | | -@register(deploy=True) |
260 | | -def check_cross_origin_opener_policy(package_configs, **kwargs): |
261 | | - if ( |
262 | | - _security_middleware() |
263 | | - and settings.SECURE_CROSS_ORIGIN_OPENER_POLICY is not None |
264 | | - and settings.SECURE_CROSS_ORIGIN_OPENER_POLICY |
265 | | - not in CROSS_ORIGIN_OPENER_POLICY_VALUES |
266 | | - ): |
267 | | - return [E024] |
268 | | - return [] |
0 commit comments