Harden Windows DLP enforcement and Electron runtime packaging
This commit is contained in:
1 parent
e7d778aeac
commit
8a253eda89
120 files changed
+3569
-135
No files matched your search
@@ -7,14 +7,31 @@ function clipboardDOM(mode,url,token,operation,payload,limit){
|
||||
const sensitive=e=>{for(let p=e;p&&p!==document.body;p=p.parentElement)if(p.hasAttribute?.('data-sensitive')||/password|passwd|secret|token|credential|api.?key|auth|one.?time|otp|master|credit.?card|cc-number|cc-csc/i.test(['name','id','autocomplete','aria-label'].map(a=>p.getAttribute(a)||'').join(' ')))return true;return /^(password|file|hidden)$/i.test(e?.type||'');};
|
||||
const visible=e=>{if(!e||e.closest('[hidden],[aria-hidden="true"],[inert]'))return false;let p=e,count=0;while(p&&count++<64){const s=getComputedStyle(p);if(s.display==='none'||s.visibility==='hidden'||s.opacity==='0')return false;p=p.parentElement;}return !p&&e.getClientRects().length>0;};
|
||||
const rangeSafe=range=>{const ancestor=range.commonAncestorContainer.nodeType===1?range.commonAncestorContainer:range.commonAncestorContainer.parentElement;if(!ancestor?.isConnected||!visible(ancestor)||sensitive(ancestor)||ancestor.closest('input,textarea,[contenteditable],script,style,template,noscript')||ancestor.querySelector?.('input,textarea,[contenteditable]'))return false;const walker=document.createTreeWalker(ancestor,NodeFilter.SHOW_ELEMENT);let e,visited=0;while((e=walker.nextNode())){if(++visited>2048)return false;if(range.intersectsNode(e)&&(!visible(e)||sensitive(e)||/^(SCRIPT|STYLE|TEMPLATE|NOSCRIPT)$/.test(e.tagName)))return false;}return true;};
|
||||
// Editor support remains plain text: neither clipboard HTML nor a page's paste
|
||||
// handler participates in mutation. Bind the exact DOM, focus and selection.
|
||||
const editorRangeSafe=(e,range)=>{
|
||||
if(!e?.isConnected||!e.isContentEditable||!visible(e)||sensitive(e)||e.closest('input,textarea,iframe'))return false;
|
||||
if(!e.contains(range.startContainer)||!e.contains(range.endContainer))return false;
|
||||
const walker=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);let node,count=0;
|
||||
while((node=walker.nextNode())){if(++count>2048)return false;if(range.intersectsNode(node)&&(!visible(node)||sensitive(node)||node.getAttribute('contenteditable')==='false'||/^(INPUT|TEXTAREA|IFRAME|SCRIPT|STYLE|TEMPLATE|NOSCRIPT)$/.test(node.tagName)))return false;}
|
||||
return true;
|
||||
};
|
||||
const targetFacts=(e,rect)=>{const target={tag:/^[A-Z][A-Z0-9]{0,31}$/.test(e.tagName)?e.tagName.toLowerCase():'unknown'};const role=e.getAttribute?.('role');if(['button','link','textbox','checkbox','radio','combobox','menuitem','option'].includes(role))target.role=role;if(rect){const x=rect.left+rect.width/2,y=rect.top+rect.height/2;if(Number.isFinite(x)&&Number.isFinite(y)&&x>=0&&y>=0&&x<=innerWidth&&y<=innerHeight){target.x=Math.round(x);target.y=Math.round(y);}}return target;};
|
||||
if(mode==='stage'){
|
||||
const snapshot={token,operation,field};let text='';
|
||||
const snapshot={token,operation,field};let text;
|
||||
if(field&&(field.tagName==='INPUT'||field.tagName==='TEXTAREA'||field.isContentEditable)){
|
||||
if(field.isContentEditable){
|
||||
const selection=getSelection(),range=selection?.rangeCount===1?selection.getRangeAt(0):null;
|
||||
if(!range||!editorRangeSafe(field,range))throw Error('Clipboard editor selection unsupported');
|
||||
if(field.innerHTML.length>limit||field.textContent.length>limit)throw Error('Clipboard target size limit');
|
||||
snapshot.target=targetFacts(field,field.getBoundingClientRect?.());snapshot.kind='editor';snapshot.html=field.innerHTML;snapshot.range=range.cloneRange();
|
||||
text=operation==='paste'?'':range.toString();
|
||||
}else{
|
||||
if(!editable(field)||sensitive(field)||!visible(field))throw Error('Clipboard target denied');
|
||||
snapshot.target=targetFacts(field,field.getBoundingClientRect?.());snapshot.kind='field';snapshot.value=field.value;if(snapshot.value.length>limit)throw Error('Clipboard target size limit');snapshot.start=field.selectionStart;snapshot.end=field.selectionEnd;
|
||||
if(!Number.isInteger(snapshot.start)||!Number.isInteger(snapshot.end))throw Error('Clipboard selection unsupported');
|
||||
text=operation==='paste'?'':snapshot.value.slice(snapshot.start,snapshot.end);
|
||||
}
|
||||
}else{
|
||||
if(operation!=='copy')throw Error('Clipboard edit target unsupported');
|
||||
const selection=getSelection();if(!selection||selection.rangeCount!==1||selection.isCollapsed)throw Error('Clipboard selection unavailable');
|
||||
@@ -33,10 +50,20 @@ function clipboardDOM(mode,url,token,operation,payload,limit){
|
||||
const value=operation==='paste'?payload:'';if(typeof value!=='string'||value.length>limit)throw Error('Clipboard payload denied');
|
||||
e.setRangeText(value,snapshot.start,snapshot.end,'end');e.dispatchEvent(new Event('input',{bubbles:true}));
|
||||
}
|
||||
}else if(snapshot.kind==='editor'){
|
||||
const e=snapshot.field,selection=getSelection(),range=selection?.rangeCount===1?selection.getRangeAt(0):null,original=snapshot.range;
|
||||
if(e!==document.activeElement||e.innerHTML!==snapshot.html||!range||range.startContainer!==original.startContainer||range.endContainer!==original.endContainer||range.startOffset!==original.startOffset||range.endOffset!==original.endOffset||!editorRangeSafe(e,range))throw Error('Clipboard editor target changed');
|
||||
if(mode!=='validate'&&operation!=='copy'){
|
||||
const value=operation==='paste'?payload:'';
|
||||
if(typeof value!=='string'||value.length>limit||value.includes('\0'))throw Error('Clipboard payload denied');
|
||||
range.deleteContents();
|
||||
if(value){const node=document.createTextNode(value);range.insertNode(node);range.setStartAfter(node);}
|
||||
range.collapse(true);selection.removeAllRanges();selection.addRange(range);
|
||||
e.dispatchEvent(new InputEvent('input',{bubbles:true,inputType:operation==='paste'?'insertText':'deleteByCut',data:value}));
|
||||
}
|
||||
}else{
|
||||
const selection=getSelection(),range=selection?.rangeCount===1?selection.getRangeAt(0):null,original=snapshot.range;
|
||||
if(!range||range.startContainer!==original.startContainer||range.endContainer!==original.endContainer||range.startOffset!==original.startOffset||range.endOffset!==original.endOffset||range.toString()!==snapshot.text)throw Error('Clipboard selection changed');
|
||||
const ancestor=range.commonAncestorContainer.nodeType===1?range.commonAncestorContainer:range.commonAncestorContainer.parentElement;
|
||||
if(!rangeSafe(range))throw Error('Clipboard selection changed');
|
||||
}
|
||||
return {completed:true};
|
||||
|
||||
Reference in new issue
Block a user