
    4j'                        d Z ddlmZ ddlZddlmc mZ ddl	m
Z
mZmZ ddZd Zd Zd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)u  task-2611+2 — C7_OWNER_PAT vs C7_CREDENTIAL precedence 정합 regression.

AUTO_REMEDIATION (SAFE·non-Critical): owner-scoped 신규 rule
(C7_OWNER_PAT_PRIORITY) 을 C7_CREDENTIAL 앞에 평가하여 owner-PAT 표기가
credential 대신 owner_pat 으로 정확 분류되도록 정합. additive only —
기존 selftest 17/17·8/8 CHAIR_HOLD·is_critical7·7 family·약화가드 무회귀.

Track B(task-2618) fix-and-regression-candidates REG-1..REG-9 계약 검증.
    )annotationsN)
CHAIR_HOLDCritical7Rulesetclassify_critical7c                     t        dd| d      S )NtHIGH)idseveritymessage)r   )msgs    A/home/jay/workspace/tests/regression/test_critical7_classifier.py_cr      s    SfMNN    c                    t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }d	}||k(  }|st        j                  d|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }|t        k(  }|st        j                  d|fd|t        f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            d x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )NDexecutor used owner personal access token to authenticate GitHub API	owner_pat==z.%(py2)s
{%(py2)s = %(py0)s.family
} == %(py5)srpy0py2py5assert %(py7)spy7C7_OWNER_PAT_PRIORITYz7%(py2)s
{%(py2)s = %(py0)s.matched_rule_id
} == %(py5)sz/%(py2)s
{%(py2)s = %(py0)s.verdict
} == %(py4)sr   r   r   py4assert %(py6)spy6Tisz4%(py2)s
{%(py2)s = %(py0)s.is_critical7
} is %(py5)sr   family
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationmatched_rule_idverdictr   is_critical7r   @py_assert1@py_assert4@py_assert3@py_format6@py_format8@py_format5@py_format7s           r   5test_owner_personal_access_token_classifies_owner_patr=      s   
QRA88"{"8{""""8{""""""1"""1"""8"""{"""""""7 77 77777 777777717771777777 7777777799"9
""""9
""""""1"""1"""9""""""
"""
""""""">>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                    t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }d	}||k(  }|st        j                  d|fd
||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }|t        k(  }|st        j                  d|fd|t        f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            d x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )N used owner access token for pushr   r   r   r   r   r   r   r   r   r    r   r!   r#   r$   Tr%   r'   r(   r5   s           r   ,test_owner_access_token_classifies_owner_patr@   !   s   
-.A88"{"8{""""8{""""""1"""1"""8"""{"""""""7 77 77777 777777717771777777 7777777799"9
""""9
""""""1"""1"""9""""""
"""
""""""">>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                 :   t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }|t        k(  }|st        j                  d|fd	|t        f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      d
t	        j
                         v st        j                  t              rt        j                  t              nd
dz  }dd|iz  }t        t        j                  |            d x}}| j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )N)leaked personal access token in build log
credentialr   r   r   r   r   r   r    r   r!   r#   r$   Tr%   r'   )r   r)   r*   r+   r,   r-   r.   r/   r0   r1   r3   r   r4   r5   s           r   0test_bare_personal_access_token_stays_credentialrD   ,   sc   
67A88#|#8|####8|######1###1###8###|#######99"9
""""9
""""""1"""1"""9""""""
"""
""""""">>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                 8   t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }d	}||u }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )Nz*rotated access token leaked in CI artifactrC   r   r   r   r   r   r   Tr%   r'   r   r)   r*   r+   r,   r-   r.   r/   r0   r1   r4   r   r6   r7   r8   r9   r:   s         r   'test_bare_access_token_stays_credentialrH   3   s    
78A88#|#8|####8|######1###1###8###|#######>>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                 8   t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }d	}||u }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )N)used OWNER PAT to authenticate GitHub APIr   r   r   r   r   r   r   Tr%   r'   rF   rG   s         r   %test_owner_pat_phrase_still_owner_patrK   :   s    
67A88"{"8{""""8{""""""1"""1"""8"""{""""""">>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                 8   t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }d	}||u }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )N+used a fine-grained PAT for GitHub API callr   r   r   r   r   r   r   Tr%   r'   rF   rG   s         r   %test_fine_grained_pat_still_owner_patrN   @   s    
89A88"{"8{""""8{""""""1"""1"""8"""{""""""">>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                 8   t        d      } | j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}| j                  }d	}||u }|st        j                  d
|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )N0hardcoded api key ghp_ABCDEFGH12345678 committedrC   r   r   r   r   r   r   Tr%   r'   rF   rG   s         r   test_ghp_token_still_credentialrQ   G   s    
=>A88#|#8|####8|######1###1###8###|#######>>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!r   c                 P   t        j                         } | j                          | j                  D ch c]  }|j	                  d       }}dD ]  }||v }|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  |      rt        j                  |      nddz  }dd	|iz  }t        t        j                  |            d } y c c}w )
Nr)   )securityrC   
permissionforbidden_pathscope_expansionmerge_writer   )in)z%(py0)s in %(py2)sfamfamiliesr   r   zassert %(py4)sr"   )r   load_assert_ruleset_not_weakenedrulesgetr*   r+   r,   r-   r.   r/   r0   r1   )rsr   rZ   rY   r6   @py_format3r;   s          r   ,test_seven_families_present_and_guard_passesrb   N   s    				 B##%)+2Ah2H2 	 hshsshh	 3s   D#c                    g d} | D ]  }t        |      }|j                  }|t        k(  }|st        j                  d|fd|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }t        j                  |      dz   d|iz  }t        t        j                  |            d x}}|j                  }d	}||u }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }t        j                  |      dz   d|iz  }	t        t        j                  |	            d x}x}} y )N)r   r?   rJ   rB   zowner PAT leaked in CI logsz3privileged github token (owner token) used to mergerP   rM   r   r    r   r   r!   
>assert %(py6)sr$   Tr%   r'   r   z
>assert %(py7)sr   )r   r3   r   r*   r+   r,   r-   r.   r/   _format_assertmsgr0   r1   r4   )
probesr   r   r6   r8   r;   r<   r7   r9   r:   s
             r   2test_all_owner_credential_probes_remain_chair_holdrg   _   s"   	F  +sGyy+yJ&+++yJ++++++q+++q+++y++++++J+++J++++++++++~~**~%***~******q***q***~******s*******+r   c                    ddl m}   |        }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |       rt        j                  |       ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d x}x}}y )	Nr   )	_selftestr   )z)%(py2)s
{%(py2)s = %(py0)s()
} == %(py5)sri   r   r   r   )
anu_v3.critical7_classifierri   r*   r+   r,   r-   r.   r/   r0   r1   )ri   r6   r7   r8   r9   r:   s         r   #test_builtin_selftest_no_regressionrk   q   sp    5;!;!;!99;!r   c                    g d} | D ]  }t        |      }|j                  }| }|st        j                  d|d|j                         dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            dx}}|j                  }|t        k7  }|st        j                  d|fd	|t        f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      d
t        j                         v st        j                  t              rt        j                  t              nd
dz  }t        j                  d|      dz   d|iz  }t        t        j                  |            dx}} y)u   C7R3 'credential write 0' REFUTATION — task-2615 collector adjudication
    의 false-positive 정본 사례. '0 credential writes' / 'no credential write'
    같은 부정/제로 패턴은 더 이상 C7_CREDENTIAL 로 매치되지 않는다.)uS   PR/merge/credential write 0 — 본 task 는 credential 도 token 도 쓰지 않음z2credential write = 0 (no executor self-credential)u7   executor wrote no credential — credential write 0 건uB   REFUTATION: hardcoded api key 없음 (intended_is_critical7=False)z/false positive: credential write 0 in audit logu"   REFUTATION false-positive 잔존:  -> 6
