@reason-machines/cli-linux-x64-musl 0.2.130 → 0.2.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/ara +2 -2
- package/bin/runtime/srt/sandbox-runtime.mjs +1 -1
- package/package.json +1 -1
package/bin/ara
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/bin/ara
|
|
3
|
-
size:
|
|
4
|
-
sha256:
|
|
3
|
+
size: 99277088 bytes
|
|
4
|
+
sha256: 10f1bdfc149575301f12d5ea47e900310d7c0090c17d822c2f3972a5bd6e77f7
|
|
@@ -58,7 +58,7 @@ Connection blocked by network allowlist`);return}if(W||Y.destroyed){Y.destroy();
|
|
|
58
58
|
Connection: close\r
|
|
59
59
|
\r
|
|
60
60
|
mux backend dial failed (${H})
|
|
61
|
-
`)}),U.on("error",()=>O.destroy()),U.once("close",()=>O.destroy()),O.once("close",()=>U.destroy()),U.pipe(O),O.pipe(U)}let M=Kq((U)=>{G.add(U),U.once("close",()=>G.delete(U)),U.on("error",(V)=>Z(`mux: client socket error: ${V.message}`));let O=setTimeout(()=>{Z("mux: first-byte timeout; destroying connection"),U.destroy()},J);if(typeof O.unref==="function")O.unref();U.once("readable",()=>{clearTimeout(O);let V=U.read(1);if(!V||V.length===0){U.destroy();return}if(U.unshift(V),Fq.has(V[0]))$.handleSocksConnection(U);else W(U)})});return{server:M,getPort(){let U=M.address();return U&&typeof U==="object"?U.port:void 0},async listenHttpBackend(){if(!X){let O=Rq();await iW(O).catch(()=>{}),await new Promise((V,H)=>{$.httpServer.once("error",H),$.httpServer.listen(O,()=>{$.httpServer.removeListener("error",H),V()})}),Q=O,Z(`mux: HTTP backend listening on ${O}`);return}await iY($.httpServer,(O)=>$.httpServer.listen(O,"127.0.0.1"),$.httpBackendPortRange,new Set);let U=$.httpServer.address();return Y=U&&typeof U==="object"?U.port:void 0,Z(`mux: HTTP backend listening on 127.0.0.1:${Y}`),Y},async close(){for(let U of G)U.destroy();if(G.clear(),await new Promise((U)=>M.close(()=>U())),await new Promise((U)=>$.httpServer.close(()=>U())),Q)await iW(Q).catch(()=>{}),Q=void 0;Y=void 0},unref(){M.unref(),$.httpServer.unref()}}}import{randomBytes as Aq,randomUUID as Dq}from"crypto";var xX="fake_value_",aW="abcdefghijklmnopqrstuvwxyz0123456789_-";function Zq($){let J=xX+Dq(),X=Buffer.byteLength($)-J.length;if(X<=0)return J;let Q=J;for(let Y of Aq(X))Q+=aW[Y%aW.length];return Q}class t8{byName=new Map;bySentinel=new Map;allSentinelsPrefixed=!0;register($,J,X){return this.registerWithSentinel($,Zq(J),J,X)}registerWithSentinel($,J,X,Q){let Y=this.byName.get($);if(Y!==void 0)return Y.realValue=X,Y.injectHosts=Q,Y.sentinel;if(!J.startsWith(xX))this.allSentinelsPrefixed=!1;let G={name:$,sentinel:J,realValue:X,injectHosts:Q};return this.byName.set($,G),this.bySentinel.set(J,G),J}lookupReal($){return this.bySentinel.get($)?.realValue}namesInjectableAt($,J){let X=[];for(let Q of this.byName.values())if(Q.injectHosts.some((Y)=>J($,Y)))X.push(Q.name);return X}sentinelsForHost($,J){let X=[];for(let Q of this.bySentinel.values()){if(!Q.injectHosts.some((Y)=>J($,Y)))continue;X.push({sentinel:Buffer.from(Q.sentinel),realValue:Buffer.from(Q.realValue)})}return X}*entries(){for(let $ of this.bySentinel.values())yield[$.sentinel,$.realValue]}get size(){return this.bySentinel.size}clear(){this.byName.clear(),this.bySentinel.clear(),this.allSentinelsPrefixed=!0}substituteInHeaders($,J,X){if(this.bySentinel.size===0)return;for(let[Q,Y]of Object.entries($)){if(Y===void 0)continue;if(Array.isArray(Y))for(let G=0;G<Y.length;G++)Y[G]=this.substituteInHeaderValue(Q,Y[G],J,X);else $[Q]=this.substituteInHeaderValue(Q,Y,J,X)}}substituteInHeaderValue($,J,X,Q){let Y=this.substituteInString(J,X,Q);if($.toLowerCase()!=="authorization")return Y;let G=/^(\s*basic\s+)([a-z0-9+/]+={0,2})(\s*)$/i.exec(Y);if(G===null)return Y;let W=G[2],M=Buffer.from(W,"base64");if(W.length%4!==0||M.toString("base64")!==W)return Y;let U=M.toString("utf8");if(!Buffer.from(U,"utf8").equals(M))return Y;let O=this.substituteInString(U,X,Q);if(O===U)return Y;return`${G[1]}${Buffer.from(O,"utf8").toString("base64")}${G[3]}`}substituteInString($,J,X){if(this.allSentinelsPrefixed&&!$.includes(xX))return $;let Q=$;for(let Y of this.bySentinel.values()){if(!Q.includes(Y.sentinel))continue;if(!Y.injectHosts.some((G)=>X(J,G)))continue;Q=Q.split(Y.sentinel).join(Y.realValue)}return Q}}import{randomUUID as Pq}from"crypto";import*as pJ from"fs";import{tmpdir as _q}from"os";import{join as eW}from"path";function Bq($,J){let X=!1;for(let Q=J+1;Q<$.length;Q++){let Y=$[Q];if(X){X=!1;continue}if(Y==="\\")X=!0;else if(Y==="]")return Q+1}return $.length}function jq($){switch($){case"s":return{kind:"whitespace"};case"S":return{kind:"non-whitespace"};case"d":return{kind:"digit"};case"D":return{kind:"non-digit"};case"w":return{kind:"word"};case"W":return{kind:"non-word"};default:return{kind:"unknown"}}}function sW($,J){if($===null||J===null)return!0;if($.kind==="literal"&&J.kind==="literal")return $.value===J.value;if($.kind==="whitespace"&&J.kind==="non-whitespace"||$.kind==="non-whitespace"&&J.kind==="whitespace"||$.kind==="digit"&&J.kind==="non-digit"||$.kind==="non-digit"&&J.kind==="digit"||$.kind==="word"&&J.kind==="non-word"||$.kind==="non-word"&&J.kind==="word")return!1;return!0}function Tq($,J){if($[J+1]!=="?")return{next:J+1,capturing:!0};if($[J+2]==="<"){let Q=$[J+3];if(Q==="="||Q==="!")return{next:J+4,capturing:!1};let Y=$.indexOf(">",J+3);return{next:Y===-1?J+3:Y+1,capturing:!0}}return{next:J+3,capturing:!1}}function Sq($,J){let X=$[J];if(X==="*"||X==="+")return{next:$[J+1]==="?"?J+2:J+1,unbounded:!0};if(X==="?")return{next:$[J+1]==="?"?J+2:J+1,unbounded:!1};if(X!=="{")return null;let Q=J+1,Y=Q;while(/[0-9]/.test($[Q]??""))Q++;if(Q===Y)return null;let G=Number($.slice(Y,Q)),W=G,M=!1;if($[Q]===","){Q++;let U=Q;while(/[0-9]/.test($[Q]??""))Q++;if(Q===U)M=!0,W=void 0;else W=Number($.slice(U,Q))}if($[Q]!=="}")return null;if(!Number.isFinite(G)||G>4096||W!==void 0&&(!Number.isFinite(W)||W>4096))return{next:Q+1,unbounded:M,error:"finite repetitions must be at most 4096"};if(Q++,$[Q]==="?")Q++;return{next:Q,unbounded:M}}function Iq($){let J=[{previousAtom:null,lastAtom:null,atomCount:0,simpleClass:null,containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1}],X=0,Q=()=>J[J.length-1],Y=(G)=>{let W=Q();if(W.lastAtom?.hasUnboundedQuantifier&&G.hasUnboundedQuantifier&&W.lastAtom.repeatClass!==null&&G.repeatClass!==null&&sW(W.lastAtom.repeatClass,G.repeatClass))W.error="adjacent unbounded repetition with overlapping input is not supported";if(W.previousAtom=W.lastAtom,W.lastAtom=G,W.atomCount===0)W.simpleClass=G.repeatClass;else W.simpleClass=null;if(W.atomCount++,G.kind==="group")W.containsQuantifier||=G.containsQuantifier,W.containsAlternation||=G.containsAlternation;W.hasUnboundedQuantifier||=G.hasUnboundedQuantifier};for(let G=0;G<$.length;){if(Q().error!==void 0)return{groupCount:X,error:Q().error};let W=$[G];if(W==="\\"){let U=$[G+1];if(U!==void 0&&/[1-9]/.test(U)||U==="k"&&$[G+2]==="<")return{groupCount:X,error:"backreferences are not supported by the safe extractor"};let O=U==="b"||U==="B";if(Y({kind:"token",containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1,repeatClass:jq(U)}),G+=U===void 0?1:2,O)Q().previousAtom=null,Q().lastAtom=null;continue}if(W==="["){Y({kind:"token",containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1,repeatClass:{kind:"unknown"}}),G=Bq($,G);continue}if(W==="("){let U=Tq($,G);if(U.capturing)X++;J.push({previousAtom:null,lastAtom:null,atomCount:0,simpleClass:null,containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1}),G=U.next;continue}if(W===")"){if(J.length>1){let U=J.pop();if(U.error!==void 0)return{groupCount:X,error:U.error};Y({kind:"group",containsQuantifier:U.containsQuantifier,containsAlternation:U.containsAlternation,hasUnboundedQuantifier:U.hasUnboundedQuantifier,repeatClass:U.atomCount===1&&!U.containsAlternation?U.simpleClass:null})}G++;continue}if(W==="|"){Q().containsAlternation=!0,Q().previousAtom=null,Q().lastAtom=null,G++;continue}let M=Sq($,G);if(M!==null){if(M.error)return{groupCount:X,error:M.error};let U=Q(),O=U.lastAtom;if(M.unbounded&&O?.kind==="group"&&(O.containsQuantifier||O.containsAlternation))return{groupCount:X,error:"nested unbounded repetition or unbounded alternation is not supported"};if(M.unbounded&&U.previousAtom?.hasUnboundedQuantifier&&O!==null&&U.previousAtom.repeatClass!==null&&O.repeatClass!==null&&sW(U.previousAtom.repeatClass,O.repeatClass))return{groupCount:X,error:"adjacent unbounded repetition with overlapping input is not supported"};if(U.containsQuantifier=!0,O!==null)U.lastAtom={...O,containsQuantifier:!0,hasUnboundedQuantifier:O.hasUnboundedQuantifier||M.unbounded};U.hasUnboundedQuantifier||=M.unbounded,G=M.next;continue}if(W!=="^"&&W!=="$")Y({kind:"token",containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1,repeatClass:W==="."?{kind:"any"}:{kind:"literal",value:W}});else Q().previousAtom=null,Q().lastAtom=null;G++}return{groupCount:X,error:Q().error}}function e8($){if($.length>2048)throw Error("Credential extract pattern exceeds the 2048-character limit");let J;try{J=new RegExp($)}catch{throw Error("Credential extract pattern is not a valid regular expression")}let X=Iq($);if(X.error!==void 0)throw Error(`Credential extract pattern rejected: ${X.error}`);return{regex:J,groupCount:X.groupCount}}function Cq($,J=""){e8($);try{return new RegExp($,J)}catch{throw Error("Credential extract pattern is not supported by this runtime")}}function oY($,J,X,Q={}){if($.length>1048576)throw Error("Credential extraction input exceeds the 1048576-character limit");let Y=Cq(J,"gd"),G=new Map,W=new Map,M=[],U=0;for(let H of $.matchAll(Y)){if(U++,U>4096)throw Error("Credential extraction exceeds the 4096-match limit");let q=H[1];if(q===void 0)throw Error(`Credential extraction matched at offset ${H.index} without a group-1 capture; group 1 must capture the credential value on every match.`);if(q.length===0)continue;let E=G.get(q);if(E===void 0)G.set(q,E=G.size);let[K,R]=H.indices[1],L=X(q,E);if(!W.has(q))W.set(q,L);M.push({start:K,end:R,sentinel:L})}if(G.size===0)return null;if(Q.maskDuplicates){let H=[...G.keys()].sort((q,E)=>E.length-q.length);for(let q of H){let E=W.get(q);if(E===q)continue;for(let K=$.indexOf(q);K!==-1;K=$.indexOf(q,K+1)){let R=K+q.length;if(M.some((L)=>K<L.end&&L.start<R))continue;M.push({start:K,end:R,sentinel:E})}}M.sort((q,E)=>q.start-E.start)}let O="",V=0;for(let H of M)O+=$.slice(V,H.start)+H.sentinel,V=H.end;return{fakeContent:O+$.slice(V),captures:[...G.keys()]}}var rW="(eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)";function $G($){try{return JSON.parse(Buffer.from($,"base64url").toString("utf8"))}catch{return}}function aY($){let J=$.split(".");if(J.length!==3)return!1;let X=$G(J[0]);if(typeof X!=="object"||X===null||!("alg"in X))return!1;return $G(J[1])!==void 0}var wq=9999999999,tW="c3J0LWZha2U";function JG($){return Buffer.from($,"utf8").toString("base64url")}function sY($){let J=JG(JSON.stringify({alg:"HS256",typ:"JWT"})),X=JG(JSON.stringify({sub:xX+$,exp:wq}));return`${J}.${X}.${tW}`}function rY($,J,X){let[Q,Y]=$.split("."),G=$G(Y??"");if(typeof G!=="object"||G===null||Array.isArray(G))return null;let W=G,M=[];for(let O of J){let V=W[O];if(typeof V==="string")M.push([O,V])}if(M.length===0)return null;let U=new Map;for(let[O,V]of M){let H=X(O,V);W[O]=H,U.set(O,H)}return{fakeToken:`${Q}.${JG(JSON.stringify(W))}.${tW}`,claimSentinels:U}}var xq="file:";class QG{dir;byKey=new Map;write($,J){if(this.dir===void 0)this.dir=pJ.mkdtempSync(eW(_q(),"srt-credmask-"));let X=this.byKey.get($);if(X===void 0)X=eW(this.dir,`${this.byKey.size}.fake`),this.byKey.set($,X);return pJ.rmSync(X,{force:!0}),pJ.writeFileSync(X,J,{mode:384}),X}dispose(){if(this.dir!==void 0)try{pJ.rmSync(this.dir,{recursive:!0,force:!0})}catch($){Z(`MaskedFileStore cleanup failed: ${$}`,{level:"error"})}this.dir=void 0,this.byKey.clear()}get dirPath(){return this.dir}}function $4($,J,X,Q){let Y=[],G=[];for(let W of $){if(W.mode!=="mask")continue;let M=e$(W.path),U;try{if(pJ.statSync(M).isDirectory()){Z(`[credential-mask] Skipping masked file entry that resolves to a directory: ${W.path} \u2014 use mode "deny" for directories.`,{level:"warn"});continue}let K=pJ.readFileSync(M);if(U=K.toString("utf8"),Buffer.byteLength(U,"utf8")!==K.length){Z(`[credential-mask] Skipping masked file with non-UTF-8 content (binary credential files are not supported in mask mode): ${W.path}`,{level:"warn"});continue}}catch(E){Z(`[credential-mask] Skipping masked file (unreadable on host): ${W.path} \u2014 ${E.message}`);continue}let O=W.injectHosts??J,V=xq+M,H;if(W.extract===void 0&&W.decode===void 0)H=X.register(V,U,O);else{let E=W.extract??rW,K=0,R=oY(U,E,(L,D)=>{if(W.decode==="jwt"&&!aY(L))return L;let w=`${V}#${D}`;if(W.decode==="jwt"&&W.maskClaims?.length){let T=rY(L,W.maskClaims,(S,C)=>X.register(`${V}#jwt${D}.${S}`,C,O));if(T===null)return Z(`[credential-mask] ${W.path}: verified JWT candidate has none of maskClaims ${JSON.stringify(W.maskClaims)} as `+"string claims \u2014 left unmasked."),L;let P=W.maskClaims.filter((S)=>!T.claimSentinels.has(S));if(P.length>0)Z(`[credential-mask] ${W.path}: maskClaims ${JSON.stringify(P)} absent or non-string in a `+"verified JWT \u2014 skipped.");return K++,X.registerWithSentinel(w,T.fakeToken,L,O)}return K++,W.decode==="jwt"?X.registerWithSentinel(w,sY(Pq()),L,O):X.register(w,L,O)},{maskDuplicates:W.maskDuplicates??!1});if(R===null||K===0){let L=W.decode==="jwt"?W.maskClaims?.length?`decode "jwt" with pattern "${E}" that matched no verified JWT with maskable claims (maskClaims: ${JSON.stringify(W.maskClaims)})`:`decode "jwt" with pattern "${E}" that matched no verified JWT`:`extract pattern "${E}" that matched nothing`,D=W.onExtractNoMatch??"warn";if(D==="error")throw Error(`credentials.files entry "${W.path}": ${L} (onExtractNoMatch: "error"). Fix the config, change to "warn"/"deny", or remove the entry.`);if(D==="deny"){Z(`[credential-mask] ${W.path} has ${L} \u2014 degrading to `+'mode "deny".',{level:"warn"}),G.push(M);continue}let w=`[sandbox-runtime] WARNING: credentials.files entry "${W.path}" has ${L} in the file. The file is left UNPROTECTED (readable as-is inside the sandbox). Fix the config, set onExtractNoMatch to "deny" or "error", or remove the entry.`;console.warn(w),Z(w,{level:"warn"});continue}H=R.fakeContent}let q=Q.write(V,H);Y.push({realPath:M,fakePath:q})}return{binds:Y,degradeToDenyPaths:G}}import{randomUUID as vq}from"crypto";var tY="env:";function J4($,J,X,Q=process.env){let Y={},G=[];for(let W of $){if(W.mode!=="mask")continue;let M=Q[W.name];if(M===void 0)continue;let U=W.injectHosts??J;if(W.decode==="jwt"){if(!aY(M)){let V=`[sandbox-runtime] WARNING: credentials.envVars entry "${W.name}" has decode "jwt" but its value did not verify as a JWT. The variable is left UNPROTECTED (real value visible as-is inside the sandbox). Fix the config or remove the entry.`;console.warn(V),Z(V,{level:"warn"});continue}if(W.maskClaims?.length){let V=rY(M,W.maskClaims,(q,E)=>X.register(`${tY}${W.name}#${q}`,E,U));if(V===null){let q=`[sandbox-runtime] WARNING: credentials.envVars entry "${W.name}" has maskClaims ${JSON.stringify(W.maskClaims)} but none is present as a string claim in its JWT value. The variable is left UNPROTECTED (real value visible as-is inside the sandbox). Fix the config or remove the entry.`;console.warn(q),Z(q,{level:"warn"});continue}let H=W.maskClaims.filter((q)=>!V.claimSentinels.has(q));if(H.length>0)Z(`[credential-mask] env var "${W.name}": maskClaims ${JSON.stringify(H)} absent or non-string in the `+"JWT \u2014 skipped.");Y[W.name]=X.registerWithSentinel(`${tY}${W.name}`,V.fakeToken,M,U);continue}Y[W.name]=X.registerWithSentinel(`${tY}${W.name}`,sY(vq()),M,U);continue}if(W.extract===void 0){Y[W.name]=X.register(W.name,M,U);continue}let O=oY(M,W.extract,(V,H)=>X.register(`${tY}${W.name}#${H}`,V,U));if(O===null){let V=W.onExtractNoMatch??"warn";if(V==="error")throw Error(`credentials.envVars entry "${W.name}": extract pattern "${W.extract}" matched nothing (onExtractNoMatch: "error"). Fix the regex, change to "warn"/"deny", or remove the entry.`);if(V==="deny"){Z(`[credential-mask] extract pattern /${W.extract}/ matched nothing in the value of ${W.name} \u2014 unsetting the variable.`,{level:"warn"}),G.push(W.name);continue}let H=`[sandbox-runtime] WARNING: credentials.envVars entry "${W.name}" has extract pattern "${W.extract}" that matched nothing in the variable's value. The variable is left UNPROTECTED (visible as-is inside the sandbox). Fix the regex, set onExtractNoMatch to "deny" or "error", or remove the entry.`;console.warn(H),Z(H,{level:"warn"});continue}Y[W.name]=O.fakeContent}return{setEnvVars:Y,degradeToUnsetNames:G}}var Q4="AWS_ACCESS_KEY_ID",X4="AWS_SECRET_ACCESS_KEY",Y4="AWS_SESSION_TOKEN";class XG{bySentinel=new Map;register($){this.bySentinel.set($.accessKeyIdSentinel,$)}lookup($){return this.bySentinel.get($)}get size(){return this.bySentinel.size}clear(){this.bySentinel.clear()}}function G4($,J,X,Q,Y,G=process.env){let W=[...J??[]],M=new Set(W.flatMap((H)=>[H.accessKeyIdVar,H.secretAccessKeyVar,...H.sessionTokenVar?[H.sessionTokenVar]:[]]));if(![Q4,X4,Y4].some((H)=>M.has(H)))W.push({accessKeyIdVar:Q4,secretAccessKeyVar:X4,sessionTokenVar:Y4});let O=(H)=>$.find((q)=>q.name===H&&q.mode==="mask"&&q.extract===void 0&&q.decode===void 0),V=(H)=>O(H)!==void 0?Q[H]:void 0;for(let H of W){let q=V(H.accessKeyIdVar),E=V(H.secretAccessKeyVar)!==void 0,K=G[H.accessKeyIdVar],R=G[H.secretAccessKeyVar];if(q===void 0||!E||K===void 0||R===void 0){if(E&&q===void 0){let T=`[sandbox-runtime] WARNING: "${H.secretAccessKeyVar}" is masked but "${H.accessKeyIdVar}" is not, so no AWS credential pair was registered. SigV4 requests will be signed with the masked placeholder secret and the proxy cannot `+"detect or re-sign them \u2014 they will fail upstream. Mask both "+"variables (whole-value) to enable re-signing.";console.warn(T),Z(T,{level:"warn"})}continue}let L=O(H.accessKeyIdVar),w=(H.sessionTokenVar!==void 0?V(H.sessionTokenVar):void 0)!==void 0&&H.sessionTokenVar!==void 0?G[H.sessionTokenVar]:void 0;Y.register({accessKeyIdSentinel:q,realAccessKeyId:K,realSecretAccessKey:R,...w!==void 0?{realSessionToken:w}:{},injectHosts:L.injectHosts??X}),Z(`[credential-aws] registered SigV4 pair for ${H.accessKeyIdVar}/${H.secretAccessKeyVar}`+(w!==void 0?" (+session token)":""))}}function kq($){return{streaming:$?.streaming??"deny",presigned:$?.presigned??"deny",sigv4a:$?.sigv4a??"deny"}}function W4($,J,X){let Q=kq(J);return(Y,G,W,M)=>{if($.size===0)return;let U=TW(W,G);if(U===null)return;let O=$.lookup(U.accessKeyId);if(O===void 0)return;if(!O.injectHosts.some((K)=>X(M,K)))return;if(U.kind!=="header-sigv4"){if(Q[U.kind]==="passthrough"){Z(`[credential-aws] ${U.kind} request with masked credential passed through un-resigned per credentials.sigv4.${U.kind} (its signature covers the placeholder secret and will fail upstream)`);return}return{action:"deny",reason:`AWS SigV4 ${U.kind} request uses a masked credential but cannot be re-signed by the sandbox proxy; denied by policy. Set credentials.sigv4.${U.kind} to "passthrough" to forward it unmodified (it will fail upstream: the signature covers the masked placeholder).`}}let V=SW(hQ(W.authorization));if(V===null)return{action:"deny",reason:"AWS SigV4 request uses a masked credential but its Authorization header is malformed; the proxy cannot re-sign it."};let H=hQ(W["x-amz-date"]);if(H===void 0)return{action:"deny",reason:"AWS SigV4 request uses a masked credential but carries no x-amz-date header; the proxy cannot re-sign it."};let q=[...V.signedHeaders];for(let K of q){if(K==="host")continue;if(K==="x-amz-security-token"&&O.realSessionToken!==void 0)continue;if(W[K]===void 0)return{action:"deny",reason:`AWS SigV4 request uses a masked credential but signed header "${K}" is missing; the proxy cannot re-sign it.`}}if(O.realSessionToken!==void 0&&!q.includes("x-amz-security-token"))q.push("x-amz-security-token");let E=hQ(W["x-amz-content-sha256"]);return{action:"resign",payloadHash:E===pY?pY:void 0,apply(K,R,L){if(O.realSessionToken!==void 0)K["x-amz-security-token"]=O.realSessionToken;if(K["x-amz-content-sha256"]!==void 0&&E!==pY)K["x-amz-content-sha256"]=L;let{authorization:D}=IW({method:Y,requestTarget:G,headers:K,hostHeader:R,signedHeaders:q,payloadHash:L,amzDate:H,scope:{date:V.date,region:V.region,service:V.service},accessKeyId:O.realAccessKeyId,secretAccessKey:O.realSecretAccessKey});K.authorization=D}}}}import{spawnSync as fq}from"child_process";function N0($){if(typeof globalThis.Bun<"u")return globalThis.Bun.which($);let J=fq("which",[$],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:1000});if(J.status===0&&J.stdout)return J.stdout.trim();return null}import*as g0 from"fs";import{randomBytes as CK}from"crypto";function IJ($){return $.map((J)=>{if(J==="")return"''";if(/^[A-Za-z0-9_./:@+,-][A-Za-z0-9_./:=@+,-]*$/.test(J))return J;return"'"+J.replace(/'/g,`'"'"'`)+"'"}).join(" ")}import{randomBytes as dq}from"crypto";import*as J$ from"fs";import{spawn as V4}from"child_process";import{tmpdir as OG}from"os";import k$,{join as H4}from"path";import{spawn as yq}from"child_process";import{text as M4}from"stream/consumers";async function U4($,J,X,Q={command:"rg"}){let{command:Y,args:G=[],argv0:W}=Q,M=yq(Y,[...G,...$,J],{argv0:W,signal:X,timeout:1e4,windowsHide:!0}),[U,O,V]=await Promise.all([M4(M.stdout),M4(M.stderr),new Promise((H,q)=>{M.on("close",H),M.on("error",q)})]);if(V===0)return U.trim().split(`
|
|
61
|
+
`)}),U.on("error",()=>O.destroy()),U.once("close",()=>O.destroy()),O.once("close",()=>U.destroy()),U.pipe(O),O.pipe(U)}let M=Kq((U)=>{G.add(U),U.once("close",()=>G.delete(U)),U.on("error",(V)=>Z(`mux: client socket error: ${V.message}`));let O=setTimeout(()=>{Z("mux: first-byte timeout; destroying connection"),U.destroy()},J);if(typeof O.unref==="function")O.unref();U.once("readable",()=>{clearTimeout(O);let V=U.read(1);if(!V||V.length===0){U.destroy();return}if(U.unshift(V),Fq.has(V[0]))$.handleSocksConnection(U);else W(U)})});return{server:M,getPort(){let U=M.address();return U&&typeof U==="object"?U.port:void 0},async listenHttpBackend(){if(!X){let O=Rq();await iW(O).catch(()=>{}),await new Promise((V,H)=>{$.httpServer.once("error",H),$.httpServer.listen(O,()=>{$.httpServer.removeListener("error",H),V()})}),Q=O,Z(`mux: HTTP backend listening on ${O}`);return}await iY($.httpServer,(O)=>$.httpServer.listen(O,"127.0.0.1"),$.httpBackendPortRange,new Set);let U=$.httpServer.address();return Y=U&&typeof U==="object"?U.port:void 0,Z(`mux: HTTP backend listening on 127.0.0.1:${Y}`),Y},async close(){for(let U of G)U.destroy();if(G.clear(),await new Promise((U)=>M.close(()=>U())),await new Promise((U)=>$.httpServer.close(()=>U())),Q)await iW(Q).catch(()=>{}),Q=void 0;Y=void 0},unref(){M.unref(),$.httpServer.unref()}}}import{randomBytes as Aq,randomUUID as Dq}from"crypto";var xX="fake_value_",aW="abcdefghijklmnopqrstuvwxyz0123456789_-";function Zq($){let J=xX+Dq(),X=Buffer.byteLength($)-J.length;if(X<=0)return J;let Q=J;for(let Y of Aq(X))Q+=aW[Y%aW.length];return Q}class t8{byName=new Map;bySentinel=new Map;allSentinelsPrefixed=!0;register($,J,X){return this.registerWithSentinel($,Zq(J),J,X)}registerWithSentinel($,J,X,Q){let Y=this.byName.get($);if(Y!==void 0)return Y.realValue=X,Y.injectHosts=Q,Y.sentinel;if(!J.startsWith(xX))this.allSentinelsPrefixed=!1;let G={name:$,sentinel:J,realValue:X,injectHosts:Q};return this.byName.set($,G),this.bySentinel.set(J,G),J}lookupReal($){return this.bySentinel.get($)?.realValue}namesInjectableAt($,J){let X=[];for(let Q of this.byName.values())if(Q.injectHosts.some((Y)=>J($,Y)))X.push(Q.name);return X}sentinelsForHost($,J){let X=[];for(let Q of this.bySentinel.values()){if(!Q.injectHosts.some((Y)=>J($,Y)))continue;X.push({sentinel:Buffer.from(Q.sentinel),realValue:Buffer.from(Q.realValue)})}return X}*entries(){for(let $ of this.bySentinel.values())yield[$.sentinel,$.realValue]}get size(){return this.bySentinel.size}clear(){this.byName.clear(),this.bySentinel.clear(),this.allSentinelsPrefixed=!0}substituteInHeaders($,J,X){if(this.bySentinel.size===0)return;for(let[Q,Y]of Object.entries($)){if(Y===void 0)continue;if(Array.isArray(Y))for(let G=0;G<Y.length;G++)Y[G]=this.substituteInHeaderValue(Q,Y[G],J,X);else $[Q]=this.substituteInHeaderValue(Q,Y,J,X)}}substituteInHeaderValue($,J,X,Q){let Y=this.substituteInString(J,X,Q);if($.toLowerCase()!=="authorization")return Y;let G=/^(\s*basic\s+)([a-z0-9+/]+={0,2})(\s*)$/i.exec(Y);if(G===null)return Y;let W=G[2],M=Buffer.from(W,"base64");if(W.length%4!==0||M.toString("base64")!==W)return Y;let U=M.toString("utf8");if(!Buffer.from(U,"utf8").equals(M))return Y;let O=this.substituteInString(U,X,Q);if(O===U)return Y;return`${G[1]}${Buffer.from(O,"utf8").toString("base64")}${G[3]}`}substituteInString($,J,X){if(this.allSentinelsPrefixed&&!$.includes(xX))return $;let Q=$;for(let Y of this.bySentinel.values()){if(!Q.includes(Y.sentinel))continue;if(!Y.injectHosts.some((G)=>X(J,G)))continue;Q=Q.split(Y.sentinel).join(Y.realValue)}return Q}}import{randomUUID as Pq}from"crypto";import*as pJ from"fs";import{tmpdir as _q}from"os";import{join as eW}from"path";function Bq($,J){let X=!1;for(let Q=J+1;Q<$.length;Q++){let Y=$[Q];if(X){X=!1;continue}if(Y==="\\")X=!0;else if(Y==="]")return Q+1}return $.length}function jq($){switch($){case"s":return{kind:"whitespace"};case"S":return{kind:"non-whitespace"};case"d":return{kind:"digit"};case"D":return{kind:"non-digit"};case"w":return{kind:"word"};case"W":return{kind:"non-word"};default:return{kind:"unknown"}}}function sW($,J){if($===null||J===null)return!0;if($.kind==="literal"&&J.kind==="literal")return $.value===J.value;if($.kind==="whitespace"&&J.kind==="non-whitespace"||$.kind==="non-whitespace"&&J.kind==="whitespace"||$.kind==="digit"&&J.kind==="non-digit"||$.kind==="non-digit"&&J.kind==="digit"||$.kind==="word"&&J.kind==="non-word"||$.kind==="non-word"&&J.kind==="word")return!1;return!0}function Tq($,J){if($[J+1]!=="?")return{next:J+1,capturing:!0};if($[J+2]==="<"){let Q=$[J+3];if(Q==="="||Q==="!")return{next:J+4,capturing:!1};let Y=$.indexOf(">",J+3);return{next:Y===-1?J+3:Y+1,capturing:!0}}return{next:J+3,capturing:!1}}function Sq($,J){let X=$[J];if(X==="*"||X==="+")return{next:$[J+1]==="?"?J+2:J+1,unbounded:!0};if(X==="?")return{next:$[J+1]==="?"?J+2:J+1,unbounded:!1};if(X!=="{")return null;let Q=J+1,Y=Q;while(/[0-9]/.test($[Q]??""))Q++;if(Q===Y)return null;let G=Number($.slice(Y,Q)),W=G,M=!1;if($[Q]===","){Q++;let U=Q;while(/[0-9]/.test($[Q]??""))Q++;if(Q===U)M=!0,W=void 0;else W=Number($.slice(U,Q))}if($[Q]!=="}")return null;if(!Number.isFinite(G)||G>4096||W!==void 0&&(!Number.isFinite(W)||W>4096))return{next:Q+1,unbounded:M,error:"finite repetitions must be at most 4096"};if(Q++,$[Q]==="?")Q++;return{next:Q,unbounded:M}}function Iq($){let J=[{previousAtom:null,lastAtom:null,atomCount:0,simpleClass:null,containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1}],X=0,Q=()=>J[J.length-1],Y=(G)=>{let W=Q();if(W.lastAtom?.hasUnboundedQuantifier&&G.hasUnboundedQuantifier&&W.lastAtom.repeatClass!==null&&G.repeatClass!==null&&sW(W.lastAtom.repeatClass,G.repeatClass))W.error="adjacent unbounded repetition with overlapping input is not supported";if(W.previousAtom=W.lastAtom,W.lastAtom=G,W.atomCount===0)W.simpleClass=G.repeatClass;else W.simpleClass=null;if(W.atomCount++,G.kind==="group")W.containsQuantifier||=G.containsQuantifier,W.containsAlternation||=G.containsAlternation;W.hasUnboundedQuantifier||=G.hasUnboundedQuantifier};for(let G=0;G<$.length;){if(Q().error!==void 0)return{groupCount:X,error:Q().error};let W=$[G];if(W==="\\"){let U=$[G+1];if(U!==void 0&&/[1-9]/.test(U)||U==="k"&&$[G+2]==="<")return{groupCount:X,error:"backreferences are not supported by the safe extractor"};let O=U==="b"||U==="B";if(Y({kind:"token",containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1,repeatClass:jq(U)}),G+=U===void 0?1:2,O)Q().previousAtom=null,Q().lastAtom=null;continue}if(W==="["){Y({kind:"token",containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1,repeatClass:{kind:"unknown"}}),G=Bq($,G);continue}if(W==="("){let U=Tq($,G);if(U.capturing)X++;J.push({previousAtom:null,lastAtom:null,atomCount:0,simpleClass:null,containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1}),G=U.next;continue}if(W===")"){if(J.length>1){let U=J.pop();if(U.error!==void 0)return{groupCount:X,error:U.error};Y({kind:"group",containsQuantifier:U.containsQuantifier,containsAlternation:U.containsAlternation,hasUnboundedQuantifier:U.hasUnboundedQuantifier,repeatClass:U.atomCount===1&&!U.containsAlternation?U.simpleClass:null})}G++;continue}if(W==="|"){Q().containsAlternation=!0,Q().previousAtom=null,Q().lastAtom=null,G++;continue}let M=Sq($,G);if(M!==null){if(M.error)return{groupCount:X,error:M.error};let U=Q(),O=U.lastAtom;if(M.unbounded&&O?.kind==="group"&&(O.containsQuantifier||O.containsAlternation))return{groupCount:X,error:"nested unbounded repetition or unbounded alternation is not supported"};if(M.unbounded&&U.previousAtom?.hasUnboundedQuantifier&&O!==null&&U.previousAtom.repeatClass!==null&&O.repeatClass!==null&&sW(U.previousAtom.repeatClass,O.repeatClass))return{groupCount:X,error:"adjacent unbounded repetition with overlapping input is not supported"};if(U.containsQuantifier=!0,O!==null)U.lastAtom={...O,containsQuantifier:!0,hasUnboundedQuantifier:O.hasUnboundedQuantifier||M.unbounded};U.hasUnboundedQuantifier||=M.unbounded,G=M.next;continue}if(W!=="^"&&W!=="$")Y({kind:"token",containsQuantifier:!1,containsAlternation:!1,hasUnboundedQuantifier:!1,repeatClass:W==="."?{kind:"any"}:{kind:"literal",value:W}});else Q().previousAtom=null,Q().lastAtom=null;G++}return{groupCount:X,error:Q().error}}function e8($){if($.length>2048)throw Error("Credential extract pattern exceeds the 2048-character limit");let J;try{J=new RegExp($)}catch{throw Error("Credential extract pattern is not a valid regular expression")}let X=Iq($);if(X.error!==void 0)throw Error(`Credential extract pattern rejected: ${X.error}`);return{regex:J,groupCount:X.groupCount}}function Cq($,J=""){e8($);try{return new RegExp($,J)}catch{throw Error("Credential extract pattern is not supported by this runtime")}}function oY($,J,X,Q={}){if($.length>1048576)throw Error("Credential extraction input exceeds the 1048576-character limit");let Y=Cq(J,"gd"),G=new Map,W=new Map,M=[],U=0;for(let H of $.matchAll(Y)){if(U++,U>4096)throw Error("Credential extraction exceeds the 4096-match limit");let q=H[1];if(q===void 0)throw Error(`Credential extraction matched at offset ${H.index} without a group-1 capture; group 1 must capture the credential value on every match.`);if(q.length===0)continue;let E=G.get(q);if(E===void 0)G.set(q,E=G.size);let[K,R]=H.indices[1],L=X(q,E);if(!W.has(q))W.set(q,L);M.push({start:K,end:R,sentinel:L})}if(G.size===0)return null;if(Q.maskDuplicates){let H=[...G.keys()].sort((q,E)=>E.length-q.length);for(let q of H){let E=W.get(q);if(E===q)continue;for(let K=$.indexOf(q);K!==-1;K=$.indexOf(q,K+1)){let R=K+q.length;if(M.some((L)=>K<L.end&&L.start<R))continue;M.push({start:K,end:R,sentinel:E})}}M.sort((q,E)=>q.start-E.start)}let O="",V=0;for(let H of M)O+=$.slice(V,H.start)+H.sentinel,V=H.end;return{fakeContent:O+$.slice(V),captures:[...G.keys()]}}var rW="(eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+)";function $G($){try{return JSON.parse(Buffer.from($,"base64url").toString("utf8"))}catch{return}}function aY($){let J=$.split(".");if(J.length!==3)return!1;let X=$G(J[0]);if(typeof X!=="object"||X===null||!("alg"in X))return!1;return $G(J[1])!==void 0}var wq=9999999999,tW="c3J0LWZha2U";function JG($){return Buffer.from($,"utf8").toString("base64url")}function sY($){let J=JG(JSON.stringify({alg:"HS256",typ:"JWT"})),X=JG(JSON.stringify({sub:xX+$,exp:wq}));return`${J}.${X}.${tW}`}function rY($,J,X){let[Q,Y]=$.split("."),G=$G(Y??"");if(typeof G!=="object"||G===null||Array.isArray(G))return null;let W=G,M=[];for(let O of J){let V=W[O];if(typeof V==="string")M.push([O,V])}if(M.length===0)return null;let U=new Map;for(let[O,V]of M){let H=X(O,V);W[O]=H,U.set(O,H)}return{fakeToken:`${Q}.${JG(JSON.stringify(W))}.${tW}`,claimSentinels:U}}var xq="file:";class QG{dir;byKey=new Map;write($,J){if(this.dir===void 0)this.dir=pJ.mkdtempSync(eW(_q(),"srt-credmask-"));let X=this.byKey.get($);if(X===void 0)X=eW(this.dir,`${this.byKey.size}.fake`),this.byKey.set($,X);return pJ.rmSync(X,{force:!0}),pJ.writeFileSync(X,J,{mode:384}),X}dispose(){if(this.dir!==void 0)try{pJ.rmSync(this.dir,{recursive:!0,force:!0})}catch($){Z(`MaskedFileStore cleanup failed: ${$}`,{level:"error"})}this.dir=void 0,this.byKey.clear()}get dirPath(){return this.dir}}function $4($,J,X,Q){let Y=[],G=[];for(let W of $){if(W.mode!=="mask")continue;let M=e$(W.path),U;try{if(pJ.statSync(M).isDirectory()){Z(`[credential-mask] Skipping masked file entry that resolves to a directory: ${W.path} \u2014 use mode "deny" for directories.`,{level:"warn"});continue}let K=pJ.readFileSync(M);if(U=K.toString("utf8"),Buffer.byteLength(U,"utf8")!==K.length){Z(`[credential-mask] Skipping masked file with non-UTF-8 content (binary credential files are not supported in mask mode): ${W.path}`,{level:"warn"});continue}}catch(E){Z(`[credential-mask] Skipping masked file (unreadable on host): ${W.path} \u2014 ${E.message}`);continue}let O=W.injectHosts??J,V=xq+M,H;if(W.extract===void 0&&W.decode===void 0)H=X.register(V,U,O);else{let E=W.extract??rW,K=0,R=oY(U,E,(L,D)=>{if(W.decode==="jwt"&&!aY(L))return L;let w=`${V}#${D}`;if(W.decode==="jwt"&&W.maskClaims?.length){let T=rY(L,W.maskClaims,(S,C)=>X.register(`${V}#jwt${D}.${S}`,C,O));if(T===null)return Z(`[credential-mask] ${W.path}: verified JWT candidate has none of maskClaims ${JSON.stringify(W.maskClaims)} as `+"string claims \u2014 left unmasked."),L;let P=W.maskClaims.filter((S)=>!T.claimSentinels.has(S));if(P.length>0)Z(`[credential-mask] ${W.path}: maskClaims ${JSON.stringify(P)} absent or non-string in a `+"verified JWT \u2014 skipped.");return K++,X.registerWithSentinel(w,T.fakeToken,L,O)}return K++,W.decode==="jwt"?X.registerWithSentinel(w,sY(Pq()),L,O):X.register(w,L,O)},{maskDuplicates:W.maskDuplicates??!1});if(R===null||K===0){let L=W.decode==="jwt"?W.maskClaims?.length?`decode "jwt" with pattern "${E}" that matched no verified JWT with maskable claims (maskClaims: ${JSON.stringify(W.maskClaims)})`:`decode "jwt" with pattern "${E}" that matched no verified JWT`:`extract pattern "${E}" that matched nothing`,D=W.onExtractNoMatch??"warn";if(D==="error")throw Error(`credentials.files entry "${W.path}": ${L} (onExtractNoMatch: "error"). Fix the config, change to "warn"/"deny", or remove the entry.`);if(D==="deny"){Z(`[credential-mask] ${W.path} has ${L} \u2014 degrading to `+'mode "deny".',{level:"warn"}),G.push(M);continue}let w=`[sandbox-runtime] WARNING: credentials.files entry "${W.path}" has ${L} in the file. The file is left UNPROTECTED (readable as-is inside the sandbox). Fix the config, set onExtractNoMatch to "deny" or "error", or remove the entry.`;console.warn(w),Z(w,{level:"warn"});continue}H=R.fakeContent}let q=Q.write(V,H);Y.push({realPath:M,fakePath:q})}return{binds:Y,degradeToDenyPaths:G}}import{randomUUID as vq}from"crypto";var tY="env:";function J4($,J,X,Q=process.env){let Y={},G=[];for(let W of $){if(W.mode!=="mask")continue;let M=Q[W.name];if(M===void 0)continue;let U=W.injectHosts??J;if(W.decode==="jwt"){if(!aY(M)){let V=`[sandbox-runtime] WARNING: credentials.envVars entry "${W.name}" has decode "jwt" but its value did not verify as a JWT. The variable is left UNPROTECTED (real value visible as-is inside the sandbox). Fix the config or remove the entry.`;console.warn(V),Z(V,{level:"warn"});continue}if(W.maskClaims?.length){let V=rY(M,W.maskClaims,(q,E)=>X.register(`${tY}${W.name}#${q}`,E,U));if(V===null){let q=`[sandbox-runtime] WARNING: credentials.envVars entry "${W.name}" has maskClaims ${JSON.stringify(W.maskClaims)} but none is present as a string claim in its JWT value. The variable is left UNPROTECTED (real value visible as-is inside the sandbox). Fix the config or remove the entry.`;console.warn(q),Z(q,{level:"warn"});continue}let H=W.maskClaims.filter((q)=>!V.claimSentinels.has(q));if(H.length>0)Z(`[credential-mask] env var "${W.name}": maskClaims ${JSON.stringify(H)} absent or non-string in the `+"JWT \u2014 skipped.");Y[W.name]=X.registerWithSentinel(`${tY}${W.name}`,V.fakeToken,M,U);continue}Y[W.name]=X.registerWithSentinel(`${tY}${W.name}`,sY(vq()),M,U);continue}if(W.extract===void 0){Y[W.name]=X.register(W.name,M,U);continue}let O=oY(M,W.extract,(V,H)=>X.register(`${tY}${W.name}#${H}`,V,U));if(O===null){let V=W.onExtractNoMatch??"warn";if(V==="error")throw Error(`credentials.envVars entry "${W.name}": extract pattern "${W.extract}" matched nothing (onExtractNoMatch: "error"). Fix the regex, change to "warn"/"deny", or remove the entry.`);if(V==="deny"){Z(`[credential-mask] extract pattern /${W.extract}/ matched nothing in the value of ${W.name} \u2014 unsetting the variable.`,{level:"warn"}),G.push(W.name);continue}let H=`[sandbox-runtime] WARNING: credentials.envVars entry "${W.name}" has extract pattern "${W.extract}" that matched nothing in the variable's value. The variable is left UNPROTECTED (visible as-is inside the sandbox). Fix the regex, set onExtractNoMatch to "deny" or "error", or remove the entry.`;console.warn(H),Z(H,{level:"warn"});continue}Y[W.name]=O.fakeContent}return{setEnvVars:Y,degradeToUnsetNames:G}}var Q4="AWS_ACCESS_KEY_ID",X4="AWS_SECRET_ACCESS_KEY",Y4="AWS_SESSION_TOKEN";class XG{bySentinel=new Map;register($){this.bySentinel.set($.accessKeyIdSentinel,$)}lookup($){return this.bySentinel.get($)}get size(){return this.bySentinel.size}clear(){this.bySentinel.clear()}}function G4($,J,X,Q,Y,G=process.env){let W=[...J??[]],M=new Set(W.flatMap((H)=>[H.accessKeyIdVar,H.secretAccessKeyVar,...H.sessionTokenVar?[H.sessionTokenVar]:[]]));if(![Q4,X4,Y4].some((H)=>M.has(H)))W.push({accessKeyIdVar:Q4,secretAccessKeyVar:X4,sessionTokenVar:Y4});let O=(H)=>$.find((q)=>q.name===H&&q.mode==="mask"&&q.extract===void 0&&q.decode===void 0),V=(H)=>O(H)!==void 0?Q[H]:void 0;for(let H of W){let q=V(H.accessKeyIdVar),E=V(H.secretAccessKeyVar)!==void 0,K=G[H.accessKeyIdVar],R=G[H.secretAccessKeyVar];if(q===void 0||!E||K===void 0||R===void 0){if(E&&q===void 0){let T=`[sandbox-runtime] WARNING: "${H.secretAccessKeyVar}" is masked but "${H.accessKeyIdVar}" is not, so no AWS credential pair was registered. SigV4 requests will be signed with the masked placeholder secret and the proxy cannot `+"detect or re-sign them \u2014 they will fail upstream. Mask both "+"variables (whole-value) to enable re-signing.";console.warn(T),Z(T,{level:"warn"})}continue}let L=O(H.accessKeyIdVar),w=(H.sessionTokenVar!==void 0?V(H.sessionTokenVar):void 0)!==void 0&&H.sessionTokenVar!==void 0?G[H.sessionTokenVar]:void 0;Y.register({accessKeyIdSentinel:q,realAccessKeyId:K,realSecretAccessKey:R,...w!==void 0?{realSessionToken:w}:{},injectHosts:L.injectHosts??X}),Z(`[credential-aws] registered SigV4 pair for ${H.accessKeyIdVar}/${H.secretAccessKeyVar}`+(w!==void 0?" (+session token)":""))}}function kq($){return{streaming:$?.streaming??"deny",presigned:$?.presigned??"deny",sigv4a:$?.sigv4a??"deny"}}function W4($,J,X){let Q=kq(J);return(Y,G,W,M)=>{if($.size===0)return;let U=TW(W,G);if(U===null)return;let O=$.lookup(U.accessKeyId);if(O===void 0)return;if(!O.injectHosts.some((K)=>X(M,K)))return;if(U.kind!=="header-sigv4"){if(Q[U.kind]==="passthrough"){Z(`[credential-aws] ${U.kind} request with masked credential passed through un-resigned per credentials.sigv4.${U.kind} (its signature covers the placeholder secret and will fail upstream)`);return}return{action:"deny",reason:`AWS SigV4 ${U.kind} request uses a masked credential but cannot be re-signed by the sandbox proxy; denied by policy. Set credentials.sigv4.${U.kind} to "passthrough" to forward it unmodified (it will fail upstream: the signature covers the masked placeholder).`}}let V=SW(hQ(W.authorization));if(V===null)return{action:"deny",reason:"AWS SigV4 request uses a masked credential but its Authorization header is malformed; the proxy cannot re-sign it."};let H=hQ(W["x-amz-date"]);if(H===void 0)return{action:"deny",reason:"AWS SigV4 request uses a masked credential but carries no x-amz-date header; the proxy cannot re-sign it."};let q=[...V.signedHeaders];for(let K of q){if(K==="host")continue;if(K==="x-amz-security-token"&&O.realSessionToken!==void 0)continue;if(W[K]===void 0)return{action:"deny",reason:`AWS SigV4 request uses a masked credential but signed header "${K}" is missing; the proxy cannot re-sign it.`}}if(O.realSessionToken!==void 0&&!q.includes("x-amz-security-token"))q.push("x-amz-security-token");let E=hQ(W["x-amz-content-sha256"]);return{action:"resign",payloadHash:E===pY?pY:void 0,apply(K,R,L){if(O.realSessionToken!==void 0)K["x-amz-security-token"]=O.realSessionToken;if(K["x-amz-content-sha256"]!==void 0&&E!==pY)K["x-amz-content-sha256"]=L;let{authorization:D}=IW({method:Y,requestTarget:G,headers:K,hostHeader:R,signedHeaders:q,payloadHash:L,amzDate:H,scope:{date:V.date,region:V.region,service:V.service},accessKeyId:O.realAccessKeyId,secretAccessKey:O.realSecretAccessKey});K.authorization=D}}}}import{spawnSync as fq}from"child_process";function N0($){if(typeof globalThis.Bun<"u")return globalThis.Bun.which($);let J=fq("which",[$],{encoding:"utf8",stdio:["ignore","pipe","ignore"],timeout:1000});if(J.status===0&&J.stdout)return J.stdout.trim();return null}import*as g0 from"fs";import{randomBytes as CK}from"crypto";function IJ($){return $.map((J)=>{if(J==="")return"''";if(/^[A-Za-z0-9_./:@+,-][A-Za-z0-9_./:=@+,-]*$/.test(J))return J;return"'"+J.replace(/'/g,`'"'"'`)+"'"}).join(" ")}import{randomBytes as dq}from"crypto";import*as J$ from"fs";import{spawn as V4}from"child_process";import{tmpdir as OG}from"os";import k$,{join as H4}from"path";import{spawn as yq}from"child_process";import{text as M4}from"stream/consumers";async function U4($,J,X,Q={command:"rg"}){let{command:Y,args:G=[],argv0:W}=Q,M=yq(Y,[...G,...$,J],{argv0:W,env:{PATH:process.env.PATH??"/usr/bin:/bin"},signal:X,timeout:1e4,windowsHide:!0}),[U,O,V]=await Promise.all([M4(M.stdout),M4(M.stderr),new Promise((H,q)=>{M.on("close",H),M.on("error",q)})]);if(V===0)return U.trim().split(`
|
|
62
62
|
`).filter(Boolean);if(V===1)return[];throw Error(`ripgrep failed with exit code ${V}: ${O}`)}import{join as M0,dirname as bq}from"path";import{fileURLToPath as hq}from"url";import*as eY from"fs";import{homedir as uq}from"os";var YG=new Map,GG=null;function gq(){if(GG)return GG;let $=[],J=uq();return $.push(M0("/usr","lib","node_modules","@anthropic-ai","sandbox-runtime"),M0("/usr","local","lib","node_modules","@anthropic-ai","sandbox-runtime"),M0("/opt","homebrew","lib","node_modules","@anthropic-ai","sandbox-runtime"),M0(J,".npm","lib","node_modules","@anthropic-ai","sandbox-runtime"),M0(J,".npm-global","lib","node_modules","@anthropic-ai","sandbox-runtime")),GG=$,$}function O4(){let $=process.arch;switch($){case"x64":case"x86_64":return"x64";case"arm64":case"aarch64":return"arm64";case"ia32":case"x86":return Z("[SeccompFilter] 32-bit x86 (ia32) is not currently supported due to missing socketcall() syscall blocking. The current seccomp filter only blocks socket(AF_UNIX, ...), but on 32-bit x86, socketcall() can be used to bypass this.",{level:"error"}),null;default:return Z(`[SeccompFilter] Unsupported architecture: ${$}. Only x64 and arm64 are supported.`),null}}function mq($){let J=O4();if(!J)return[];let X=bq(hq(import.meta.url)),Q=M0("vendor","seccomp",J,$);return[M0(X,Q),M0(X,"..","..",Q),M0(X,"..",Q)]}function WG($){let J=$??"";if(YG.has(J))return YG.get(J);let X=lq($);return YG.set(J,X),X}function lq($){if($){if(eY.existsSync($))return Z(`[SeccompFilter] Using apply-seccomp binary from explicit path: ${$}`),$;Z(`[SeccompFilter] Explicit path provided but file not found: ${$}`)}let J=O4();if(!J)return Z(`[SeccompFilter] Cannot find apply-seccomp binary: unsupported architecture ${process.arch}`),null;Z(`[SeccompFilter] Looking for apply-seccomp binary for architecture: ${J}`);for(let X of mq("apply-seccomp"))if(eY.existsSync(X))return Z(`[SeccompFilter] Found apply-seccomp binary: ${X} (${J})`),X;for(let X of gq()){let Q=M0(X,"vendor","seccomp",J,"apply-seccomp");if(eY.existsSync(Q))return Z(`[SeccompFilter] Found apply-seccomp binary in global install: ${Q} (${J})`),Q}return Z(`[SeccompFilter] apply-seccomp binary not found in any expected location (${J})`),null}var VG=3;function pq($){let J=$.uid===void 0?$.bwrapCommand:[$.setprivPath??"/usr/bin/setpriv",`--reuid=${$.uid}`,`--regid=${$.gid??$.uid}`,"--clear-groups","--inh-caps=-all","--ambient-caps=-all","--bounding-set=-all",...$.bwrapCommand],X=$.unsetEnvVars??[],Q=Object.entries($.setEnvVars??{});if(X.length===0&&Q.length===0)return J;return["/usr/bin/env",...X.flatMap((Y)=>["-u",Y]),...Q.map(([Y,G])=>`${Y}=${G}`),...J]}function MG($,J){let X=$.split(k$.sep),Q="";for(let Y of X){if(!Y)continue;let G=Q+k$.sep+Y;try{if(J$.lstatSync(G).isSymbolicLink()){if(J.some((U)=>G.startsWith(U+"/")||G===U))return G}}catch{break}Q=G}return null}var cq=40;function q4($){let J=$;for(let X=0;X<cq;X++){try{return J$.realpathSync(J)}catch{}let Q=J,Y=[],G=null;while(G===null){let U=k$.dirname(Q);if(U===Q)return null;Y.unshift(k$.basename(Q)),Q=U;try{G=J$.realpathSync(Q)}catch{}}let W=k$.join(G,Y[0]),M=null;try{M=J$.readlinkSync(W)}catch{}if(M===null)return k$.join(G,...Y);J=k$.join(k$.resolve(k$.dirname(W),M),...Y.slice(1))}return null}function nq($){let J=$.split(k$.sep),X="";for(let Q of J){if(!Q)continue;let Y=X+k$.sep+Q;try{let G=J$.statSync(Y);if(G.isFile()||G.isSymbolicLink())return!0}catch{break}X=Y}return!1}function iq($){let J=$.split(k$.sep),X="";for(let Q of J){if(!Q)continue;let Y=X+k$.sep+Q;if(!J$.existsSync(Y))return Y;X=Y}return $}async function oq($={command:"rg"},J=VG,X=!1,Q){let Y=process.cwd(),G=new AbortController,W=Q??G.signal,M=$Y(),U=[...GX.map((E)=>k$.resolve(Y,E)),...M.map((E)=>k$.resolve(Y,E))],O=k$.resolve(Y,".git"),V=!1;try{V=J$.statSync(O).isDirectory()}catch{}if(V){if(U.push(k$.resolve(Y,".git/hooks")),!X)U.push(k$.resolve(Y,".git/config"))}let H=[];for(let E of GX)H.push("--iglob",E);for(let E of M)H.push("--iglob",`**/${E}/**`);if(H.push("--iglob","**/.git/hooks/**"),!X)H.push("--iglob","**/.git/config");let q=[];try{q=await U4(["--files","--hidden","--max-depth",String(J),...H,"-g","!**/node_modules/**"],Y,W,$)}catch(E){Z(`[Sandbox] ripgrep scan failed: ${E}`)}for(let E of q){let K=k$.resolve(Y,E),R=!1;for(let L of[...M,".git"]){let D=S9(L),w=K.split(k$.sep),T=w.findIndex((P)=>S9(P)===D);if(T!==-1){if(L===".git"){let P=w.slice(0,T+1).join(k$.sep);if(E.includes(".git/hooks"))U.push(k$.join(P,"hooks"));else if(E.includes(".git/config"))U.push(k$.join(P,"config"))}else U.push(w.slice(0,T+1).join(k$.sep));R=!0;break}}if(!R)U.push(K)}return[...new Set(U)]}var $9=new Set,f0=0,K4=!1;function z4(){if(K4)return;process.on("exit",()=>{J9({force:!0})}),K4=!0}function J9($){if(!$?.force){if(f0>0)f0--;if(f0>0){Z(`[Sandbox Linux] Deferring mount point cleanup \u2014 ${f0} sandbox(es) still active`);return}}else f0=0;for(let J of $9)try{let X=J$.statSync(J);if(X.isFile()&&X.size===0)J$.unlinkSync(J),Z(`[Sandbox Linux] Cleaned up bwrap mount point (file): ${J}`);else if(X.isDirectory()){if(J$.readdirSync(J).length===0)J$.rmdirSync(J),Z(`[Sandbox Linux] Cleaned up bwrap mount point (dir): ${J}`)}}catch{}$9.clear()}function E4($){try{return J$.accessSync($,J$.constants.X_OK),!0}catch{return!1}}function N4($){let{seccompConfig:J,bwrapPath:X,socatPath:Q}=$??{},Y=[],G=[];if(X){if(!E4(X))Y.push(`bubblewrap (bwrap) not executable at ${X}`)}else if(N0("bwrap")===null)Y.push("bubblewrap (bwrap) not installed");if(Q){if(!E4(Q))Y.push(`socat not executable at ${Q}`)}else if(N0("socat")===null)Y.push("socat not installed");if(!J?.argv0&&WG(J?.applyPath)===null)G.push("seccomp not available - unix socket access not restricted");return{warnings:G,errors:Y}}async function L4($,J,X,Q,Y){let G=X??"socat",W=dq(8).toString("hex"),M=H4(OG(),`claude-http-${W}.sock`),U=H4(OG(),`claude-socks-${W}.sock`),O=[`UNIX-LISTEN:${M},fork,reuseaddr`,`TCP:localhost:${$},keepalive,keepidle=10,keepintvl=5,keepcnt=3`];Z(`Starting HTTP bridge: ${G} ${O.join(" ")}`);let V=V4(G,O,{stdio:"ignore"});if(V.on("error",(K)=>{Z(`HTTP bridge process error: ${K}`,{level:"error"})}),V.on("exit",(K,R)=>{Z(`HTTP bridge process exited with code ${K}, signal ${R}`,{level:K===0?"info":"error"})}),!V.pid)throw Error("Failed to start HTTP bridge process");let H,q;if(J===$)H=V,q=M;else{q=U;let K=[`UNIX-LISTEN:${U},fork,reuseaddr`,`TCP:localhost:${J},keepalive,keepidle=10,keepintvl=5,keepcnt=3`];if(Z(`Starting SOCKS bridge: ${G} ${K.join(" ")}`),H=V4(G,K,{stdio:"ignore"}),H.on("error",(R)=>{Z(`SOCKS bridge process error: ${R}`,{level:"error"})}),H.on("exit",(R,L)=>{Z(`SOCKS bridge process exited with code ${R}, signal ${L}`,{level:R===0?"info":"error"})}),!H.pid){if(V.pid)try{process.kill(V.pid,"SIGTERM")}catch{}throw Error("Failed to start SOCKS bridge process")}}let E=200;for(let K=0;K<E;K++){if(!V.pid||V.killed||!H.pid||H.killed)throw Error("Linux bridge process died unexpectedly");try{if(J$.existsSync(M)&&J$.existsSync(q)){if(Q!==void 0){let R=Y??Q;for(let L of new Set([M,q]))J$.chownSync(L,Q,R),J$.chmodSync(L,384)}Z(`Linux bridges ready after ${K+1} attempts`);break}}catch(R){Z(`Error checking sockets (attempt ${K+1}): ${R}`,{level:"error"})}if(K===E-1){if(V.pid)try{process.kill(V.pid,"SIGTERM")}catch{}if(H.pid)try{process.kill(H.pid,"SIGTERM")}catch{}throw Error(`Failed to create bridge sockets after ${E} attempts`)}await new Promise((R)=>setTimeout(R,5))}return{httpSocketPath:M,socksSocketPath:q,httpBridgeProcess:V,socksBridgeProcess:H,httpProxyPort:$,socksProxyPort:J}}function aq($,J){if(J){if(!$)throw Error("seccompConfig.argv0 requires seccompConfig.applyPath");return`ARGV0=${IJ([J])} ${IJ([$])} `}let X=WG($);return X?`${IJ([X])} `:void 0}function sq($,J,X,Q,Y,G){let W=Y||"bash",M=IJ([G??"socat"]),U=["srt_payload_pid=",`${M} TCP4-LISTEN:3128,bind=127.0.0.1,fork,reuseaddr ${IJ([`UNIX-CONNECT:${$}`])} >/dev/null 2>&1 &`,"srt_http_proxy_pid=$!",`${M} TCP4-LISTEN:1080,bind=127.0.0.1,fork,reuseaddr ${IJ([`UNIX-CONNECT:${J}`])} >/dev/null 2>&1 &`,"srt_socks_proxy_pid=$!","srt_cleanup_command() {"," srt_status=$?"," trap - EXIT INT TERM",' if [ -n "$srt_payload_pid" ]; then',' kill -KILL "$srt_payload_pid" 2>/dev/null',' wait "$srt_payload_pid" 2>/dev/null'," fi",' kill -KILL "$srt_http_proxy_pid" "$srt_socks_proxy_pid" 2>/dev/null',' wait "$srt_http_proxy_pid" "$srt_socks_proxy_pid" 2>/dev/null',' exit "$srt_status"',"}","trap srt_cleanup_command EXIT","trap 'exit 143' TERM","trap 'exit 130' INT",...[3128,1080].map((H)=>`${M} -u OPEN:/dev/null TCP4:127.0.0.1:${H},connect-timeout=0.1,retry=480,interval=0.005 >/dev/null 2>&1 || { printf '%s\\n' 'Sandbox proxy listener readiness failed' >&2; exit 1; }`),`kill -0 "$srt_http_proxy_pid" "$srt_socks_proxy_pid" 2>/dev/null || { printf '%s\\n' 'Sandbox proxy listener exited before command' >&2; exit 1; }`],O=(Q??"")+IJ([W,"-c",X]),V=[...U,`${O} <&0 &`,"srt_payload_pid=$!",'wait "$srt_payload_pid"',"srt_payload_status=$?","srt_payload_pid=",'exit "$srt_payload_status"'].join(`
|
|
63
63
|
`);return`${W} -c ${IJ([V])}`}function UG($){try{if(J$.lstatSync($).isSymbolicLink())return J$.realpathSync($)}catch{}return $}function F4($,J,X,Q){let Y=J==="/"?"/":J+"/";$.push("--tmpfs",J);for(let G of X)if(G.startsWith(Y)||G===J)$.push("--bind",G,G),Z(`[Sandbox Linux] Re-bound write path wiped by denyRead tmpfs: ${G}`);for(let G of Q)if(G.startsWith(Y)||G===J){if(!J$.existsSync(G)){Z(`[Sandbox Linux] Skipping non-existent read allow path: ${G}`);continue}if(X.some((W)=>(W.startsWith(Y)||W===J)&&(G===W||G.startsWith(W+"/"))))continue;$.push("--ro-bind",G,G),Z(`[Sandbox Linux] Re-allowed read access within denied region: ${G}`)}}async function rq($,J,X,Q,Y={command:"rg"},G=VG,W=!1,M){let U=[],O=[],V=[],H=new Map,q=new Map;if(J){U.push("--ro-bind","/","/");for(let G$ of J.allowOnly||[]){let r=e$(G$).replace(/\/+$/,"")||"/";if(Z(`[Sandbox Linux] Processing write path: ${G$} -> ${r}`),r.startsWith("/dev/")){Z(`[Sandbox Linux] Skipping /dev path: ${r}`);continue}if(!J$.existsSync(r)){Z(`[Sandbox Linux] Skipping non-existent write path: ${r}`);continue}try{let m=J$.realpathSync(r),W$=r.replace(/\/+$/,"");if(m!==W$&&eX(r,m)){Z(`[Sandbox Linux] Skipping symlink write path pointing outside expected location: ${G$} -> ${m}`);continue}}catch{Z(`[Sandbox Linux] Skipping write path that could not be resolved: ${r}`);continue}U.push("--bind",r,r),O.push(r)}let S,C=()=>{if(S!==void 0)return S;let G$=[];for(let m of O){G$.push(m);try{let W$=J$.realpathSync(m);if(W$!==m)G$.push(W$)}catch{}}let r=[];if($){let m=[],W$=new Set(["proc","dev","sys"]);for(let l of $.denyOnly||[])if(e$(l)==="/")try{for(let H$ of J$.readdirSync("/"))if(!W$.has(H$))m.push("/"+H$)}catch{}else m.push(l);if(J$.existsSync("/etc/ssh/ssh_config.d"))m.push("/etc/ssh/ssh_config.d");for(let l of m){let H$=e$(l),JJ=!1;try{JJ=J$.statSync(H$).isDirectory()}catch{continue}if(!JJ)continue;r.push(H$);try{let w$=J$.realpathSync(H$);if(w$!==H$)r.push(w$)}catch{}}}return S={allowedWritePathsBothForms:G$,prospectiveReadDenyTmpfsDirsBothForms:r},S},h=(G$)=>O.some((r)=>G$.startsWith(r+"/")||G$===r),s=[...J.denyWithinAllow||[],...await oq(Y,G,W,M)],a=new Set;for(let G$ of s){let r=e$(G$);if(r.startsWith("/dev/"))continue;let m=q4(r);if(m===null||m.startsWith("/dev/"))continue;if(MG(m,O))continue;let W$=!1;try{W$=J$.statSync(m).isDirectory()}catch{continue}if(!W$)continue;if(h(m)){let l=H.get(m);if(l===void 0)l=new Set,H.set(m,l);l.add(r)}}let O$=new Map,j$=(G$)=>{let r=O$.get(G$);if(r!==void 0)return r;let{allowedWritePathsBothForms:m,prospectiveReadDenyTmpfsDirsBothForms:W$}=C(),l=m.some((H$)=>H$.startsWith(G$+"/"))||W$.some((H$)=>H$===G$||H$.startsWith(G$+"/"))||W$.some((H$)=>[G$,...H.get(G$)??[]].some((JJ)=>JJ===H$||JJ.startsWith(H$+"/")));return O$.set(G$,l),l},T$=[...H.keys()];for(let G$ of s){let r=e$(G$);if(r.startsWith("/dev/"))continue;let m=q4(r);if(m===null){let H$=MG(r,O);if(H$&&!a.has(H$))a.add(H$),V.push("--ro-bind","/dev/null",H$),q.set(H$,r);Z(`[Sandbox Linux] Deny path could not be resolved through symlinks, failing closed: ${r}`);continue}if(m!==r)Z(`[Sandbox Linux] Resolved symlinked deny path: ${r} -> ${m}`);if(m.startsWith("/dev/"))continue;if(a.has(m))continue;a.add(m);let W$=MG(m,O);if(W$){if(!a.has(W$))a.add(W$),V.push("--ro-bind","/dev/null",W$),q.set(W$,r);Z(`[Sandbox Linux] Mounted /dev/null at symlink ${W$} to prevent symlink replacement attack`);continue}if(!J$.existsSync(m)){if(nq(m)){Z(`[Sandbox Linux] Skipping deny path with file ancestor (cannot create paths under a file): ${m}`);continue}let H$=k$.dirname(m);while(H$!=="/"&&!J$.existsSync(H$))H$=k$.dirname(H$);let JJ=h(H$)||h(m),w$=T$.filter((z$)=>H$===z$||H$.startsWith(z$+"/")),D$=w$.length>0&&!w$.some(j$);if(JJ&&!D$){let z$=iq(m);if(z$!==m){let $$=J$.mkdtempSync(k$.join(OG(),"claude-empty-"));V.push("--ro-bind",$$,z$),q.set(z$,r),$9.add(z$),z4(),Z(`[Sandbox Linux] Mounted empty dir at ${z$} to block creation of ${m}`)}else V.push("--ro-bind","/dev/null",z$),q.set(z$,r),$9.add(z$),z4(),Z(`[Sandbox Linux] Mounted /dev/null at ${z$} to block creation of ${m}`)}else if(D$)Z(`[Sandbox Linux] Skipping non-existent deny path inside a read-only denied directory (already uncreatable): ${m}`);else Z(`[Sandbox Linux] Skipping non-existent deny path not within allowed paths: ${m}`);continue}if(h(m))V.push("--ro-bind",m,m),q.set(m,r);else Z(`[Sandbox Linux] Skipping deny path not within allowed paths: ${m}`)}}else U.push("--bind","/","/");let E=[],K=($?.allowWithinDeny||[]).map((S)=>e$(S)),R=new Map,L=[],D=new Set(["proc","dev","sys"]);for(let S of $?.denyOnly||[])if(e$(S)==="/"){for(let C of J$.readdirSync("/"))if(!D.has(C))E.push("/"+C)}else E.push(S);if($&&J$.existsSync("/etc/ssh/ssh_config.d"))E.push("/etc/ssh/ssh_config.d");let w=E.map((S)=>e$(S)).sort((S,C)=>S.split("/").length-C.split("/").length);for(let S of w){if(!J$.existsSync(S)){Z(`[Sandbox Linux] Skipping non-existent read deny path: ${S}`);continue}if(J$.statSync(S).isDirectory())L.push(S),F4(U,S,O,K);else{if(K.includes(S)){Z(`[Sandbox Linux] Skipping read deny for re-allowed path: ${S}`);continue}let h=UG(S);U.push("--ro-bind","/dev/null",h),R.set(h,"/dev/null"),R.set(S,"/dev/null")}}for(let{realPath:S,fakePath:C}of X??[]){let h=UG(S);U.push("--ro-bind",C,h),R.set(h,C),R.set(S,C)}let T=(S)=>L.some((C)=>{if(!(S===C||S.startsWith(C+"/")))return!1;return!O.some((a)=>(a===C||a.startsWith(C+"/"))&&(S===a||S.startsWith(a+"/")))}),P=[];for(let S=0;S<V.length;S+=3){let C=V[S+2],h=q.get(C)??C;if(R.has(C))continue;if(T(C)||T(h)){Z(`[Sandbox Linux] Skipping denyWrite bind already hidden by denyRead tmpfs: ${C}`);continue}if(U.push(V[S],V[S+1],C),P.push(C),h!==C)P.push(h)}for(let S of L)if(P.some((C)=>S.startsWith(C+"/")))Z(`[Sandbox Linux] Re-applying denyRead tmpfs re-exposed by denyWrite bind: ${S}`),F4(U,S,O,K);for(let[S,C]of R)if(P.some((h)=>S.startsWith(h+"/"))){if(UG(S)!==S)continue;Z(`[Sandbox Linux] Re-applying file mask re-exposed by denyWrite bind: ${S}`),U.push("--ro-bind",C,S)}if(Q!==void 0)U.push("--ro-bind",Q,Q);return U}async function R4($){let{command:J,commandId:X,needsNetworkRestriction:Q,httpSocketPath:Y,socksSocketPath:G,httpProxyPort:W,socksProxyPort:M,proxyAuthToken:U,caCertPath:O,readConfig:V,writeConfig:H,unsetEnvVars:q,setEnvVars:E,maskedFileBinds:K,maskedFileStoreDir:R,enableWeakerNestedSandbox:L,runAsUid:D,runAsGid:w,runAsHostUid:T,runAsHostGid:P,runAsHostHome:S,runAsHostUser:C,setprivPath:h,allowAllUnixSockets:s,binShell:a,ripgrepConfig:O$={command:"rg"},mandatoryDenySearchDepth:j$=VG,allowGitConfig:T$=!1,gitSafeDirectories:G$,seccompConfig:r,bwrapPath:m,socatPath:W$,observeSocketPath:l,abortSignal:H$}=$,JJ=V&&V.denyOnly.length>0||K!==void 0&&K.length>0,w$=H!==void 0,D$=q!==void 0&&q.length>0||E!==void 0&&Object.keys(E).length>0,z$=(G$?.length??0)>0;if(!Q&&!JJ&&!w$&&!D$&&!z$)return J;f0++;let $$=["--new-session","--die-with-parent"],d$=[],h$;try{if(!s)if(h$=aq(r?.applyPath,r?.argv0),!h$)Z("[Sandbox Linux] apply-seccomp binary not available - unix socket blocking disabled. Install @anthropic-ai/sandbox-runtime globally for full protection.",{level:"warn"});else Z("[Sandbox Linux] Applying seccomp filter for Unix socket blocking");else Z("[Sandbox Linux] Skipping seccomp filter - allowAllUnixSockets is enabled");if(l&&h$)if(J$.existsSync(l))d$.push("--bind",l,l),$$.push("--setenv","SRT_OBSERVE_SOCK",l),$$.push("--setenv","SRT_ENCODED_CMD",wJ(X??J));else Z("[Sandbox Linux] observe socket missing \u2014 supervisor not running; "+"continuing without violation monitoring");if(D$){for(let x$ of q??[])$$.push("--unsetenv",x$);for(let[x$,m$]of Object.entries(E??{}))$$.push("--setenv",x$,m$)}if(G$&&G$.length>0){let x$=JY({safeDirs:G$,unsetEnvVars:q,setEnvVars:E});for(let[m$,a$]of Object.entries(x$))$$.push("--setenv",m$,a$)}if(Q){if($$.push("--unshare-net"),Y&&G){if(!J$.existsSync(Y))throw Error(`Linux HTTP bridge socket does not exist: ${Y}. The bridge process may have died. Try reinitializing the sandbox.`);if(!J$.existsSync(G))throw Error(`Linux SOCKS bridge socket does not exist: ${G}. The bridge process may have died. Try reinitializing the sandbox.`);if(d$.push("--bind",Y,Y),G!==Y)d$.push("--bind",G,G);let x$=LQ(3128,1080,O,U,H===void 0,wJ(X??J));if($$.push(...x$.flatMap((m$)=>{let a$=m$.indexOf("="),GJ=m$.slice(0,a$),c5=m$.slice(a$+1);return["--setenv",GJ,c5]})),W!==void 0)$$.push("--setenv","CLAUDE_CODE_HOST_HTTP_PROXY_PORT",String(W));if(M!==void 0)$$.push("--setenv","CLAUDE_CODE_HOST_SOCKS_PROXY_PORT",String(M))}}let t$=await rq(V,H,K,R,O$,j$,T$,H$);if($$.push(...t$),$$.push(...d$),$$.push("--dev","/dev"),$$.push("--unshare-pid"),!L){if($$.push("--unshare-user","--cap-drop","ALL","--proc","/proc"),!h$)$$.push("--ro-bind","/dev/null","/proc/sysrq-trigger")}else $$.push("--unshare-user","--bind","/proc","/proc");if(D!==void 0)$$.push("--uid",String(D)),$$.push("--gid",String(w??D));if(T!==void 0){if(S)$$.push("--setenv","HOME",S);if(C)$$.push("--setenv","USER",C),$$.push("--setenv","LOGNAME",C)}let QJ=a||"bash",o$=N0(QJ);if(!o$)throw Error(`Shell '${QJ}' not found in PATH`);if($$.push("--",o$,"-c"),Q&&Y&&G){let x$=sq(Y,G,J,h$,o$,W$);$$.push(x$)}else if(h$){let x$=h$+IJ([o$,"-c",J]);$$.push(x$)}else $$.push(J);let XJ=[m??"bwrap",...$$],YJ=IJ(pq({bwrapCommand:XJ,uid:T,gid:P,setprivPath:h,unsetEnvVars:q,setEnvVars:E})),c$=[];if(Q)c$.push("network");if(JJ||w$)c$.push("filesystem");if(D$)c$.push("env");if(h$)c$.push("seccomp(unix-block)");return Z(`[Sandbox Linux] Wrapped command with bwrap (${c$.join(", ")} restrictions)`),YJ}catch(t$){if(f0>0)f0--;throw t$}}import{spawn as tq}from"child_process";import*as L0 from"path";class Q9{violations=[];totalCount=0;maxSize=100;listeners=new Set;addViolation($){if(this.violations.push({...$,line:HG($.line).replace(/[<>]/g,"")}),this.totalCount++,this.violations.length>this.maxSize)this.violations=this.violations.slice(-this.maxSize);this.notifyListeners()}getViolations($){if($===void 0)return[...this.violations];return this.violations.slice(-$)}getCount(){return this.violations.length}getTotalCount(){return this.totalCount}getViolationsForCommand($){let J=wJ($);return this.violations.filter((X)=>X.encodedCommand===J)}clear(){this.violations=[],this.notifyListeners()}subscribe($){return this.listeners.add($),$(this.getViolations()),()=>{this.listeners.delete($)}}notifyListeners(){let $=this.getViolations();this.listeners.forEach((J)=>J($))}}function uQ($,J,X){if(!X)return!1;if((X["*"]??[]).some((Y)=>$.includes(Y)))return!0;if(J===void 0)return!1;for(let[Y,G]of Object.entries(X))if(Y!=="*"&&J.includes(Y)&&G.some((W)=>$.includes(W)))return!0;return!1}function HG($){return $.replace(/[\x00-\x1f\x7f-\x9f]+/g," ").trim()}function eq($=!1){let J=process.cwd(),X=[];for(let Q of GX)X.push(L0.resolve(J,Q)),X.push(`**/${Q}`);for(let Q of $Y())X.push(L0.resolve(J,Q)),X.push(`**/${Q}/**`);if(X.push(L0.resolve(J,".git/hooks")),X.push("**/.git/hooks/**"),!$)X.push(L0.resolve(J,".git/config")),X.push("**/.git/config");return[...new Set(X)]}var A4=`_${Math.random().toString(36).slice(2,11)}_SBX`;function $K($){return`CMD64_${wJ($)}_END_${A4}`}function gQ($){return FJ($)?`(regex ${cJ(OX($))})`:`(subpath ${cJ($)})`}function EG($){return OX($).slice(0,-1)+"(/.*)?$"}function UQ($){return FJ($)?`(regex ${cJ(EG($))})`:`(subpath ${cJ($)})`}function D4($){return $.replace(/\[[^\]]*\]|[*?]+/g,"x")}function KG($,J){let X=[...new Set(J)];if(X.length===0)return $;let Q=X.map((Y)=>`(require-not ${Y})`).join(" ");return`(require-all ${$} ${Q})`}function qG($){let J=e$($);return{path:J,glob:FJ(J)}}function Z4($,J){return $.test(J.glob?D4(J.path):J.path)}function X9($,J){let X=$.glob?D4($.path):$.path;return X.startsWith(J==="/"?"/":J+"/")&&X!==J}function JK($,J){return{denies:($.denyOnly||[]).map(qG),allows:($.allowWithinDeny||[]).map(qG),writeRoots:(J||[]).map(qG)}}function QK($){let J=[],X=!1,Q=$.allows.filter((Y)=>!Y.glob).map((Y)=>Y.path);for(let Y of $.denies){if(!Y.glob){if(Q.some((M)=>Y.path.startsWith(M+"/")))J.push(UQ(Y.path));continue}let G=new RegExp(EG(Y.path));if(G.test("/"))X=!0;let W=$.allows.filter((M)=>Z4(G,M)).map((M)=>gQ(M.path));J.push(KG(UQ(Y.path),W))}return{filters:J,coversRoot:X}}function B4($){let J=$.split(/[*?[\]]/)[0];if(!J||J==="/")return"/";return J.endsWith("/")?J.slice(0,-1):L0.dirname(J)}function XK($,J){let{denies:X,allows:Q,writeRoots:Y}=$;if(Y.length===0)return[];let G=Y.filter((H)=>H.glob).map((H)=>new RegExp(OX(H.path))),W=Y.filter((H)=>!H.glob).map((H)=>H.path),M=(H)=>W.some((q)=>X9({path:H,glob:!1},q))||G.some((q)=>q.test(H)),U=(H)=>[...Q,...Y].filter((q)=>X9(q,H)).map((q)=>gQ(q.path)),O=new Set,V=(H)=>{for(let q of H)if(M(q))O.add(`(literal ${cJ(q)})`)};for(let H of X)if(H.glob){let q=B4(H.path);if(!(G.length>0||W.some((L)=>q===L||X9({path:q,glob:!1},L)||X9({path:L,glob:!1},q))))continue;let K=new RegExp(EG(H.path)),R=[...Q,...Y].filter((L)=>Z4(K,L)).map((L)=>gQ(L.path));if(O.add(KG(UQ(H.path),R)),q!=="/")V([q,...zG(q)])}else{if(!M(H.path))continue;O.add(KG(UQ(H.path),U(H.path))),V(zG(H.path))}return y0("deny",["file-write-unlink"],O,J)}function y0($,J,X,Q){if(X.size===0)return[];return[`(${$} ${J.join(" ")}`,...[...X].map((Y)=>` ${Y}`),` (with message "${Q}"))`]}function zG($){let J=[],X=L0.dirname($);while(X!=="/"&&X!=="."){J.push(X);let Q=L0.dirname(X);if(Q===X)break;X=Q}return J}function j4($,J){let X=new Set;for(let Q of $){let Y=e$(Q);X.add(UQ(Y));let G;if(FJ(Y)){if(G=B4(Y),G==="/")continue;X.add(`(literal ${cJ(G)})`)}else G=Y;for(let W of zG(G))X.add(`(literal ${cJ(W)})`)}return y0("deny",["file-write-unlink","file-write-create"],X,J)}function YK($,J){if(!$)return["(allow file-read*)"];let X=[];X.push("(allow file-read*)");let Q=$.denies.some((U)=>U.path==="/"),Y=new Set($.denies.map((U)=>UQ(U.path)));X.push(...y0("deny",["file-read*"],Y,J));let G=new Set($.allows.map((U)=>gQ(U.path)));X.push(...y0("allow",["file-read*"],G,J));let W=QK($);if(X.push(...y0("deny",["file-read*"],new Set(W.filters),J)),Q||W.coversRoot)X.push('(allow file-read* (literal "/"))');if($.denies.length>0)X.push("(allow file-read-metadata"," (vnode-type DIRECTORY))");X.push(...j4($.denies.map((U)=>U.path),J));let M=new Set($.writeRoots.map((U)=>gQ(U.path)));return X.push(...y0("allow",["file-write-unlink","file-write-create"],M,J)),X}function GK($,J,X=!1){if(!$)return["(allow file-write*)"];let Q=[],Y=new Set;for(let M of $.allowOnly||[])Y.add(gQ(e$(M)));Q.push(...y0("allow",["file-write*"],Y,J));let G=[...$.denyWithinAllow||[],...eq(X)],W=new Set;for(let M of G)W.add(UQ(e$(M)));return Q.push(...y0("deny",["file-write*"],W,J)),Q.push(...j4(G,J)),Q}function WK({readConfig:$,writeConfig:J,httpProxyPort:X,socksProxyPort:Q,needsNetworkRestriction:Y,allowUnixSockets:G,allowAllUnixSockets:W,allowLocalBinding:M,allowMachLookup:U,allowPty:O,allowGitConfig:V=!1,enableWeakerNetworkIsolation:H=!1,allowAppleEvents:q=!1,logTag:E}){let K=["(version 1)",`(deny default (with message "${E}"))`,"",`; LogTag: ${E}`,"","; Essential permissions - based on Chrome sandbox policy","; Process permissions","(allow process-exec)","(allow process-fork)","(allow process-info* (target same-sandbox))","(allow signal (target same-sandbox))","(allow mach-priv-task-port (target same-sandbox))","","; User preferences","(allow user-preference-read)","","; Mach IPC - specific services only (no wildcard)","(allow mach-lookup",' (global-name "com.apple.audio.systemsoundserver")',' (global-name "com.apple.distributed_notifications@Uv3")',' (global-name "com.apple.FontObjectsServer")',' (global-name "com.apple.fonts")',' (global-name "com.apple.logd")',' (global-name "com.apple.lsd.mapdb")',' (global-name "com.apple.PowerManagement.control")',' (global-name "com.apple.system.logger")',' (global-name "com.apple.system.notification_center")',' (global-name "com.apple.system.opendirectoryd.libinfo")',' (global-name "com.apple.system.opendirectoryd.membership")',' (global-name "com.apple.bsd.dirhelper")',' (global-name "com.apple.securityd.xpc")',' (global-name "com.apple.coreservices.launchservicesd")',")","",...H?["; trustd.agent - needed for Go TLS certificate verification (weaker network isolation)",'(allow mach-lookup (global-name "com.apple.trustd.agent"))']:[],...q?["; Apple Events - opt-in; needed for open/osascript to talk to other apps (appleeventsd)","(allow appleevent-send)",'(allow mach-lookup (global-name "com.apple.coreservices.appleevents"))',"; Launch Services open requests need the lsopen operation plus, on","; macOS 14/15, coreservicesd and the quarantine resolver - without","; these open fails with -10822 kLSServerCommunicationErr or -54","(allow lsopen)",'(allow mach-lookup (global-name "com.apple.CoreServices.coreservicesd"))','(allow mach-lookup (global-name "com.apple.coreservices.quarantine-resolver"))']:[],...U&&U.length>0?["; User-specified XPC/Mach services",...U.map((L)=>L.endsWith("*")?`(allow mach-lookup (global-name-prefix ${cJ(L.slice(0,-1))}))`:`(allow mach-lookup (global-name ${cJ(L)}))`)]:[],"","; POSIX IPC - shared memory","(allow ipc-posix-shm)","","; POSIX IPC - semaphores for Python multiprocessing","(allow ipc-posix-sem)","","; IOKit - specific operations only","(allow iokit-open",' (iokit-registry-entry-class "IOSurfaceRootUserClient")',' (iokit-registry-entry-class "RootDomainUserClient")',' (iokit-user-client-class "IOSurfaceSendRight")',")","","; IOKit properties","(allow iokit-get-properties)","","; Specific safe system-sockets, doesn't allow network access","(allow system-socket (require-all (socket-domain AF_SYSTEM) (socket-protocol 2)))","","; sysctl - specific sysctls only","(allow sysctl-read",' (sysctl-name "hw.activecpu")',' (sysctl-name "hw.busfrequency_compat")',' (sysctl-name "hw.byteorder")',' (sysctl-name "hw.cacheconfig")',' (sysctl-name "hw.cachelinesize_compat")',' (sysctl-name "hw.cpufamily")',' (sysctl-name "hw.cpufrequency")',' (sysctl-name "hw.cpufrequency_compat")',' (sysctl-name "hw.cputype")',' (sysctl-name "hw.l1dcachesize_compat")',' (sysctl-name "hw.l1icachesize_compat")',' (sysctl-name "hw.l2cachesize_compat")',' (sysctl-name "hw.l3cachesize_compat")',' (sysctl-name "hw.logicalcpu")',' (sysctl-name "hw.logicalcpu_max")',' (sysctl-name "hw.machine")',' (sysctl-name "hw.memsize")',' (sysctl-name "hw.ncpu")',' (sysctl-name "hw.nperflevels")',' (sysctl-name "hw.packages")',' (sysctl-name "hw.pagesize_compat")',' (sysctl-name "hw.pagesize")',' (sysctl-name "hw.physicalcpu")',' (sysctl-name "hw.physicalcpu_max")',' (sysctl-name "hw.tbfrequency_compat")',' (sysctl-name "hw.vectorunit")',' (sysctl-name "kern.argmax")',' (sysctl-name "kern.bootargs")',' (sysctl-name "kern.hostname")',' (sysctl-name "kern.maxfiles")',' (sysctl-name "kern.maxfilesperproc")',' (sysctl-name "kern.maxproc")',' (sysctl-name "kern.ngroups")',' (sysctl-name "kern.osproductversion")',' (sysctl-name "kern.osrelease")',' (sysctl-name "kern.ostype")',' (sysctl-name "kern.osvariant_status")',' (sysctl-name "kern.osversion")',' (sysctl-name "kern.secure_kernel")',' (sysctl-name "kern.tcsm_available")',' (sysctl-name "kern.tcsm_enable")',' (sysctl-name "kern.usrstack64")',' (sysctl-name "kern.version")',' (sysctl-name "kern.willshutdown")',' (sysctl-name "machdep.cpu.brand_string")',' (sysctl-name "machdep.ptrauth_enabled")',' (sysctl-name "security.mac.lockdown_mode_state")',' (sysctl-name "sysctl.proc_cputype")',' (sysctl-name "vm.loadavg")',' (sysctl-name-prefix "hw.optional.arm")',' (sysctl-name-prefix "hw.optional.arm.")',' (sysctl-name-prefix "hw.optional.armv8_")',' (sysctl-name-prefix "hw.perflevel")',' (sysctl-name-prefix "kern.proc.all")',' (sysctl-name-prefix "kern.proc.pgrp.")',' (sysctl-name-prefix "kern.proc.pid.")',' (sysctl-name-prefix "machdep.cpu.")',' (sysctl-name-prefix "net.routetable.")',")","","; V8 thread calculations","(allow sysctl-write",' (sysctl-name "kern.tcsm_enable")',")","","; Distributed notifications","(allow distributed-notification-post)","","; Specific mach-lookup permissions for security operations",'(allow mach-lookup (global-name "com.apple.SecurityServer"))',"","; File I/O on device files",'(allow file-ioctl (literal "/dev/null"))','(allow file-ioctl (literal "/dev/zero"))','(allow file-ioctl (literal "/dev/random"))','(allow file-ioctl (literal "/dev/urandom"))','(allow file-ioctl (literal "/dev/dtracehelper"))','(allow file-ioctl (literal "/dev/tty"))',"","(allow file-ioctl file-read-data file-write-data"," (require-all",' (literal "/dev/null")'," (vnode-type CHARACTER-DEVICE)"," )",")",""];if(K.push("; Network"),!Y)K.push("(allow network*)");else{if(M)K.push('(allow network-bind (local ip "*:*"))'),K.push('(allow network-inbound (local ip "*:*"))'),K.push('(allow network-outbound (remote ip "localhost:*"))');if(W)K.push("(allow system-socket (socket-domain AF_UNIX))"),K.push('(allow network-bind (local unix-socket (path-regex #"^/")))'),K.push('(allow network-outbound (remote unix-socket (path-regex #"^/")))');else if(G&&G.length>0){K.push("(allow system-socket (socket-domain AF_UNIX))");for(let L of G){let D=e$(L);K.push(`(allow network-bind (local unix-socket (subpath ${cJ(D)})))`),K.push(`(allow network-outbound (remote unix-socket (subpath ${cJ(D)})))`)}}if(X!==void 0)K.push(`(allow network-bind (local ip "localhost:${X}"))`),K.push(`(allow network-inbound (local ip "localhost:${X}"))`),K.push(`(allow network-outbound (remote ip "localhost:${X}"))`);if(Q!==void 0&&Q!==X)K.push(`(allow network-bind (local ip "localhost:${Q}"))`),K.push(`(allow network-inbound (local ip "localhost:${Q}"))`),K.push(`(allow network-outbound (remote ip "localhost:${Q}"))`)}K.push("");let R=$?JK($,J?.allowOnly):void 0;if(K.push("; File read"),K.push(...YK(R,E)),K.push(""),K.push("; File write"),K.push(...GK(J,E,V)),R){let L=XK(R,E);if(L.length>0)K.push(""),K.push("; File read: keep read-denied paths inside write roots in place"),K.push(...L)}if(O)K.push(""),K.push("; Pseudo-terminal (pty) support"),K.push("(allow pseudo-tty)"),K.push("(allow file-ioctl"),K.push(' (literal "/dev/ptmx")'),K.push(' (regex #"^/dev/ttys")'),K.push(")"),K.push("(allow file-read* file-write*"),K.push(' (literal "/dev/ptmx")'),K.push(' (regex #"^/dev/ttys")'),K.push(")");return K.join(`
|
|
64
64
|
`)}function cJ($){return JSON.stringify($)}function T4($){let{command:J,commandId:X,needsNetworkRestriction:Q,httpProxyPort:Y,socksProxyPort:G,proxyAuthToken:W,caCertPath:M,allowUnixSockets:U,allowAllUnixSockets:O,allowLocalBinding:V,allowMachLookup:H,readConfig:q,writeConfig:E,unsetEnvVars:K,setEnvVars:R,maskedFileBinds:L,allowPty:D,allowGitConfig:w=!1,gitSafeDirectories:T,enableWeakerNetworkIsolation:P=!1,allowAppleEvents:S=!1,binShell:C}=$,h=q;if(L&&L.length>0)Z("[Sandbox macOS] file mask degrades to deny on macOS until the interposer lands"),h={denyOnly:[...q?.denyOnly??[],...L.map((D$)=>D$.realPath)],allowWithinDeny:q?.allowWithinDeny};let s=h&&h.denyOnly.length>0,a=E!==void 0,O$=K!==void 0&&K.length>0||R!==void 0&&Object.keys(R).length>0,j$=(T?.length??0)>0;if(!Q&&!s&&!a&&!O$&&!j$)return J;let T$=X??J,G$=$K(T$),r=WK({readConfig:h,writeConfig:E,httpProxyPort:Y,socksProxyPort:G,needsNetworkRestriction:Q,allowUnixSockets:U,allowAllUnixSockets:O,allowLocalBinding:V,allowMachLookup:H,allowPty:D,allowGitConfig:w,enableWeakerNetworkIsolation:P,allowAppleEvents:S,logTag:G$}),m=LQ(Y,G,M,W,E===void 0,wJ(T$));if(V&&Q){let $$=(K??[]).includes("JAVA_TOOL_OPTIONS")?"":process.env.JAVA_TOOL_OPTIONS??"",d$=$$.includes("-Djava.net.preferIPv4Stack=true")?$$:[$$,"-Djava.net.preferIPv4Stack=true"].filter(Boolean).join(" ");m.push(`JAVA_TOOL_OPTIONS=${d$}`)}if(T&&T.length>0){let D$=JY({safeDirs:T,unsetEnvVars:K,setEnvVars:R});for(let[z$,$$]of Object.entries(D$))m.push(`${z$}=${$$}`)}let W$=C||"bash",l=N0(W$);if(!l)throw Error(`Shell '${W$}' not found in PATH`);let H$=(K??[]).flatMap((D$)=>["-u",D$]),JJ=Object.entries(R??{}).map(([D$,z$])=>`${D$}=${z$}`),w$=IJ(["env",...H$,...JJ,...m,"/usr/bin/sandbox-exec","-p",r,l,"-c",J]);return Z(`[Sandbox macOS] Applied restrictions - network: ${!!(Y||G)}, read: ${h?"allowAllExcept"in h?"allowAllExcept":"denyAllExcept":"none"}, write: ${E?"allowAllExcept"in E?"allowAllExcept":"denyAllExcept":"none"}`),w$}function S4($,J,X=(Q)=>Q){let Q=/CMD64_(.+?)_END/,Y=/Sandbox:\s+(.+)$/,G=tq("log",["stream","--predicate",`(eventMessage ENDSWITH "${A4}")`,"--style","compact"]);return G.stdout?.on("data",(W)=>{let M=W.toString().split(`
|