o
    i=                     @   s  d dl Z d dlmZ d dlZd dlZd dlZd dlmZ d dlmZ d dl	Z	d dl
mZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ eeZeh dZ eeegZ!dZ"dee# dee# fddZ$G dd dZ%e j&ddG dd de%Z'e j&ddG dd dZ(e j&ddG dd  d Z)e j&G d!d" d"e%Z*e j&G d#d$ d$e%Z+dS )%    N)reduce)Any)Optional)STACK_TRACE)report_stack)sensitive_handler)is_iast_request_enabled)_get_source_index)VULN_INSECURE_HASHING_TYPE)VULN_WEAK_CIPHER_TYPE)VULN_WEAK_RANDOMNESS)
get_logger)config>   _rangesdialect_evidences_with_no_sources   valuereturnc                 C   s.   | du rdS t j}t| |kr| d| S | S )z5Truncate evidence value if it exceeds the max length.N)
asm_config!_iast_truncation_max_value_lengthlen)r   
max_length r   Q/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/appsec/_iast/reporter.py_truncate_evidence_value   s   r   c                   @   s   e Zd Zdd ZdS )NotNoneDictablec                 C   s   t j| dd dS )Nc                 S   s   dd | D S )Nc                 S   s&   i | ]\}}|d ur|t vr||qS N)ATTRS_TO_SKIP).0kvr   r   r   
<dictcomp>-   s   & z>NotNoneDictable._to_dict.<locals>.<lambda>.<locals>.<dictcomp>r   )xr   r   r   <lambda>-   s    z*NotNoneDictable._to_dict.<locals>.<lambda>)dict_factory)dataclassesasdictselfr   r   r   _to_dict*   s   zNotNoneDictable._to_dictN)__name__
__module____qualname__r*   r   r   r   r   r   )   s    r   F)eqc                   @   sn   e Zd ZU dZee ed< dZee ed< ej	e
dZe
e ed< dZee
 ed< dd Zd	d
 Zdd ZdS )EvidenceNr   r   default_factoryr   
valuePartsc                 C   sB   | j sd S d}| j D ]}tj|dd}t| }||N }q
|S )Nr   T)	sort_keys)r2   jsondumpszlibcrc32encode)r)   _hashpartjson_str	part_hashr   r   r   _valueParts_hash8   s   

zEvidence._valueParts_hashc                 C   s   t | j|  fS r   )hashr   r=   r(   r   r   r   __hash__D   s   zEvidence.__hash__c                 C   s   | j |j ko|  | kS r   )r   r=   )r)   otherr   r   r   __eq__G   s   zEvidence.__eq__)r+   r,   r-   r   r   str__annotations__r   r&   fieldlistr   dictr2   r=   r?   rA   r   r   r   r   r/   1   s   
 r/   T)unsafe_hashc                   @   s   e Zd ZU ejddddZeed< ejdddZe	e ed< dZ
e	e ed< dZe	e ed< ejdddd	d
Ze	e ed< ejdddd	d
Ze	e ed< dd Zdd Zdd ZdS )LocationF)comparer>   reprspanId)initrI   stackIdNpathline )rI   r>   rJ   defaultmethod
class_namec                 C      t t|  | _d S r   r6   r7   rJ   r8   r>   r(   r   r   r   __post_init__T      zLocation.__post_init__c                 C      d| j  d| j dS )NzLocation(path='z', line=))rN   rO   r(   r   r   r   __repr__W      zLocation.__repr__c                 C   st   i }| j d ur| j |d< | jr| j|d< | jd ur| j|d< | jr&| j|d< | jr.| j|d< | jr8t| j|d< |S )NrK   rN   rO   rR   classrM   )rK   rN   rO   rR   rS   rM   rB   )r)   resultr   r   r   r*   Z   s   






zLocation._to_dict)r+   r,   r-   r&   rD   rK   intrC   rM   r   rN   rB   rO   rR   rS   rV   rZ   r*   r   r   r   r   rH   K   s   
 rH   c                   @   s^   e Zd ZU eed< eed< eed< ejddde	j
v ddZeed< dd	 Zd
d Zdd ZdS )VulnerabilitytypeevidencelocationFPYTEST_CURRENT_TEST)rL   rI   r>   rJ   r>   c                 C   rT   r   rU   r(   r   r   r   rV   r   rW   zVulnerability.__post_init__c                 C   rX   )NzVulnerability(type='z', location=rY   )r`   rb   r(   r   r   r   rZ   u   r[   zVulnerability.__repr__c                 C   s"   | j | j | j | jd}|S )N)r`   ra   rb   r>   )r`   ra   r*   rb   r>   )r)   to_dictr   r   r   r*   x   s   zVulnerability._to_dictN)r+   r,   r-   rB   rC   r/   rH   r&   rD   osenvironr>   r^   rV   rZ   r*   r   r   r   r   r_   k   s   
  r_   c                   @   st   e Zd ZU eed< eed< ejdddZee	 ed< ejdddZ
ee ed< ejdddZee ed< d	d
 ZdS )SourceoriginnameNF)rQ   rJ   redactedr   patternc                 C   s   t | j| jfS )a`  origin & name serve as hashes. This approach aims to mitigate false positives when searching for
        identical sources in a list, especially when sources undergo changes. The provided example illustrates how
        two sources with different attributes could actually represent the same source. For example:
        Source(origin=<OriginType.PARAMETER: 0>, name='string1', redacted=False, value="password", pattern=None)
        could be the same source as the one below:
        Source(origin=<OriginType.PARAMETER: 0>, name='string1', redacted=True, value=None, pattern='ab')
        :return:
        )r>   rh   ri   r(   r   r   r   r?      s   	zSource.__hash__)r+   r,   r-   rB   rC   r&   rD   rj   r   boolr   rk   r?   r   r   r   r   rg      s   
 rg   c                	   @   sh  e Zd ZU dZdZeed< eje	dZ