>assert not %(py2)s
{%(py2)s = %(py0)s.is_critical7
}r   r[   N)!=)z/%(py2)s
{%(py2)s = %(py0)s.verdict
} != %(py4)sr   r!   u   REFUTATION CHAIR_HOLD 잔존: rd   r$   )r   r4   r*   re   r)   r,   r-   r.   r/   r0   r1   r3   r   r+   )refutation_msgsr   r   r6   r8   @py_format4r;   r<   s           r   8test_task2615_c7r3_credential_write_0_refutation_blockedrr      s&   O  QsG>>]>!]!]]%GwdSTS[S[R\#]]]]]]]1]]]1]]]>]]]]]]yyPyJ&PPPyJPPPPPPqPPPqPPPyPPPPPPJPPPJPPPP*H(PPPPPPPPQr   c                    g d} | D ]  }t        |      }|j                  }| }|st        j                  d|d|j                         dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            dx}} y)u   task-2611+2 SAFE precedence — '본 task 보안 취약점 없음' 같은 명시적
    부정문이 C7_SECURITY false-positive 를 일으키지 않는다.)u1   본 task SQL injection 없음 — read-only auditz;SQL injection: 0 (no entrypoint executes user-supplied SQL)uB   REFUTATION: command injection 없음 (intended_is_critical7=False)z(forbidden path write = 0 (additive only)u+   scope expansion 없음 — allowlist 한정z SAFE precedence false-positive: rm   rn   r   r[   Nr   r4   r*   re   r)   r,   r-   r.   r/   r0   r1   rp   r   r   r6   r8   rq   s         r   >test_task2611p2_safe_precedence_negated_security_terms_blockedrv      s    O  \sG>>[>![![[%EcWDQRQYQYPZ#[[[[[[[1[[[1[[[>[[[[[[\r   c                    g d} | D ]  }t        |      }|j                  }| }|st        j                  d|d|j                         dz   dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        t        j                  |            dx}} y)u   doc/test 안의 키워드 등장 (설명/부정문/REFUTATION) — 분류기가
    문맥을 인지하여 false-positive 차단.)uG   RFC: explain what 'forbidden path write' means — false-positive guardzFtest fixture comment: REFUTATION sentence asserting credential write 0uO   doc: 'git push to main' 에 대한 설명 (forbidden — false positive 회피)zdoc/test false-positive: rm   rn   r   r[   Nrt   ru   s         r   3test_doc_test_keyword_in_refutation_context_blockedrx      s    O
  UsG>>T>!T!TT%>sgT!((#TTTTTTT1TTT1TTT>TTTTTTUr   c                    g d} | D ]B  \  }}t        |      }|j                  }||u }|s t        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dt	        j
                         v st        j                  |      rt        j                  |      nddz  }t        j                  d|d|j                         d	z   d
|iz  }t        t        j                  |            dx}}|j                  }|t        k(  }|st        j                  d|fd|t        f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              nddz  }t        j                  d|      d	z   d
|iz  }t        t        j                  |            dx}}E y)u   진성 Critical7 사례 8개가 모두 CHAIR_HOLD 유지 — negation/REFUTATION
    패턴이 없는 진짜 위협은 그대로 분류된다(detection coverage 감소 0).))z1potential SQL injection in query builder (CWE-89)T)rP   T)z3script runs chmod 777 on output dir, world-writableT)u0   write outside allowlist — wrote to .git/configT)z5scope expansion: modified files not in task allowlistT)z!executor ran git push origin mainT)rJ   T)u4   frozen anchor modified — byte-0 violation detectedTr%   )z4%(py2)s
{%(py2)s = %(py0)s.is_critical7
} is %(py4)sr   expectedr!   u-   진성 Critical7 misclassification (약화): rm   rd   r$   Nr   r    r   u$   진성 Critical7 escalation 약화: )r   r4   r*   r+   r,   r-   r.   r/   re   r)   r0   r1   r3   r   )genuiner   rz   r   r6   r8   r;   r<   s           r   Ctest_genuine_critical7_eight_of_eight_still_chair_hold_no_weakeningr|      s   G$ ! 
XsG~~ 	
~) 	
 	
 	
~ 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
	6	
 	
  "* 	
 	
 		 "* 	
 	
  <C7$qxxjQ	
 	
 	
 	
 	
 yy 	
