o
    iE                  	   @   s  d dl Z d dlZd dl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 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" 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l0m1Z1 d d l2m3Z3 d d!l4m5Z5 d d"l6m7Z8 e1e9Z:d#ee;e<e<f e=e>e<e<f  f d$e;e<ee<e=e< f f fd%d&Z?d'e<d(ed$efd)d*Z@d$e<fd+d,ZAd$e3fd-d.ZBe jCd/d0G d1d2 d2eZDd3e
e>e<e<f  d4e
e>e<e<e5f  d$dfd5d6ZEe,Fd7eDjG e,Fd8eE dS )9    N)JSONDecodeError)Any)ClassVar)Optional)Sequence)Union)SpanProcessor)Span)_asm_request_context)APPSEC)DEFAULT)EXPLOIT_PREVENTION)SPAN_DATA_NAMES)STACK_TRACE)WAF_ACTIONSWAF_DATA_NAMES)WAF)ddwaf_context_capsule)report_stack)_asm_manual_keep)Binding_error)Block_config)DDWaf_result)is_inferred_span)_ORIGIN_KEY)_RUNTIME_FAMILY)	SpanTypes)core)unpatched_open)
get_logger)RateLimiter)PayloadType)configdatareturnc                 C   sz   i }t | tr	| n|  }|D ]+\}}| }|dv rq||v r6|| }t |tr/|| q||g||< q|||< q|S )N)cookiez
set-cookie)
isinstancelistitemslowerappend)r$   
normalizedheadersheadervalueexisting r1   M/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/appsec/_processor.py_transform_headers,   s   

r3   waf_namer/   c                 C   s   | t jv r	t|S |S N)r   HEADER_ADDRESSESr3   )r4   r/   r1   r1   r2   _serialize_address_values>   s   
r7   c                   C   s   t jptjS r5   )
asm_config_asm_static_rule_filer   RULESr1   r1   r1   r2   	get_rulesD   s   r;   c                   C   s   t ttdtjS )NDD_APPSEC_TRACE_RATE_LIMIT)r!   intosgetenvr   TRACE_RATE_LIMITr1   r1   r1   r2   _get_rate_limiterH   s   rA   F)eqc                   @   s  e Zd ZU ejedZeed< ejddZ	e
ed< ejddZe
ed< ejedZee ed< ejedZeed< d	Zeed   ed
< ed8ddZed8ddZedefddZd8ddZd8ddZd8ddZdeeeef  deeeeef  defddZ edefddZ!edefddZ"edefd d!Z#edefd"d#Z$edefd$d%Z%d&e&dd	fd'd(Z'							d9d)e&d*e(d+ee)ee*f  d,ee d-ee d.edee+ fd/d0Z,d1edefd2d3Z-d&e&dd	fd4d5Z.ed8d6d7Z/d	S ):AppSecSpanProcessor)default_factoryrule_filenameF)init obfuscation_parameter_key_regexp"obfuscation_parameter_value_regexp_addresses_to_keep_rate_limiterN	_instancer%   c                 C   s&   | j du r|   }| _ |  dS dS )z!Enable the AppSec span processor.N)rK   register)clsinstancer1   r1   r2   enableU   s   
zAppSecSpanProcessor.enablec                 C   s"   | j dur| j   d| _ dS dS )z"Disable the AppSec span processor.N)rK   
unregisterrM   r1   r1   r2   disable\   s   


zAppSecSpanProcessor.disablec                 C   s
   | j d uS r5   )_ddwafselfr1   r1   r2   enabledc   s   
zAppSecSpanProcessor.enabledc              
   C   s   t j | _t j | _d | _z t| jd}|	 | _W d    W d S 1 s(w   Y  W d S  t
yQ } z|jtjkrEtd| j  td| j  d }~w ty_   td| j   tym   td| j  w )NbrzO[DDAS-0001-03] ASM could not read the rule file %s. Reason: file does not existz3[DDAS-0001-03] ASM could not read the rule file %s.zM[DDAS-0001-03] ASM could not read the rule file %s. Reason: invalid JSON file)r8   %_asm_obfuscation_parameter_key_regexpencoderG   '_asm_obfuscation_parameter_value_regexprH   _rulesopenrE   readEnvironmentErrorerrnoENOENTlogerrorr   	Exception)rU   ferrr1   r1   r2   __post_init__g   s4   &z!AppSecSpanProcessor.__post_init__c                 C   s   zF| j d urEt| dsEddlm} dd lm  m} | }|d u r,td d | _	W d S || _
|| j | j| j|| _	| j
| j	j| j	j W n tyY   tjddd d | _	Y nw |   d S )NrS   r   )
waf_modulez<DDWaf features disabled. WARNING: Dynamic Library not loadedz([DDAS-0005-00] WAF initialization failedTexc_info)r[   hasattrddtrace.appsec._ddwafrg   ddtrace.appsec._metricsappsec_metricsra   warningrS   metricsrG   rH   _set_waf_init_metricinfoinitializedrc   _update_required)rU   rg   rp   DDWafr1   r1   r2   delayed_init   s(   

z AppSecSpanProcessor.delayed_initc                 C   sR   | j d u rd S | j  | j jD ]}| j| q| jtj | jtj d S r5   )rS   rI   clearrequired_dataaddr   REQUEST_HEADERS_NO_COOKIESRESPONSE_HEADERS_NO_COOKIESrU   addressr1   r1   r2   rt      s   

