
    ih'                     B   S SK r S SKrS SKrS SKrS SKJr  S SKJr  S SKJr  S SKJ	r	  S SKJ
r
  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  S SKJr  Sr\R.                  " \5      rSS jrSS jr SS jr " S S\5      r " S S5      r " S S\5      rS r g)    N)urlparse)	Blueprint)current_app)g)request)session)BadData)SignatureExpired)URLSafeTimedSerializer)
BadRequest)ValidationError)CSRF)generate_csrfvalidate_csrfCSRFProtectc                 T   [        U S[        R                  SS9n [        USSSS9nU[        ;  a|  [	        U SS9nU[
        ;  a?  [        R                  " [        R                  " S	5      5      R                  5       [
        U'    UR                  [
        U   5      n[        [        X$5        [        R                  " U5      $ ! [         aZ    [        R                  " [        R                  " S	5      5      R                  5       [
        U'   UR                  [
        U   5      n Nf = f)
a  Generate a CSRF token. The token is cached for a request, so multiple
calls to this function will generate the same token.

During testing, it might be useful to access the signed token in
``g.csrf_token`` and the raw token in ``session['csrf_token']``.

:param secret_key: Used to securely sign the token. Default is
    ``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
:param token_key: Key where token is stored in session for comparison.
    Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.
WTF_CSRF_SECRET_KEY%A secret key is required to use CSRF.messageWTF_CSRF_FIELD_NAME
csrf_token%A field name is required to use CSRF.wtf-csrf-tokensalt@   )_get_configr   
secret_keyr   r   r   hashlibsha1osurandom	hexdigestdumps	TypeErrorsetattrget)r   	token_key
field_namestokens        Q/home/kali/devsecops-assessor/venv/lib/python3.13/site-packages/flask_wtf/csrf.pyr   r      s     7	J 7	J ":4DEW$"),,rzz"~">"H"H"JGJ	1GGGJ/0E
 	:%55  	1"),,rzz"~">"H"H"JGJGGGJ/0E	1s   C A!D'&D'c                    [        US[        R                  SS9n[        USSSS9n[        USSS	S
9nU (       d  [        S5      eU[        ;  a  [        S5      e[        USS9n UR                  XS9n[        R                  " [        U   U5      (       d  [        S5      eg! [         a  n[        S5      UeSnAf[         a  n[        S5      UeSnAff = f)a  Check if the given data is a valid CSRF token. This compares the given
signed token to the one stored in the session.

:param data: The signed CSRF token to be checked.
:param secret_key: Used to securely sign the token. Default is
    ``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
:param time_limit: Number of seconds that the token is valid. Default is
    ``WTF_CSRF_TIME_LIMIT`` or 3600 seconds (60 minutes).
:param token_key: Key where token is stored in session for comparison.
    Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.

:raises ValidationError: Contains the reason that validation failed.

.. versionchanged:: 0.14
    Raises ``ValidationError`` with a specific error message rather than
    returning ``True`` or ``False``.
r   r   r   r   r   r   WTF_CSRF_TIME_LIMIT  F)requiredzThe CSRF token is missing.z"The CSRF session token is missing.r   r   )max_agezThe CSRF token has expired.NzThe CSRF token is invalid.zThe CSRF tokens do not match.)r   r   r   r   r   r   loadsr
   r	   hmaccompare_digest)datar   
time_limitr)   r*   r+   r,   es           r-   r   r   B   s    & 7	J 7	J Z)>uUJ:;; BCCz0@AAC1 wz2E::=>> ;  D;<!C C:;BCs$   %B# #
C-B99CCCc                 t    U c  [         R                  R                  X5      n U(       a  U c  [        U5      eU $ )a  Find config value based on provided value, Flask config, and default
value.

:param value: already provided config value
:param config_name: Flask ``config`` key
:param default: default value if not provided or configured
:param required: whether the value must not be ``None``
:param message: error message if required config is not found
:raises KeyError: if required config is not found
)r   configr(   RuntimeError)valueconfig_namedefaultr1   r   s        r-   r   r   v   s6     }""&&{<EM7##L    c                   4   ^  \ rS rSrU 4S jrS rS rSrU =r$ )_FlaskFormCSRF   c                 D   > UR                   U l         [        TU ]	  U5      $ N)metasuper
setup_form)selfform	__class__s     r-   rG   _FlaskFormCSRF.setup_form   s    II	w!$''r?   c                 f    [        U R                  R                  U R                  R                  S9$ )N)r   r)   )r   rE   csrf_secretcsrf_field_name)rH   csrf_token_fields     r-   generate_csrf_token"_FlaskFormCSRF.generate_csrf_token   s(    yy,,		8Q8Q
 	
r?   c                 R   [         R                  " SS5      (       a  g  [        UR                  U R                  R
                  U R                  R                  U R                  R                  5        g ! [         a(  n[        R                  UR                  S   5        e S nAff = f)N
csrf_validFr   )r   r(   r   r6   rE   rM   csrf_time_limitrN   r   loggerinfoargs)rH   rI   fieldr8   s       r-   validate_csrf_token"_FlaskFormCSRF.validate_csrf_token   sz    55u%%		

		%%		))		))	  	KKq	"	s   AA4 4
B&>#B!!B&)rE   )	__name__
__module____qualname____firstlineno__rG   rP   rY   __static_attributes____classcell__)rJ   s   @r-   rA   rA      s    (

 r?   rA   c                   @    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
rg)r      a;  Enable CSRF protection globally for a Flask app.

::

    app = Flask(__name__)
    csrf = CSRFProtect(app)

Checks the ``csrf_token`` field sent with forms, or the ``X-CSRFToken``
header sent with JavaScript requests. Render the token in templates using
``{{ csrf_token() }}``.

See the :ref:`csrf` documentation.
Nc                 r    [        5       U l        [        5       U l        U(       a  U R                  U5        g g rD   )set_exempt_views_exempt_blueprintsinit_app)rH   apps     r-   __init__CSRFProtect.__init__   s*     U"%%MM# r?   c                 l  ^ ^ T TR                   S'   TR                  R                  SS5        TR                  R                  SS5        [        TR                  R	                  S/ SQ5      5      TR                  S'   TR                  R                  SS5        TR                  R                  S	S
S/5        TR                  R                  SS5        TR                  R                  SS5        [
        TR                  R                  S'   TR                  S 5        TR                  UU 4S j5       ng )NcsrfWTF_CSRF_ENABLEDTWTF_CSRF_CHECK_DEFAULTWTF_CSRF_METHODS)POSTPUTPATCHDELETEr   r   WTF_CSRF_HEADERSzX-CSRFTokenzX-CSRF-Tokenr/   r0   WTF_CSRF_SSL_STRICTc                      S[         0$ )Nr   )r    r?   r-   <lambda>&CSRFProtect.init_app.<locals>.<lambda>   s	    |]&Cr?   c                    > TR                   S   (       d  g TR                   S   (       d  g [        R                  TR                   S   ;  a  g [        R                  (       d  g TR                  R                  [        R                  5      TR                  ;   a  g TR                  R                  [        R                  5      n U R                   SU R                   3nUTR                  ;   a  g TR                  5         g )Nrm   rn   ro   .)r:   r   methodendpoint
blueprintsr(   	blueprintrf   view_functionsr\   r[   re   protect)viewdestrh   rH   s     r-   csrf_protect*CSRFProtect.init_app.<locals>.csrf_protect   s    ::01::67~~SZZ0B%CC##~~!!'"3"348O8OO%%))'*:*:;Doo&a7Dt)))LLNr?   )

extensionsr:   
setdefaultrd   r(   r   	jinja_envglobalscontext_processorbefore_request)rH   rh   r   s   `` r-   rg   CSRFProtect.init_app   s    !%v

0$7

6=),JJNN-/QR*


%& 	

3\B

0=.2QR

3T:

3T:.;l+CD				 
	r?   c                    [         R                  S   n[        R                  R	                  U5      nU(       a  U$ [        R                   H9  nUR                  U5      (       d  M  [        R                  U   nU(       d  M7  Us  $    [         R                  S    H-  n[        R                  R	                  U5      nU(       d  M+  Us  $    g )Nr   rt   )r   r:   r   rI   r(   endswithheaders)rH   r*   
base_tokenkeyr   header_names         r-   _get_csrf_tokenCSRFProtect._get_csrf_token   s     ''(=>
\\%%j1
 <<C||J''$\\#.
:%%   '--.@AK ,,[9Jz!!	 B r?   c                 v   [         R                  [        R                  S   ;  a  g  [	        U R                  5       5        [         R                  (       a  [        R                  S   (       aj  [         R                  (       d  U R                  S5        S[         R                   S3n[        [         R                  U5      (       d  U R                  S5        S[        l        g ! [         aJ  n[        R                  UR                  S   5        U R                  UR                  S   5         S nANS nAff = f)	Nro   r   ru   zThe referrer header is missing.zhttps:///z%The referrer does not match the host.T)r   r|   r   r:   r   r   r   rU   rV   rW   _error_response	is_securereferrerhostsame_originr   rS   )rH   r8   good_referrers      r-   r   CSRFProtect.protect   s    >>!3!34F!GG	,$..01
 !3!34I!J##$$%FG&w||nA6Mw//??$$%LM  	,KKq	"  ++	,s   C$ $
D8.A D33D8c                    [        U[        5      (       a  U R                  R                  U5        U$ [        U[        5      (       a  UnO'SR                  UR                  UR                  45      nU R                  R                  U5        U$ )zMark a view or blueprint to be excluded from CSRF protection.

::

    @app.route('/some-view', methods=['POST'])
    @csrf.exempt
    def some_view():
        ...

::

    bp = Blueprint(...)
    csrf.exempt(bp)

r{   )	
isinstancer   rf   addstrjoinr\   r[   re   )rH   r   view_locations      r-   exemptCSRFProtect.exempt  sp    " dI&&##''-KdC   MHHdoot}}%EFM}-r?   c                     [        U5      erD   )	CSRFError)rH   reasons     r-   r   CSRFProtect._error_response2  s    r?   )rf   re   rD   )r[   r\   r]   r^   __doc__ri   rg   r   r   r   r   r_   rw   r?   r-   r   r      s&    'R2*: r?   r   c                       \ rS rSrSrSrSrg)r   i6  zRaise if the client sends invalid CSRF data with the request.

Generates a 400 Bad Request response with the failure reason by default.
Customize the response by registering a handler with
:meth:`flask.Flask.errorhandler`.
zCSRF validation failed.rw   N)r[   r\   r]   r^   r   descriptionr_   rw   r?   r-   r   r   6  s     ,Kr?   r   c                     [        U 5      n[        U5      nUR                  UR                  :H  =(       a9    UR                  UR                  :H  =(       a    UR                  UR                  :H  $ rD   )r   schemehostnameport)current_uricompare_uricurrentcompares       r-   r   r   A  s[    {#G{#G 	'..( 	) 0 00	)LLGLL(r?   )NN)NNN)NTzCSRF is not configured.)!r    r4   loggingr"   urllib.parser   flaskr   r   r   r   r   itsdangerousr	   r
   r   werkzeug.exceptionsr   wtformsr   wtforms.csrf.corer   __all__	getLoggerr[   rU   r   r   r   rA   r   r   r   rw   r?   r-   <module>r      s       	 !        ) / * # "
;			8	$(V1?j >W.T 6K  K \,
 ,r?   