The XSRF-prevention token for the current user/session. To prevent cross-site request forgery, we set an '_xsrf' cookie and include the same '_xsrf' value as an argument with all POST requests. If the two do not match, we reject the form submission as a potential for
(self)
| 1374 | |
| 1375 | @property |
| 1376 | def xsrf_token(self) -> bytes: |
| 1377 | """The XSRF-prevention token for the current user/session. |
| 1378 | |
| 1379 | To prevent cross-site request forgery, we set an '_xsrf' cookie |
| 1380 | and include the same '_xsrf' value as an argument with all POST |
| 1381 | requests. If the two do not match, we reject the form submission |
| 1382 | as a potential forgery. |
| 1383 | |
| 1384 | See http://en.wikipedia.org/wiki/Cross-site_request_forgery |
| 1385 | |
| 1386 | This property is of type `bytes`, but it contains only ASCII |
| 1387 | characters. If a character string is required, there is no |
| 1388 | need to base64-encode it; just decode the byte string as |
| 1389 | UTF-8. |
| 1390 | |
| 1391 | .. versionchanged:: 3.2.2 |
| 1392 | The xsrf token will now be have a random mask applied in every |
| 1393 | request, which makes it safe to include the token in pages |
| 1394 | that are compressed. See http://breachattack.com for more |
| 1395 | information on the issue fixed by this change. Old (version 1) |
| 1396 | cookies will be converted to version 2 when this method is called |
| 1397 | unless the ``xsrf_cookie_version`` `Application` setting is |
| 1398 | set to 1. |
| 1399 | |
| 1400 | .. versionchanged:: 4.3 |
| 1401 | The ``xsrf_cookie_kwargs`` `Application` setting may be |
| 1402 | used to supply additional cookie options (which will be |
| 1403 | passed directly to `set_cookie`). For example, |
| 1404 | ``xsrf_cookie_kwargs=dict(httponly=True, secure=True)`` |
| 1405 | will set the ``secure`` and ``httponly`` flags on the |
| 1406 | ``_xsrf`` cookie. |
| 1407 | """ |
| 1408 | if not hasattr(self, "_xsrf_token"): |
| 1409 | version, token, timestamp = self._get_raw_xsrf_token() |
| 1410 | output_version = self.settings.get("xsrf_cookie_version", 2) |
| 1411 | cookie_kwargs = self.settings.get("xsrf_cookie_kwargs", {}) |
| 1412 | if output_version == 1: |
| 1413 | self._xsrf_token = binascii.b2a_hex(token) |
| 1414 | elif output_version == 2: |
| 1415 | mask = os.urandom(4) |
| 1416 | self._xsrf_token = b"|".join( |
| 1417 | [ |
| 1418 | b"2", |
| 1419 | binascii.b2a_hex(mask), |
| 1420 | binascii.b2a_hex(_websocket_mask(mask, token)), |
| 1421 | utf8(str(int(timestamp))), |
| 1422 | ] |
| 1423 | ) |
| 1424 | else: |
| 1425 | raise ValueError("unknown xsrf cookie version %d", output_version) |
| 1426 | if version is None: |
| 1427 | if self.current_user and "expires_days" not in cookie_kwargs: |
| 1428 | cookie_kwargs["expires_days"] = 30 |
| 1429 | self.set_cookie("_xsrf", self._xsrf_token, **cookie_kwargs) |
| 1430 | return self._xsrf_token |
| 1431 | |
| 1432 | def _get_raw_xsrf_token(self) -> Tuple[Optional[int], bytes, float]: |
| 1433 | """Read or generate the xsrf token in its raw form. |
nothing calls this directly
no test coverage detected