"name":"[회계관리 > 매출관리] [EDGE] 특수문자/XSS 입력 → 방어 확인",
"action":"evaluate",
"script":"(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const sv=(el,v)=>{const p=el.tagName==='TEXTAREA'?HTMLTextAreaElement.prototype:HTMLInputElement.prototype;const ns=Object.getOwnPropertyDescriptor(p,'value')?.set;if(ns)ns.call(el,v);else el.value=v;el.dispatchEvent(new Event('input',{bubbles:true}));el.dispatchEvent(new Event('change',{bubbles:true}));};const R={phase:'XSS_CHECK'};const xssPayload='<script>alert(1)</script><img onerror=alert(1) src=x>';const inputs=Array.from(document.querySelectorAll('input[type=\"text\"],input:not([type]),textarea')).filter(i=>i.offsetParent!==null&&!i.readOnly&&!i.disabled);const itemInput=inputs.find(i=>(i.placeholder||'').includes('품목')||(i.name||'').includes('item')||(i.name||'').includes('product'));const targetInput=itemInput||inputs[0];if(targetInput){sv(targetInput,xssPayload);await w(500);R.inputSet=true;R.storedValue=targetInput.value;R.xssAccepted=targetInput.value.includes('<script>');R.sanitized=!targetInput.value.includes('<script>');const hasError=document.querySelector('[class*=\"error\"],[class*=\"Error\"],[role=\"alert\"],.text-red-500,.text-destructive');R.errorShown=!!hasError;const scriptTags=document.querySelectorAll('script:not([src])');R.injectedScripts=Array.from(scriptTags).filter(s=>s.textContent?.includes('alert(1)')).length;}else{R.inputNotFound=true;}R.ok=true;R.info=R.sanitized?'✅ XSS 입력 새니타이징됨':(R.errorShown?'✅ XSS 입력 시 에러 표시':'⚠️ XSS 페이로드가 그대로 수용됨 - 서버 측 방어 확인 필요');return JSON.stringify(R);})()",
"timeout":10000,
"phase":"BOUNDARY"
},
{
"id":10,
"name":"[회계관리 > 매출관리] [EDGE] 빈 폼 저장 시도 → 유효성 검사 확인",
"action":"evaluate",
"script":"(async()=>{const w=ms=>new Promise(r=>setTimeout(r,ms));const sv=(el,v)=>{const p=el.tagName==='TEXTAREA'?HTMLTextAreaElement.prototype:HTMLInputElement.prototype;const ns=Object.getOwnPropertyDescriptor(p,'value')?.set;if(ns)ns.call(el,v);else el.value=v;el.dispatchEvent(new Event('input',{bubbles:true}));el.dispatchEvent(new Event('change',{bubbles:true}));};const R={phase:'EMPTY_SUBMIT'};const inputs=Array.from(document.querySelectorAll('input[type=\"text\"],input[type=\"number\"],input:not([type]),textarea')).filter(i=>i.offsetParent!==null&&!i.readOnly&&!i.disabled);for(const inp of inputs){sv(inp,'');await w(100);}await w(500);const beforeErrors=document.querySelectorAll('[class*=\"error\"],[class*=\"Error\"],[class*=\"destructive\"],[role=\"alert\"]').length;const submitBtn=Array.from(document.querySelectorAll('button')).find(b=>{const t=b.innerText?.trim()||'';return(/등록|저장|확인|제출/.test(t))&&b.offsetParent!==null&&!b.disabled;});if(!submitBtn){R.err='저장/등록 버튼 없음';R.ok=true;return JSON.stringify(R);}R.submitBtnText=submitBtn.innerText?.trim();submitBtn.click();await w(2000);const toasts=document.querySelectorAll('[data-sonner-toast],[role=\"status\"],[class*=\"toast\"],[class*=\"Toast\"],[class*=\"Toaster\"] [data-content]');R.toastCount=toasts.length;if(toasts.length>0){R.toastTexts=Array.from(toasts).map(t=>t.innerText?.trim().substring(0,80)).filter(Boolean);}const errors=document.querySelectorAll('[class*=\"error\"],[class*=\"Error\"],[class*=\"destructive\"],[role=\"alert\"],[class*=\"invalid\"]');R.errorCount=errors.length;R.newErrors=errors.length-beforeErrors;if(errors.length>0){R.errorTexts=Array.from(errors).slice(0,5).map(e=>e.innerText?.trim().substring(0,60)).filter(Boolean);}const invalidFields=document.querySelectorAll('[aria-invalid=\"true\"]');R.ariaInvalidCount=invalidFields.length;const redBorders=Array.from(document.querySelectorAll('input,textarea,select,[role=\"combobox\"]')).filter(el=>{const cs=getComputedStyle(el);return cs.borderColor?.includes('rgb(239')||cs.borderColor?.includes('rgb(220')||cs.borderColor?.includes('rgb(248');});R.redBorderCount=redBorders.length;const dialogs=document.querySelectorAll('[role=\"alertdialog\"],[role=\"dialog\"]');const validationDialog=Array.from(dialogs).find(d=>d.offsetParent!==null);R.hasValidationDialog=!!validationDialog;if(validationDialog){R.dialogText=validationDialog.innerText?.trim().substring(0,100);}R.totalValidationSignals=R.toastCount+R.newErrors+R.ariaInvalidCount+R.redBorderCount+(R.hasValidationDialog?1:0);R.validationTriggered=R.totalValidationSignals>0;R.ok=true;R.info=R.validationTriggered?'✅ 빈 폼 제출 시 유효성 검사 정상 동작 (시그널 '+R.totalValidationSignals+'개)':'⚠️ 빈 폼 제출 시 유효성 검사 미감지';return JSON.stringify(R);})()",