e	e ed< ejedZee ed< defdd	Zd
d ZdeddfddZdeddfddZdeddfddZdeeef ddfddZd/ddZdd defddZdeeef fddZd d! Zed"edee	e e	e f fd#d$Zd%d& Zdeeef fd'd(Z d)ed*e	e de	e de	e fd+d,Z!d0defd-d.Z"dS )1IastSpanReporterz3
    Class representing an IAST span reporter.
    r   stacktrace_idr0   sourcesvulnerabilitiesr   c                 C   s"   t tjdd t| j| jB D S )zq
        Computes the hash value of the IAST span reporter.

        Returns:
        - int: Hash value.
        c                 s   s    | ]}t |V  qd S r   )r>   )r   objr   r   r   	<genexpr>   s    z,IastSpanReporter.__hash__.<locals>.<genexpr>)r   operatorxorsetro   rp   r(   r   r   r   r?      s   "zIastSpanReporter.__hash__c                 C   s   | j D ]}| | qdS )zQ
        Populates the stacktrace_id of provided vulnerabilities if any.
        N)rp   _populate_stacktrace_idr)   vulnerabilityr   r   r   rV      s   
zIastSpanReporter.__post_init__rx   Nc                 C   s   |  | | j| dS )z
        Appends a vulnerability to the IAST span reporter.

        Args:
        - vulnerability (Vulnerability): Vulnerability to append.
        N)rv   rp   addrw   r   r   r   _append_vulnerability   s   
z&IastSpanReporter._append_vulnerabilityc                 C   s@   |  j d7  _ t| j }t|tjdsd|j_dS | j |j_dS )zH
        Populates the stacktrace_id of the IAST span reporter.
           )stack_id	namespaceN)rn   rB   r   r   IASTrb   rM   )r)   rx   str_idr   r   r   rv      s
   
z(IastSpanReporter._populate_stacktrace_idr;   c                 C   s4   t  }| j|_|t| | | |j| _dS )z
        Merges the current IAST span reporter with another IAST span reporter from a JSON string.

        Args:
        - json_str (str): JSON string.
        N)rm   rn   
_from_dictr4   loads_merge)r)   r;   r@   r   r   r   _merge_json   s
   
zIastSpanReporter._merge_jsondatac                 C   s.   t  }| j|_|| | | |j| _dS )z
        Merges the current IAST span reporter with another IAST span reporter from a dictionary.

        Args:
        - data (dict[str, Any]): dictionary.
        N)rm   rn   r   r   )r)   r   r@   r   r   r   _merge_dict   s
   

zIastSpanReporter._merge_dictr@   c                 C   s(   t | j}| j|j | _| || dS )z
        Merges the current IAST span reporter with another IAST span reporter.

        Args:
        - other (IastSpanReporter): IAST span reporter to merge.
        N)r   ro   _update_vulnerabilities)r)   r@   len_previous_sourcesr   r   r   r      s   
zIastSpanReporter._mergeoffsetc                 C   sd   |j D ],}t|dr)t|jdr)|jjd ur)|jjD ]}d|v r(|d | |d< q| j | qd S )Nra   r2   source)rp   hasattrra   r2   ry   )r)   r@   r   vulnr:   r   r   r   r      s   

z(IastSpanReporter._update_vulnerabilitiesc                 C   s@  ddl m} g | _|d D ]/}t||d |d d}d|v r$|d |_d|v r-|d |_d	|v r6|d	 |_| j| qt | _	|d
 D ]X}t
 }d|d v rW|d d |_d|d v rft|d d |_d|d v rs|d d |_d|d v r|d d |_| t|d |t|d d |d d |d d dd qEdS )z5Initializes the IAST span reporter from a dictionary.r{   )str_to_originro   rh   ri   )rh   ri   r   rj   rk   rp   rangesra   r2   r   r`   rb   rK   rN   rO   )rK   rN   rO   )r`   ra   rb   N)_taint_trackingr   ro   rg   r   rj   rk   appendru   rp   r/   r   r   r2   r   rz   r_   rH   )r)   r   r   ir   ra   r   r   r   r      sJ   