z$AppSecSpanProcessor._update_requiredremovalsupdatesc                 C   s^   t | ds	|   | jd u rdS d}tjd ur|S | j||}| j| jj| | 	  |S )NrS   F)
rj   rv   rS   r8   r9   update_rulesrp   _set_waf_updates_metricrr   rt   )rU   r~   r   resultr1   r1   r2   _update_rules   s   


z!AppSecSpanProcessor._update_rulesc                 C      t j| jv S r5   )r   LFI_ADDRESSrI   rT   r1   r1   r2   rasp_lfi_enabled      z$AppSecSpanProcessor.rasp_lfi_enabledc                 C   r   r5   )r   SHI_ADDRESSrI   rT   r1   r1   r2   rasp_shi_enabled   r   z$AppSecSpanProcessor.rasp_shi_enabledc                 C   r   r5   )r   CMDI_ADDRESSrI   rT   r1   r1   r2   rasp_cmdi_enabled   r   z%AppSecSpanProcessor.rasp_cmdi_enabledc                 C   r   r5   )r   SSRF_ADDRESSrI   rT   r1   r1   r2   rasp_ssrf_enabled   r   z%AppSecSpanProcessor.rasp_ssrf_enabledc                 C   r   r5   )r   SQLI_ADDRESSrI   rT   r1   r1   r2   rasp_sqli_enabled   r   z%AppSecSpanProcessor.rasp_sqli_enabledspanc                 C   s  ddl m} t| ds|   | jd u rd S |jtjvrd S |jtj	krE|
tjd td}|rEtd td |
tjd d S t|rR|
tjd d S |j}|
tjd |td | j }|d urwt| j||}|j}nd }d}t||| t }t  }	t! }
|	d urt"t#j$|	 t"t#j%|
 |sd S |&|	||
}t"t#j'| |r| (t)j'rtd	 t*d
d i d S d S d S d S )Nr   )trace_utilsrS   g      ?appsec_skip_next_lambda_eventz)appsec: ignoring unsupported lambda eventpython z5[DDAS-001-00] Executing ASM WAF for checking IP blockREQUEST_HTTP_IP)+ddtrace.contrib.internalr   rj   rv   rS   	span_typer8   _asm_processed_span_typesr   
SERVERLESS
set_metricr   SERVERLESS_TRACER_ENABLEDr   	find_itemdiscard_itemra   debugUNSUPPORTED_EVENT_TYPEr   ENABLED_service_entry_span_set_tag_strr   _at_request_start	functoolspartial_waf_actionrc_productsr
   start_contextget_ipget_headersget_headers_case_sensitiveset_waf_addressr   rz   REQUEST_HEADERS_NO_COOKIES_CASE_get_request_header_client_ipr   
_is_neededr   call_waf_callback)rU   r   r   
skip_event
entry_spanctxwaf_callabler   peer_ipr-   headers_case_sensitiveipr1   r1   r2   on_span_start   s^   





z!AppSecSpanProcessor.on_span_startr   r   custom_data
crop_trace	rule_type
force_sentc                    s  t  dr
 jdu rdS t r|r|di ddsdS i }i }|dur-dd |D nt}	t }
|
du r:t }
|rF|di ddnd}|	D ]k\}}||
v rU|sUqJ|tjvrk|rk||v rjt	|||||< qJ 
|sr|rd}|dur||dur||}n|tv rtdt| }|durt |d	st	||||< |tjv r|
| td
t|| qJ|s|sdS z jj|||pdtjd}W n ty   tjddd t}Y nw t fdd |jdk r(|rtjntj}||}|du r	||t|j nzt|}W n ty   d}Y nw ||tt||j i }|j ! D ]>\}}|t"j#kr=|}q/|t"j$krL|}d|t"j%< q/|t"j&krl|d }t'd|||t(j)d |j*D ]}||t+j,< qcq/|j-! D ]\}}||| qs|j.! D ]\}}|/|| q|j*rtd|j*|j0 |rt1t2di | d}|j3r j45 }t6 jj7j8t9||||  |j*rt:|j* |r|;tj<d |tj=d t>tj?}|r|d| |t@du r|t@tjA |j3r|rtB| |S )ax  
        Call the `WAF` with the given parameters. If `custom_data_names` is specified as
        a list of `(WAF_NAME, WAF_STR)` tuples specifying what values of the `WAF_DATA_NAMES`
        constant class will be checked. Else, it will check all the possible values
        from `WAF_DATA_NAMES`.

        If `custom_data_values` is specified, it must be a dictionary where the key is the
        `WAF_DATA_NAMES` key and the value the custom value. If not used, the values will
        be retrieved from the `core`. This can be used when you don't want to store
        the value in the `core` before checking the `WAF`.
        rS   NPROCESSOR_SETTINGSzextract-schemaFc                 S   s   g | ]}|t | fqS r1   r   ).0keyr1   r1   r2   