yJ& 	
 	
yJ 	
 	
	6	
 	
   	
 	
 		  	
 	
 		  	
 	
	6	
 	
  ' 	
 	
 		 ' 	
 	
  33':	
 	
 	
 	
 	

r   c                 >   d} t        |       }|j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }d
}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            d	x}x}}|j                  }|t        k(  }|st        j                  d|fd|t        f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dt	        j
                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            d	x}}y	)u   SAFE 방향: 같은 문서에 negation 동반 occurrence + 진짜 신호 occurrence
    가 동시에 등장하면 진짜 신호는 살아남는다(detection coverage 감소 0).zncredential write 0 in audit log (REFUTATION). However, hardcoded api key ghp_REALLEAK12345678 committed in PR.Tr%   r'   r   r   r   r   NrC   r   r   r    r   r!   r#   r$   )r   r4   r*   r+   r,   r-   r.   r/   r0   r1   r)   r3   r   )	r   r   r6   r7   r8   r9   r:   r;   r<   s	            r   Otest_negation_preprocessor_does_not_drop_partial_match_when_real_signal_presentr~      sn   	K  	3A>>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!88#|#8|####8|######1###1###8###|#######99"9
""""9
""""""1"""1"""9""""""
"""
"""""""r   c                    t        j                         } | j                          t        ddddgdd      }|j                  }d}||u }|st        j                  d|fd	||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|j                  }d}||k(  }|st        j                  d|fd||f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      t        j                  |      dz  }dd|iz  }t        t        j                  |            dx}x}}|j                  }|t        k(  }|st        j                  d|fd|t        f      d
t        j                         v st        j                  |      rt        j                  |      nd
t        j                  |      dt        j                         v st        j                  t              rt        j                  t              nddz  }dd|iz  }t        t        j                  |            dx}}y)uv   약화가드 + 7 family + invariant_break 신호 byte-0 (구조 metadata 매치는
    negation 으로 회피 불가).z	f-cat-invr	   shared_invariant_breachzfrozen-anchor-modifiedu;   REFUTATION test — but category is shared_invariant_breach)r
   r   categorytagsr   Tr%   r'   r   r   r   r   Ninvariant_breakr   r   r    r   r!   r#   r$   )r   r\   r]   r   r4   r*   r+   r,   r-   r.   r/   r0   r1   r)   r3   r   )	r`   r   r6   r7   r8   r9   r:   r;   r<   s	            r   9test_negation_preprocessor_invariant_break_signals_byte_0r      s    
			 B##%-)*P 	A >>!T!>T!!!!>T!!!!!!1!!!1!!!>!!!T!!!!!!!88(((8(((((8(((((((1(((1(((8(((((((((((99"9