zIastSpanReporter._from_dictc                 C   s"   dd | j D dd | jD dS )Nc                 S      g | ]}|  qS r   r*   r   r   r   r   r   
<listcomp>"      z-IastSpanReporter._to_dict.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r   #  r   ro   rp   r   r(   r   r   r   r*      s   zIastSpanReporter._to_dictpyobjectc                 C   s   ddl m} t }|| }t }t|sg g fS |D ](}t|jj|jj|jjd}||vr2|	| |	|j
|j
|j |j|d q||fS )z
        Extracts tainted ranges as evidence information.

        Args:
        - pyobject (Any): Python object.

        Returns:
        - tuple[set[Source], list[dict]]: Set of Source objects and list of tainted ranges as dictionaries.
        r   )get_tainted_ranges)rh   ri   r   )startendlengthr   )8ddtrace.appsec._iast._taint_tracking._taint_objects_baser   rE   r   rg   r   rh   ri   r   r   r   r   )r   r   ro   tainted_rangestainted_ranges_to_dict_ranger   r   r   r   taint_ranges_as_evidence_info&  s   
z.IastSpanReporter.taint_ranges_as_evidence_infoc                 C   sT   t  s
td d S | |jj\}}||j_|D ]}|| jvr'| j|g | _qd S )Nziast::propagation::context::add_ranges_to_evidence_and_extract_sources. No request quota or this vulnerability is outside the context)r   logdebugr   ra   r   r   ro   )r)   r   ro   r   r   r   r   r   *add_ranges_to_evidence_and_extract_sourcesC  s   
z;IastSpanReporter.add_ranges_to_evidence_and_extract_sourcesc                 C   s   t  s
td i S | jD ]_}t|j|j|jj| j	}|rO|d }|D ]}d|v r2t
|d |d< q$|d }d}| j	D ]	}||v rEd|_q<||j_d|j_q|jjdurl|jtvrl| |jj|jj| j	|j_d|j_q|  S )z
        Builds and scrubs value parts of vulnerabilities.

        Returns:
        - dict[str, Any]: Dictionary representation of the IAST span reporter.
        zviast::propagation::context::build_and_scrub_value_parts. No request quota or this vulnerability is outside the contextredacted_value_partsr   redacted_sourcesr   N)r   r   r   rp   r   scrub_evidencer`   ra   r   ro   r   r   r2   EVIDENCES_WITH_NO_SOURCESget_unredacted_value_partsr*   )r)   r   scrubbing_resultr   r:   r   r   r   r   r   r   build_and_scrub_value_partsP  s<   


z,IastSpanReporter.build_and_scrub_value_partsevidence_valuer   c              	   C   s   g }d}|D ]4}||d k r| dt|||d  i t||d }| t||d |d  |d |d }q|t|k rN| dt||d i |S )a(  
        Gets unredacted value parts of evidence.

        Args:
        - evidence_value (str): Evidence value.
        - ranges (list[dict]): list of tainted ranges.
        - sources (list[Any]): list of sources.

        Returns:
        - list[dict]: list of unredacted value parts.
        r   r   r   r   r   )r   r   N)r   r   r	   r   )r)   r   r   ro   value_parts
from_indexrange_source_indexr   r   r   r   u  s   
z+IastSpanReporter.get_unredacted_value_partsc                    sT   ddl m  ddl m G  fdddtj}|r!tj||dS tj|  |dS )z
        Converts the IAST span reporter to a JSON string.

        Returns:
        - str: JSON representation of the IAST span reporter.
        r{   )
OriginType)origin_to_strc                       s   e Zd Z fddZdS )z3IastSpanReporter._to_str.<locals>.OriginTypeEncoderc                    s    t | r	|S tj| |S r   )
isinstancer4   JSONEncoderrQ   )r)   rq   r   r   r   r   rQ     s   
z;IastSpanReporter._to_str.<locals>.OriginTypeEncoder.defaultN)r+   r,   r-   rQ   r   r   r   r   OriginTypeEncoder  s    r   )cls)r   r   r   r4   r   r5   r*   )r)   	dict_datar   r   r   r   _to_str  s   zIastSpanReporter._to_str)r@   rm   r   Nr   )#r+   r,   r-   __doc__rn   r^   rC   r&   rD   rE   ro   rg   ru   rp   r_   r?   rV   rz   rv   rB   r   rF   r   r   r   r   r   r*   staticmethodtupler   r   r   r   r   r   r   r   r   rm      s*   
 	

)$&%#rm   ),r&   	functoolsr   r4   rs   re   typingr   r   r6   ddtrace.appsec._constantsr   /ddtrace.appsec._exploit_prevention.stack_tracesr   ;ddtrace.appsec._iast._evidence_redaction._sensitive_handlerr   /ddtrace.appsec._iast._iast_request_context_baser   ddtrace.appsec._iast._utilsr	   ddtrace.appsec._iast.constantsr
   r   r   ddtrace.internal.loggerr   ddtrace.internal.settings.asmr   r   r+   r   	frozensetr   r   "DEFAULT_EVIDENCE_TRUNCATION_LENGTHrB   r   r   	dataclassr/   rH   r_   rg   rm   r   r   r   r   <module>   sD    