<listcomp>  s    z3AppSecSpanProcessor._waf_action.<locals>.<listcomp>waf_addresses__call__z[action] WAF got value %s)ephemeral_data
timeout_mszappsec::processor::waf::runTrh   c                      s    j jS r5   )rS   rr   r1   rT   r1   r2   <lambda>F  s    z1AppSecSpanProcessor._waf_action.<locals>.<lambda>r   inonestack_idzexploit detected)r   	namespacez5[DDAS-011-00] ASM In-App WAF returned: %s. Timeout %struezactor.ipr1   )Crj   rS   r
   get_blockedgetr   get_data_sentsetPERSISTENT_ADDRESSESr7   r   r   	get_valuery   ra   r   runr8   _waf_timeoutrc   r   set_waf_inforeturn_coder   
RASP_ERROR	WAF_ERRORget_tagr   strr=   
ValueErrormaxactionsr)   r   BLOCK_ACTIONREDIRECT_ACTIONTYPESTACK_ACTIONr   r   RASPr$   r   STACK_TRACE_ID	meta_tagsrp   r   timeoutset_blockedr   keeprJ   
is_allowedset_waf_telemetry_resultsrr   versionboolstore_waf_results_dataset_tagBLOCKEDEVENTget_waf_addressr   r   ORIGIN_VALUEr   )rU   r   r   r   r   r   r   r$   r   	iter_datadata_already_sent
force_keysr   r4   r/   waf_results	error_tagpreviousint_previousblockedaction
parametersstack_trace_idruleallowed	remote_ipr1   rT   r2   r      s   






zAppSecSpanProcessor._waf_actionr}   c                 C   s
   || j v S r5   )rI   r|   r1   r1   r2   r     s   
zAppSecSpanProcessor._is_neededc                 C   s:   t | dd d u r
d S |jtjv rt  t| d S d S )NrS   )getattrr   r8   r   r
   $call_waf_callback_no_instrumentationend_context)rU   r   r1   r1   r2   on_span_finish  s   z"AppSecSpanProcessor.on_span_finishc                 C   s   |    tjr|   dS dS )z Reset the AppSec span processor.N)rR   r8   _asm_enabledrO   rQ   r1   r1   r2   _reset  s   zAppSecSpanProcessor._reset)r%   N)NNNF)0__name__
__module____qualname__dataclassesfieldr;   rE   r   __annotations__rG   bytesrH   r   rI   rA   rJ   r!   rK   r   r   classmethodrO   rR   propertyr   rV   rf   rv   rt   r   tupler"   r   r   r   r   r   r   r	   r   r   dictr   r   r   r   r   r  r1   r1   r1   r2   rC   L   st   
 



=
 rC   r~   r   c                 C   s    t jdurt j| | dS dS )z<Update the WAF rules with the provided removals and updates.N)rC   rK   r   )r~   r   r1   r1   r2   
waf_update  s   
r  ztest.config.overridez
waf.update)Hr  r_   r   json.decoderr   r>   typingr   r   r   r   r   ddtrace._trace.processorr   ddtrace._trace.spanr	   ddtrace.appsecr
   ddtrace.appsec._constantsr   r   r   r   r   r   r   ddtrace.appsec._ddwaf.waf_stubsr   r   /ddtrace.appsec._exploit_prevention.stack_tracesr   ddtrace.appsec._trace_utilsr   ddtrace.appsec._utilsr   r   r   r   ddtrace.constantsr   r   ddtrace.extr   ddtrace.internalr   ddtrace.internal._unpatchedr   r\   ddtrace.internal.loggerr    ddtrace.internal.rate_limiterr!   ddtrace.internal.remoteconfigr"   ddtrace.internal.settings.asmr#   r8   r  ra   r  r   r(   r  r3   r7   r;   rA   	dataclassrC   r  onr  r1   r1   r1   r2   <module>   sn    B
  Y
	