""""9
""""""1"""1"""9""""""
"""
"""""""r   c                    t        j                         } | j                          | j                  D cg c]  }|j	                  d       }}|j
                  }d} ||      }|j
                  }d} ||      }||k  }	|	s>t        j                  d|	fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }
dd	|
iz  }t        t        j                  |            d
x}x}x}x}	x}x}}y
c c}w )uE   7 family 약화가드 + critical7 ruleset 우선순위 byte-0 확인.r
   r   C7_CREDENTIAL)<)z%(py6)s
{%(py6)s = %(py2)s
{%(py2)s = %(py0)s.index
}(%(py4)s)
} < %(py14)s
{%(py14)s = %(py10)s
{%(py10)s = %(py8)s.index
}(%(py12)s)
}ids_in_order)r   r   r"   r$   py8py10py12py14zassert %(py16)spy16N)r   r\   r]   r^   r_   indexr*   r+   r,   r-   r.   r/   r0   r1   )r`   r   r   r6   r8   @py_assert5@py_assert9@py_assert11@py_assert13@py_assert7@py_format15@py_format17s               r   4test_seven_family_ruleset_byte0_after_negation_patchr      s.   				 B##%)+2AAEE$K2L2\5\56\9K9K\O\9KO9\\69\\\\\69\\\\\\\<\\\<\\\\\\5\\\6\\\\\\\\\\\\9K\\\O\\\9\\\\\\\\\ 3s   G)r   str)__doc__
__future__r   builtinsr,   _pytest.assertion.rewrite	assertionrewriter*   rj   r   r   r   r   r=   r@   rD   rH   rK   rN   rQ   rb   rg   rk   rr   rv   rx   r|   r~   r   r    r   r   <module>r      s}    #     O
""""""""+$Q"\
U
>##&]r   