πŸš€ Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more β†’
Sign In

@promptshield/core

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@promptshield/core - npm Package Compare versions

Comparing version
0.0.0
to
0.1.0
+39
-7
dist/index.d.mts

@@ -12,2 +12,16 @@ /**

/**
* Numeric severity ranking map.
*
* Lower numbers represent higher severity.
*
* Used for:
* - Severity threshold comparisons
* - Sorting threats by priority
* - Efficient numeric filtering
*
* Example:
* SEVERITY_MAP["CRITICAL"] < SEVERITY_MAP["LOW"] // true
*/
declare const SEVERITY_MAP: Record<Severity, number>;
/**
* Categories of threats detected by PromptShield.

@@ -163,13 +177,31 @@ *

minSeverity?: Severity;
/** Disable invisible-character detection */
/** Disable invisible-character detection
*
* @default false
*/
disableInvisible?: boolean;
/** Disable homoglyph detection */
/** Disable homoglyph detection
*
* @default false
*/
disableHomoglyphs?: boolean;
/** Disable smuggling detection */
/** Disable smuggling detection
*
* @default false
*/
disableSmuggling?: boolean;
/** Disable Trojan Source detection */
/** Disable Trojan Source detection
*
* @default false
*/
disableTrojan?: boolean;
/** Disable normalization detection */
/** Disable normalization detection
*
* @default false
*/
disableNormalization?: boolean;
/** Disable injection-pattern detection */
/** Disable injection-pattern detection
*
* @default false
*/
disableInjectionPatterns?: boolean;

@@ -387,2 +419,2 @@ }

export { type Detector, type ScanContext, type ScanOptions, type ScanResult, type ScanStats, type Severity, ThreatCategory, type ThreatLoc, type ThreatReport, decodeUnicodeTags, scan, scanHomoglyphs, scanInjectionPatterns, scanInvisibleChars, scanNormalization, scanSmuggling, scanTrojanSource };
export { type Detector, SEVERITY_MAP, type ScanContext, type ScanOptions, type ScanResult, type ScanStats, type Severity, ThreatCategory, type ThreatLoc, type ThreatReport, decodeUnicodeTags, scan, scanHomoglyphs, scanInjectionPatterns, scanInvisibleChars, scanNormalization, scanSmuggling, scanTrojanSource };

@@ -12,2 +12,16 @@ /**

/**
* Numeric severity ranking map.
*
* Lower numbers represent higher severity.
*
* Used for:
* - Severity threshold comparisons
* - Sorting threats by priority
* - Efficient numeric filtering
*
* Example:
* SEVERITY_MAP["CRITICAL"] < SEVERITY_MAP["LOW"] // true
*/
declare const SEVERITY_MAP: Record<Severity, number>;
/**
* Categories of threats detected by PromptShield.

@@ -163,13 +177,31 @@ *

minSeverity?: Severity;
/** Disable invisible-character detection */
/** Disable invisible-character detection
*
* @default false
*/
disableInvisible?: boolean;
/** Disable homoglyph detection */
/** Disable homoglyph detection
*
* @default false
*/
disableHomoglyphs?: boolean;
/** Disable smuggling detection */
/** Disable smuggling detection
*
* @default false
*/
disableSmuggling?: boolean;
/** Disable Trojan Source detection */
/** Disable Trojan Source detection
*
* @default false
*/
disableTrojan?: boolean;
/** Disable normalization detection */
/** Disable normalization detection
*
* @default false
*/
disableNormalization?: boolean;
/** Disable injection-pattern detection */
/** Disable injection-pattern detection
*
* @default false
*/
disableInjectionPatterns?: boolean;

@@ -387,2 +419,2 @@ }

export { type Detector, type ScanContext, type ScanOptions, type ScanResult, type ScanStats, type Severity, ThreatCategory, type ThreatLoc, type ThreatReport, decodeUnicodeTags, scan, scanHomoglyphs, scanInjectionPatterns, scanInvisibleChars, scanNormalization, scanSmuggling, scanTrojanSource };
export { type Detector, SEVERITY_MAP, type ScanContext, type ScanOptions, type ScanResult, type ScanStats, type Severity, ThreatCategory, type ThreatLoc, type ThreatReport, decodeUnicodeTags, scan, scanHomoglyphs, scanInjectionPatterns, scanInvisibleChars, scanNormalization, scanSmuggling, scanTrojanSource };
+4
-4

@@ -1,4 +0,4 @@

"use strict";var x=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var w=(e,t)=>{for(var r in t)x(e,r,{get:t[r],enumerable:!0})},z=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of D(t))!N.call(e,n)&&n!==r&&x(e,n,{get:()=>t[n],enumerable:!(i=j(t,n))||i.enumerable});return e};var M=e=>z(x({},"__esModule",{value:!0}),e);var te={};w(te,{ThreatCategory:()=>H,decodeUnicodeTags:()=>A,scan:()=>ee,scanHomoglyphs:()=>v,scanInjectionPatterns:()=>R,scanInvisibleChars:()=>C,scanNormalization:()=>O,scanSmuggling:()=>L,scanTrojanSource:()=>P});module.exports=M(te);var E=require("perf_hooks");var H=(o=>(o.Invisible="INVISIBLE_CHAR",o.Homoglyph="HOMOGLYPH",o.Smuggling="SMUGGLING",o.Injection="PROMPT_INJECTION",o.Trojan="TROJAN_SOURCE",o.Normalization="NORMALIZATION",o))(H||{});var u=e=>{let t=[0];for(let r=0;r<e.length;r++)e[r]===`
`&&t.push(r+1);return t},p=(e,t)=>{let{lineOffsets:r=[0],baseLine:i=1,baseCol:n=1}=t,s=0,o=r.length-1;for(;s<=o;){let a=s+o>>1;r[a]<=e?s=a+1:o=a-1}let d=Math.max(o,0);return{line:i+d,column:e-r[d]+(d===0?n:1),index:e}};var G=/\p{Script=Latin}/u,B=/\p{Script=Cyrillic}/u,_=/\p{Script=Greek}/u,k=/[\p{L}\p{N}_]+/gu,v=(e,t={},r={})=>{let i=new RegExp(k),n=i.exec(e);if(!n)return[];let s=[];for(r.lineOffsets=r.lineOffsets??u(e);n!==null;){let o=n[0],d=n.index,a=G.test(o),l=B.test(o),c=_.test(o);if(a&&(l||c)){let g=[];if(a&&g.push("Latin"),l&&g.push("Cyrillic"),c&&g.push("Greek"),s.push({ruleId:"PSH001",category:"HOMOGLYPH",severity:"CRITICAL",message:`Mixed-script homoglyph detected: "${o}" (${g.join(" + ")})`,referenceUrl:"https://promptshield.js.org/docs/detectors/homoglyph#PSH001",loc:p(d,r),offendingText:o,readableLabel:`[Mixed-Script] ${o}`,suggestion:"Replace visually similar characters with characters from a single script."}),t?.stopOnFirstThreat)return s}n=i.exec(e)}return s};var $=[{id:"PSI001",severity:"CRITICAL",message:"Prompt injection attempt: ignore previous instructions",regex:/ignore\s+previous\s+instructions/i,normalizedPattern:"ignorepreviousinstructions"},{id:"PSI002",severity:"CRITICAL",message:"Attempt to reveal system prompt",regex:/reveal\s+(system|hidden)\s+prompt/i,normalizedPattern:"revealsystemprompt"},{id:"PSI003",severity:"HIGH",message:"Attempt to disable guardrails",regex:/disable\s+(guardrails|safety)/i,normalizedPattern:"disableguardrails"},{id:"PSI004",severity:"HIGH",message:"System override instruction detected",regex:/override\s+(system|instructions)/i,normalizedPattern:"overridesysteminstructions"}],W=e=>e.toLowerCase().replace(/[^a-z\s]/g,"").replace(/\s+/g,""),R=(e,t={},r={})=>{let i=[];r.lineOffsets=r.lineOffsets??u(e);let n=e.split(`
`),s=0;for(let o of n){let d=W(o);for(let a of $){let l=a.regex.exec(o);if(l){if(i.push({ruleId:a.id,category:"PROMPT_INJECTION",severity:a.severity,message:a.message,offendingText:l[0],loc:p(s+l.index,r),readableLabel:"[Injection]",suggestion:"Remove instruction-override language from prompts or user content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${a.id}`}),t.stopOnFirstThreat)return i;continue}if(d.includes(a.normalizedPattern)&&(i.push({ruleId:a.id,category:"PROMPT_INJECTION",severity:a.severity,message:`${a.message} (obfuscated spacing detected)`,offendingText:o.trim(),loc:p(s,r),readableLabel:"[Injection]",suggestion:"Obfuscated instruction detected. Inspect and remove malicious content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${a.id}`}),t.stopOnFirstThreat))return i}s+=o.length+1}return i};var F={"\u200B":"ZWSP","\u200C":"ZWNJ","\u200D":"ZWJ","\uFEFF":"BOM",\u3164:"HF",\uFFA0:"HHF"},K=/([\u200B-\u200D\uFEFF\u3164\uFFA0]|\uDB40[\uDC00-\uDC7F])/gu,X=16,C=(e,t={},r={})=>{let i=new RegExp(K),n=i.exec(e);if(!n||t?.minSeverity==="CRITICAL")return[];let s=[];r.lineOffsets=r.lineOffsets??u(e);let o=-1,d=-1,a=()=>{o=-1,d=-1},l=()=>{if(o===-1)return;let c=e.slice(o,d),g=A(c),f=[...c].map(S=>{let b=S.codePointAt(0);return F[S]||`U+${b?.toString(16).toUpperCase()}`}),m=p(o,r);if(g){s.push({ruleId:"PSU004",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Unicode tag characters encode hidden ASCII content inside invisible text.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU004",loc:m,offendingText:c,decodedPayload:g,readableLabel:"[TAG_PAYLOAD]",suggestion:"Remove Unicode tag characters containing hidden text."}),a();return}if(t.minSeverity!=="HIGH"){if(c.length>=X){s.push({ruleId:"PSU005",category:"INVISIBLE_CHAR",severity:"MEDIUM",message:"Excessive invisible characters detected. Large invisible sequences are commonly used for padding or obfuscation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU005",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove unnecessary invisible characters."}),a();return}t.minSeverity!=="MEDIUM"&&(s.push({ruleId:"PSU001",category:"INVISIBLE_CHAR",severity:"LOW",message:"Invisible Unicode characters detected. These characters can alter tokenization and prompt interpretation without being visible.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU001",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove invisible characters to ensure the prompt text is interpreted exactly as written."}),a())}};for(;n!==null;){let c=n.index,g=n[0];if(c>0&&c<e.length-1){let f=e[c-1],m=e[c+g.length];if(f?.trim()&&m?.trim()&&(s.push({ruleId:"PSU002",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Invisible character detected inside a visible token. This can manipulate token boundaries or bypass validation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU002",loc:p(c,r),offendingText:g,readableLabel:`[${F[g]}]`||"[INVISIBLE]",suggestion:"Remove invisible characters embedded within words."}),t.stopOnFirstThreat))return s}if(o===-1)o=c,d=c+g.length;else if(c===d)d+=g.length;else{if(l(),t.stopOnFirstThreat&&s.length)return s;o=c,d=c+g.length}n=i.exec(e)}return l(),s},A=e=>{let t="",r=!1;for(let i of e){let n=i.codePointAt(0);if(n>=917504&&n<=917631){let s=n-917504;s>=32&&s<=126&&(t+=String.fromCharCode(s),r=!0)}}return r?t:void 0};var O=(e,t={},r={})=>{if(t.minSeverity==="CRITICAL")return[];let i=[],n=e.normalize("NFKC");if(e===n)return[];r.lineOffsets=r.lineOffsets??u(e);let s=0,o=-1,d=-1,a="",l=()=>{if(o===-1)return;let c=e.slice(o,d);i.push({ruleId:"PSN001",category:"NORMALIZATION",severity:"HIGH",message:"Text changes under Unicode NFKC normalization. This may cause ambiguity between displayed and interpreted content.",referenceUrl:"https://promptshield.js.org/docs/detectors/normalization#PSN001",loc:p(o,r),offendingText:c,decodedPayload:a,readableLabel:"[NFKC_DIFF]",suggestion:"Replace with normalized text to avoid ambiguity."}),o=-1,d=-1,a=""};for(let c of e){let g=c.normalize("NFKC");if(c!==g){if(o===-1?(o=s,d=s+c.length):d+=c.length,a+=g,t.stopOnFirstThreat)return l(),i}else l();s+=c.length}return l(),i};var Z=/(?:[A-Za-z0-9+/]{4}){8,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/g,J=/<!--[\s\S]*?-->/g,V=/\[\s*\]\([^)]+\)/g,Y=/([\u200B-\u200D\u2060\uFEFF\u3164\uFFA0]+)/g,q=e=>{try{let t=Buffer.from(e,"base64").toString("utf8");if(!t)return null;let r=0;for(let n of t){let s=n.charCodeAt(0);s>=32&&s<=126&&r++}return r/t.length>=.7?t:null}catch{return null}},L=(e,t={},r={})=>{if(t.minSeverity==="CRITICAL")return[];let i=[],n;r.lineOffsets=r.lineOffsets??u(e);let s=new RegExp(Y);for(;(n=s.exec(e))!==null;){let l=n[0];if(l.length<8||l.length>4096)continue;let c=Array.from(new Set(l.split("")));if(c.length<2||c.length>3)continue;let[g,f]=c,m=[{zero:g,one:f},{zero:f,one:g}];for(let{zero:S,one:b}of m){let y="";for(let h of l)h===S?y+="0":h===b&&(y+="1");let I="";for(let h=0;h<y.length;h+=8){let U=y.slice(h,h+8);if(U.length!==8)continue;let T=parseInt(U,2);T>=32&&T<=126&&(I+=String.fromCharCode(T))}if(I.length>=3){if(i.push({ruleId:"PSS001",category:"SMUGGLING",severity:"HIGH",message:"Detected hidden steganography message encoded in invisible characters.",loc:p(n.index,r),offendingText:l,decodedPayload:I,readableLabel:`[Hidden]: ${I.slice(0,50)}...`,suggestion:"Invisible-character encoding detected. Inspect hidden content.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS001"}),t.stopOnFirstThreat)return i;break}}}if(t.minSeverity==="HIGH")return i;let o=new RegExp(Z);for(;(n=o.exec(e))!==null;){let l=n[0];if(l.length<24)continue;let c=q(l);if(c&&(i.push({ruleId:"PSS002",category:"SMUGGLING",severity:"MEDIUM",message:"Detected Base64 payload containing readable content.",loc:p(n.index,r),offendingText:l,decodedPayload:c,readableLabel:`[Base64]: ${c.slice(0,50)}...`,suggestion:"Decoded Base64 contains readable text. Inspect payload.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS002"}),t.stopOnFirstThreat))return i}if(t.minSeverity==="MEDIUM")return i;let d=new RegExp(J);for(;(n=d.exec(e))!==null;)if(i.push({ruleId:"PSS003",category:"SMUGGLING",severity:"LOW",message:"Detected hidden Markdown comment.",loc:p(n.index,r),offendingText:n[0],readableLabel:"[Hidden Comment]",suggestion:"Comments are not visible in rendered Markdown but can carry instructions.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS003"}),t.stopOnFirstThreat)return i;let a=new RegExp(V);for(;(n=a.exec(e))!==null;)if(i.push({ruleId:"PSS004",category:"SMUGGLING",severity:"LOW",message:"Detected empty Markdown link (invisible in rendered output).",loc:p(n.index,r),offendingText:n[0],readableLabel:"[Empty Link]",suggestion:"Empty links can be used to hide URLs or data.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS004"}),t.stopOnFirstThreat)return i;return i};var Q={"\u202A":"PUSH","\u202B":"PUSH","\u202D":"PUSH","\u202E":"PUSH","\u2066":"PUSH","\u2067":"PUSH","\u2068":"PUSH","\u202C":"POP","\u2069":"POP"},P=(e,t={},r={})=>{let i=[];r.lineOffsets=r.lineOffsets??u(e);let n=e.split(`
`),s=0;for(let o=0;o<n.length;o++){let d=n[o],a=null;for(let l=0;l<d.length;l++){let c=d[l],g=Q[c];if(g==="PUSH"&&a===null)a=s;else if(g==="POP"&&a!==null){let f=s+1,m=e.slice(a,f),S=e.slice(a+1,s);if(i.push({ruleId:"PST001",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Bidirectional override characters detected (Trojan Source). These characters can visually reorder text and mislead readers.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST001",loc:p(a,r),offendingText:m,decodedPayload:S,readableLabel:"[BIDI_OVERRIDE]",suggestion:"Remove bidirectional control characters from the source."}),a=null,t.stopOnFirstThreat)return i}s++}if(a!==null){let l=s,c=e.slice(a,l),g=e.slice(a+1,l);if(i.push({ruleId:"PST002",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Unterminated bidirectional override sequence detected (Trojan Source). This may cause visual and logical text order to differ.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST002",loc:p(a,r),offendingText:c,decodedPayload:g,readableLabel:"[BIDI_UNTERMINATED]",suggestion:"Remove BIDI control characters or ensure they are properly terminated within the same line."}),t.stopOnFirstThreat)return i}s++}return i};var ee=(e,t={},r={})=>{let i=E.performance.now(),n=[],s=[];t.disableTrojan||s.push(P),t.disableInvisible||s.push(C),t.disableHomoglyphs||s.push(v),t.disableNormalization||s.push(O),t.disableSmuggling||s.push(L),t.disableInjectionPatterns||s.push(R);for(let d of s){let a=d(e,t,r);if(n.push(...a),t.stopOnFirstThreat&&a.length>0)break}let o=E.performance.now();return{threats:n,stats:{durationMs:o-i,totalChars:e.length},isClean:n.length===0}};0&&(module.exports={ThreatCategory,decodeUnicodeTags,scan,scanHomoglyphs,scanInjectionPatterns,scanInvisibleChars,scanNormalization,scanSmuggling,scanTrojanSource});
"use strict";var x=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var M=Object.prototype.hasOwnProperty;var N=(e,t)=>{for(var r in t)x(e,r,{get:t[r],enumerable:!0})},w=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of D(t))!M.call(e,n)&&n!==r&&x(e,n,{get:()=>t[n],enumerable:!(i=j(t,n))||i.enumerable});return e};var z=e=>w(x({},"__esModule",{value:!0}),e);var re={};N(re,{SEVERITY_MAP:()=>G,ThreatCategory:()=>U,decodeUnicodeTags:()=>A,scan:()=>te,scanHomoglyphs:()=>v,scanInjectionPatterns:()=>R,scanInvisibleChars:()=>C,scanNormalization:()=>O,scanSmuggling:()=>L,scanTrojanSource:()=>P});module.exports=z(re);var E=require("perf_hooks");var G={CRITICAL:1,HIGH:2,MEDIUM:3,LOW:4},U=(o=>(o.Invisible="INVISIBLE_CHAR",o.Homoglyph="HOMOGLYPH",o.Smuggling="SMUGGLING",o.Injection="PROMPT_INJECTION",o.Trojan="TROJAN_SOURCE",o.Normalization="NORMALIZATION",o))(U||{});var u=e=>{let t=[0];for(let r=0;r<e.length;r++)e[r]===`
`&&t.push(r+1);return t},p=(e,t)=>{let{lineOffsets:r=[0],baseLine:i=1,baseCol:n=1}=t,s=0,o=r.length-1;for(;s<=o;){let a=s+o>>1;r[a]<=e?s=a+1:o=a-1}let d=Math.max(o,0);return{line:i+d,column:e-r[d]+(d===0?n:1),index:e}};var B=/\p{Script=Latin}/u,_=/\p{Script=Cyrillic}/u,k=/\p{Script=Greek}/u,$=/[\p{L}\p{N}_]+/gu,v=(e,t={},r={})=>{let i=new RegExp($),n=i.exec(e);if(!n)return[];let s=[];for(r.lineOffsets=r.lineOffsets??u(e);n!==null;){let o=n[0],d=n.index,a=B.test(o),l=_.test(o),c=k.test(o);if(a&&(l||c)){let g=[];if(a&&g.push("Latin"),l&&g.push("Cyrillic"),c&&g.push("Greek"),s.push({ruleId:"PSH001",category:"HOMOGLYPH",severity:"CRITICAL",message:`Mixed-script homoglyph detected: "${o}" (${g.join(" + ")})`,referenceUrl:"https://promptshield.js.org/docs/detectors/homoglyph#PSH001",loc:p(d,r),offendingText:o,readableLabel:`[Mixed-Script] ${o}`,suggestion:"Replace visually similar characters with characters from a single script."}),t?.stopOnFirstThreat)return s}n=i.exec(e)}return s};var W=[{id:"PSI001",severity:"CRITICAL",message:"Prompt injection attempt: ignore previous instructions",regex:/ignore\s+previous\s+instructions/i,normalizedPattern:"ignorepreviousinstructions"},{id:"PSI002",severity:"CRITICAL",message:"Attempt to reveal system prompt",regex:/reveal\s+(system|hidden)\s+prompt/i,normalizedPattern:"revealsystemprompt"},{id:"PSI003",severity:"HIGH",message:"Attempt to disable guardrails",regex:/disable\s+(guardrails|safety)/i,normalizedPattern:"disableguardrails"},{id:"PSI004",severity:"HIGH",message:"System override instruction detected",regex:/override\s+(system|instructions)/i,normalizedPattern:"overridesysteminstructions"}],K=e=>e.toLowerCase().replace(/[^a-z\s]/g,"").replace(/\s+/g,""),R=(e,t={},r={})=>{let i=[];r.lineOffsets=r.lineOffsets??u(e);let n=e.split(`
`),s=0;for(let o of n){let d=K(o);for(let a of W){let l=a.regex.exec(o);if(l){if(i.push({ruleId:a.id,category:"PROMPT_INJECTION",severity:a.severity,message:a.message,offendingText:l[0],loc:p(s+l.index,r),readableLabel:"[Injection]",suggestion:"Remove instruction-override language from prompts or user content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${a.id}`}),t.stopOnFirstThreat)return i;continue}if(d.includes(a.normalizedPattern)&&(i.push({ruleId:a.id,category:"PROMPT_INJECTION",severity:a.severity,message:`${a.message} (obfuscated spacing detected)`,offendingText:o.trim(),loc:p(s,r),readableLabel:"[Injection]",suggestion:"Obfuscated instruction detected. Inspect and remove malicious content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${a.id}`}),t.stopOnFirstThreat))return i}s+=o.length+1}return i};var F={"\u200B":"ZWSP","\u200C":"ZWNJ","\u200D":"ZWJ","\uFEFF":"BOM",\u3164:"HF",\uFFA0:"HHF"},X=/([\u200B-\u200D\uFEFF\u3164\uFFA0]|\uDB40[\uDC00-\uDC7F])/gu,Z=16,C=(e,t={},r={})=>{let i=new RegExp(X),n=i.exec(e);if(!n||t?.minSeverity==="CRITICAL")return[];let s=[];r.lineOffsets=r.lineOffsets??u(e);let o=-1,d=-1,a=()=>{o=-1,d=-1},l=()=>{if(o===-1)return;let c=e.slice(o,d),g=A(c),f=[...c].map(S=>{let b=S.codePointAt(0);return F[S]||`U+${b?.toString(16).toUpperCase()}`}),m=p(o,r);if(g){s.push({ruleId:"PSU004",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Unicode tag characters encode hidden ASCII content inside invisible text.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU004",loc:m,offendingText:c,decodedPayload:g,readableLabel:"[TAG_PAYLOAD]",suggestion:"Remove Unicode tag characters containing hidden text."}),a();return}if(t.minSeverity!=="HIGH"){if(c.length>=Z){s.push({ruleId:"PSU005",category:"INVISIBLE_CHAR",severity:"MEDIUM",message:"Excessive invisible characters detected. Large invisible sequences are commonly used for padding or obfuscation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU005",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove unnecessary invisible characters."}),a();return}t.minSeverity!=="MEDIUM"&&(s.push({ruleId:"PSU001",category:"INVISIBLE_CHAR",severity:"LOW",message:"Invisible Unicode characters detected. These characters can alter tokenization and prompt interpretation without being visible.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU001",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove invisible characters to ensure the prompt text is interpreted exactly as written."}),a())}};for(;n!==null;){let c=n.index,g=n[0];if(c>0&&c<e.length-1){let f=e[c-1],m=e[c+g.length];if(f?.trim()&&m?.trim()&&(s.push({ruleId:"PSU002",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Invisible character detected inside a visible token. This can manipulate token boundaries or bypass validation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU002",loc:p(c,r),offendingText:g,readableLabel:`[${F[g]}]`||"[INVISIBLE]",suggestion:"Remove invisible characters embedded within words."}),t.stopOnFirstThreat))return s}if(o===-1)o=c,d=c+g.length;else if(c===d)d+=g.length;else{if(l(),t.stopOnFirstThreat&&s.length)return s;o=c,d=c+g.length}n=i.exec(e)}return l(),s},A=e=>{let t="",r=!1;for(let i of e){let n=i.codePointAt(0);if(n>=917504&&n<=917631){let s=n-917504;s>=32&&s<=126&&(t+=String.fromCharCode(s),r=!0)}}return r?t:void 0};var O=(e,t={},r={})=>{if(t.minSeverity==="CRITICAL")return[];let i=[],n=e.normalize("NFKC");if(e===n)return[];r.lineOffsets=r.lineOffsets??u(e);let s=0,o=-1,d=-1,a="",l=()=>{if(o===-1)return;let c=e.slice(o,d);i.push({ruleId:"PSN001",category:"NORMALIZATION",severity:"HIGH",message:"Text changes under Unicode NFKC normalization. This may cause ambiguity between displayed and interpreted content.",referenceUrl:"https://promptshield.js.org/docs/detectors/normalization#PSN001",loc:p(o,r),offendingText:c,decodedPayload:a,readableLabel:"[NFKC_DIFF]",suggestion:"Replace with normalized text to avoid ambiguity."}),o=-1,d=-1,a=""};for(let c of e){let g=c.normalize("NFKC");if(c!==g){if(o===-1?(o=s,d=s+c.length):d+=c.length,a+=g,t.stopOnFirstThreat)return l(),i}else l();s+=c.length}return l(),i};var V=/(?:[A-Za-z0-9+/]{4}){8,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/g,J=/<!--[\s\S]*?-->/g,Y=/\[\s*\]\([^)]+\)/g,q=/([\u200B-\u200D\u2060\uFEFF\u3164\uFFA0]+)/g,Q=e=>{try{let t=Buffer.from(e,"base64").toString("utf8");if(!t)return null;let r=0;for(let n of t){let s=n.charCodeAt(0);s>=32&&s<=126&&r++}return r/t.length>=.7?t:null}catch{return null}},L=(e,t={},r={})=>{if(t.minSeverity==="CRITICAL")return[];let i=[],n;r.lineOffsets=r.lineOffsets??u(e);let s=new RegExp(q);for(;(n=s.exec(e))!==null;){let l=n[0];if(l.length<8||l.length>4096)continue;let c=Array.from(new Set(l.split("")));if(c.length<2||c.length>3)continue;let[g,f]=c,m=[{zero:g,one:f},{zero:f,one:g}];for(let{zero:S,one:b}of m){let I="";for(let h of l)h===S?I+="0":h===b&&(I+="1");let y="";for(let h=0;h<I.length;h+=8){let H=I.slice(h,h+8);if(H.length!==8)continue;let T=parseInt(H,2);T>=32&&T<=126&&(y+=String.fromCharCode(T))}if(y.length>=3){if(i.push({ruleId:"PSS001",category:"SMUGGLING",severity:"HIGH",message:"Detected hidden steganography message encoded in invisible characters.",loc:p(n.index,r),offendingText:l,decodedPayload:y,readableLabel:`[Hidden]: ${y.slice(0,50)}...`,suggestion:"Invisible-character encoding detected. Inspect hidden content.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS001"}),t.stopOnFirstThreat)return i;break}}}if(t.minSeverity==="HIGH")return i;let o=new RegExp(V);for(;(n=o.exec(e))!==null;){let l=n[0];if(l.length<24)continue;let c=Q(l);if(c&&(i.push({ruleId:"PSS002",category:"SMUGGLING",severity:"MEDIUM",message:"Detected Base64 payload containing readable content.",loc:p(n.index,r),offendingText:l,decodedPayload:c,readableLabel:`[Base64]: ${c.slice(0,50)}...`,suggestion:"Decoded Base64 contains readable text. Inspect payload.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS002"}),t.stopOnFirstThreat))return i}if(t.minSeverity==="MEDIUM")return i;let d=new RegExp(J);for(;(n=d.exec(e))!==null;)if(i.push({ruleId:"PSS003",category:"SMUGGLING",severity:"LOW",message:"Detected hidden Markdown comment.",loc:p(n.index,r),offendingText:n[0],readableLabel:"[Hidden Comment]",suggestion:"Comments are not visible in rendered Markdown but can carry instructions.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS003"}),t.stopOnFirstThreat)return i;let a=new RegExp(Y);for(;(n=a.exec(e))!==null;)if(i.push({ruleId:"PSS004",category:"SMUGGLING",severity:"LOW",message:"Detected empty Markdown link (invisible in rendered output).",loc:p(n.index,r),offendingText:n[0],readableLabel:"[Empty Link]",suggestion:"Empty links can be used to hide URLs or data.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS004"}),t.stopOnFirstThreat)return i;return i};var ee={"\u202A":"PUSH","\u202B":"PUSH","\u202D":"PUSH","\u202E":"PUSH","\u2066":"PUSH","\u2067":"PUSH","\u2068":"PUSH","\u202C":"POP","\u2069":"POP"},P=(e,t={},r={})=>{let i=[];r.lineOffsets=r.lineOffsets??u(e);let n=e.split(`
`),s=0;for(let o=0;o<n.length;o++){let d=n[o],a=null;for(let l=0;l<d.length;l++){let c=d[l],g=ee[c];if(g==="PUSH"&&a===null)a=s;else if(g==="POP"&&a!==null){let f=s+1,m=e.slice(a,f),S=e.slice(a+1,s);if(i.push({ruleId:"PST001",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Bidirectional override characters detected (Trojan Source). These characters can visually reorder text and mislead readers.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST001",loc:p(a,r),offendingText:m,decodedPayload:S,readableLabel:"[BIDI_OVERRIDE]",suggestion:"Remove bidirectional control characters from the source."}),a=null,t.stopOnFirstThreat)return i}s++}if(a!==null){let l=s,c=e.slice(a,l),g=e.slice(a+1,l);if(i.push({ruleId:"PST002",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Unterminated bidirectional override sequence detected (Trojan Source). This may cause visual and logical text order to differ.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST002",loc:p(a,r),offendingText:c,decodedPayload:g,readableLabel:"[BIDI_UNTERMINATED]",suggestion:"Remove BIDI control characters or ensure they are properly terminated within the same line."}),t.stopOnFirstThreat)return i}s++}return i};var te=(e,t={},r={})=>{let i=E.performance.now(),n=[],s=[];t.disableTrojan||s.push(P),t.disableInvisible||s.push(C),t.disableHomoglyphs||s.push(v),t.disableNormalization||s.push(O),t.disableSmuggling||s.push(L),t.disableInjectionPatterns||s.push(R);for(let d of s){let a=d(e,t,r);if(n.push(...a),t.stopOnFirstThreat&&a.length>0)break}let o=E.performance.now();return{threats:n,stats:{durationMs:o-i,totalChars:e.length},isClean:n.length===0}};0&&(module.exports={SEVERITY_MAP,ThreatCategory,decodeUnicodeTags,scan,scanHomoglyphs,scanInjectionPatterns,scanInvisibleChars,scanNormalization,scanSmuggling,scanTrojanSource});

@@ -1,4 +0,4 @@

import{performance as U}from"perf_hooks";var H=(s=>(s.Invisible="INVISIBLE_CHAR",s.Homoglyph="HOMOGLYPH",s.Smuggling="SMUGGLING",s.Injection="PROMPT_INJECTION",s.Trojan="TROJAN_SOURCE",s.Normalization="NORMALIZATION",s))(H||{});var u=e=>{let r=[0];for(let n=0;n<e.length;n++)e[n]===`
`&&r.push(n+1);return r},p=(e,r)=>{let{lineOffsets:n=[0],baseLine:a=1,baseCol:o=1}=r,t=0,s=n.length-1;for(;t<=s;){let i=t+s>>1;n[i]<=e?t=i+1:s=i-1}let d=Math.max(s,0);return{line:a+d,column:e-n[d]+(d===0?o:1),index:e}};var F=/\p{Script=Latin}/u,A=/\p{Script=Cyrillic}/u,j=/\p{Script=Greek}/u,D=/[\p{L}\p{N}_]+/gu,v=(e,r={},n={})=>{let a=new RegExp(D),o=a.exec(e);if(!o)return[];let t=[];for(n.lineOffsets=n.lineOffsets??u(e);o!==null;){let s=o[0],d=o.index,i=F.test(s),l=A.test(s),c=j.test(s);if(i&&(l||c)){let g=[];if(i&&g.push("Latin"),l&&g.push("Cyrillic"),c&&g.push("Greek"),t.push({ruleId:"PSH001",category:"HOMOGLYPH",severity:"CRITICAL",message:`Mixed-script homoglyph detected: "${s}" (${g.join(" + ")})`,referenceUrl:"https://promptshield.js.org/docs/detectors/homoglyph#PSH001",loc:p(d,n),offendingText:s,readableLabel:`[Mixed-Script] ${s}`,suggestion:"Replace visually similar characters with characters from a single script."}),r?.stopOnFirstThreat)return t}o=a.exec(e)}return t};var N=[{id:"PSI001",severity:"CRITICAL",message:"Prompt injection attempt: ignore previous instructions",regex:/ignore\s+previous\s+instructions/i,normalizedPattern:"ignorepreviousinstructions"},{id:"PSI002",severity:"CRITICAL",message:"Attempt to reveal system prompt",regex:/reveal\s+(system|hidden)\s+prompt/i,normalizedPattern:"revealsystemprompt"},{id:"PSI003",severity:"HIGH",message:"Attempt to disable guardrails",regex:/disable\s+(guardrails|safety)/i,normalizedPattern:"disableguardrails"},{id:"PSI004",severity:"HIGH",message:"System override instruction detected",regex:/override\s+(system|instructions)/i,normalizedPattern:"overridesysteminstructions"}],w=e=>e.toLowerCase().replace(/[^a-z\s]/g,"").replace(/\s+/g,""),R=(e,r={},n={})=>{let a=[];n.lineOffsets=n.lineOffsets??u(e);let o=e.split(`
`),t=0;for(let s of o){let d=w(s);for(let i of N){let l=i.regex.exec(s);if(l){if(a.push({ruleId:i.id,category:"PROMPT_INJECTION",severity:i.severity,message:i.message,offendingText:l[0],loc:p(t+l.index,n),readableLabel:"[Injection]",suggestion:"Remove instruction-override language from prompts or user content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${i.id}`}),r.stopOnFirstThreat)return a;continue}if(d.includes(i.normalizedPattern)&&(a.push({ruleId:i.id,category:"PROMPT_INJECTION",severity:i.severity,message:`${i.message} (obfuscated spacing detected)`,offendingText:s.trim(),loc:p(t,n),readableLabel:"[Injection]",suggestion:"Obfuscated instruction detected. Inspect and remove malicious content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${i.id}`}),r.stopOnFirstThreat))return a}t+=s.length+1}return a};var C={"\u200B":"ZWSP","\u200C":"ZWNJ","\u200D":"ZWJ","\uFEFF":"BOM",\u3164:"HF",\uFFA0:"HHF"},z=/([\u200B-\u200D\uFEFF\u3164\uFFA0]|\uDB40[\uDC00-\uDC7F])/gu,M=16,O=(e,r={},n={})=>{let a=new RegExp(z),o=a.exec(e);if(!o||r?.minSeverity==="CRITICAL")return[];let t=[];n.lineOffsets=n.lineOffsets??u(e);let s=-1,d=-1,i=()=>{s=-1,d=-1},l=()=>{if(s===-1)return;let c=e.slice(s,d),g=G(c),f=[...c].map(S=>{let b=S.codePointAt(0);return C[S]||`U+${b?.toString(16).toUpperCase()}`}),m=p(s,n);if(g){t.push({ruleId:"PSU004",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Unicode tag characters encode hidden ASCII content inside invisible text.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU004",loc:m,offendingText:c,decodedPayload:g,readableLabel:"[TAG_PAYLOAD]",suggestion:"Remove Unicode tag characters containing hidden text."}),i();return}if(r.minSeverity!=="HIGH"){if(c.length>=M){t.push({ruleId:"PSU005",category:"INVISIBLE_CHAR",severity:"MEDIUM",message:"Excessive invisible characters detected. Large invisible sequences are commonly used for padding or obfuscation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU005",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove unnecessary invisible characters."}),i();return}r.minSeverity!=="MEDIUM"&&(t.push({ruleId:"PSU001",category:"INVISIBLE_CHAR",severity:"LOW",message:"Invisible Unicode characters detected. These characters can alter tokenization and prompt interpretation without being visible.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU001",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove invisible characters to ensure the prompt text is interpreted exactly as written."}),i())}};for(;o!==null;){let c=o.index,g=o[0];if(c>0&&c<e.length-1){let f=e[c-1],m=e[c+g.length];if(f?.trim()&&m?.trim()&&(t.push({ruleId:"PSU002",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Invisible character detected inside a visible token. This can manipulate token boundaries or bypass validation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU002",loc:p(c,n),offendingText:g,readableLabel:`[${C[g]}]`||"[INVISIBLE]",suggestion:"Remove invisible characters embedded within words."}),r.stopOnFirstThreat))return t}if(s===-1)s=c,d=c+g.length;else if(c===d)d+=g.length;else{if(l(),r.stopOnFirstThreat&&t.length)return t;s=c,d=c+g.length}o=a.exec(e)}return l(),t},G=e=>{let r="",n=!1;for(let a of e){let o=a.codePointAt(0);if(o>=917504&&o<=917631){let t=o-917504;t>=32&&t<=126&&(r+=String.fromCharCode(t),n=!0)}}return n?r:void 0};var L=(e,r={},n={})=>{if(r.minSeverity==="CRITICAL")return[];let a=[],o=e.normalize("NFKC");if(e===o)return[];n.lineOffsets=n.lineOffsets??u(e);let t=0,s=-1,d=-1,i="",l=()=>{if(s===-1)return;let c=e.slice(s,d);a.push({ruleId:"PSN001",category:"NORMALIZATION",severity:"HIGH",message:"Text changes under Unicode NFKC normalization. This may cause ambiguity between displayed and interpreted content.",referenceUrl:"https://promptshield.js.org/docs/detectors/normalization#PSN001",loc:p(s,n),offendingText:c,decodedPayload:i,readableLabel:"[NFKC_DIFF]",suggestion:"Replace with normalized text to avoid ambiguity."}),s=-1,d=-1,i=""};for(let c of e){let g=c.normalize("NFKC");if(c!==g){if(s===-1?(s=t,d=t+c.length):d+=c.length,i+=g,r.stopOnFirstThreat)return l(),a}else l();t+=c.length}return l(),a};var B=/(?:[A-Za-z0-9+/]{4}){8,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/g,_=/<!--[\s\S]*?-->/g,k=/\[\s*\]\([^)]+\)/g,$=/([\u200B-\u200D\u2060\uFEFF\u3164\uFFA0]+)/g,W=e=>{try{let r=Buffer.from(e,"base64").toString("utf8");if(!r)return null;let n=0;for(let o of r){let t=o.charCodeAt(0);t>=32&&t<=126&&n++}return n/r.length>=.7?r:null}catch{return null}},P=(e,r={},n={})=>{if(r.minSeverity==="CRITICAL")return[];let a=[],o;n.lineOffsets=n.lineOffsets??u(e);let t=new RegExp($);for(;(o=t.exec(e))!==null;){let l=o[0];if(l.length<8||l.length>4096)continue;let c=Array.from(new Set(l.split("")));if(c.length<2||c.length>3)continue;let[g,f]=c,m=[{zero:g,one:f},{zero:f,one:g}];for(let{zero:S,one:b}of m){let y="";for(let h of l)h===S?y+="0":h===b&&(y+="1");let I="";for(let h=0;h<y.length;h+=8){let x=y.slice(h,h+8);if(x.length!==8)continue;let T=parseInt(x,2);T>=32&&T<=126&&(I+=String.fromCharCode(T))}if(I.length>=3){if(a.push({ruleId:"PSS001",category:"SMUGGLING",severity:"HIGH",message:"Detected hidden steganography message encoded in invisible characters.",loc:p(o.index,n),offendingText:l,decodedPayload:I,readableLabel:`[Hidden]: ${I.slice(0,50)}...`,suggestion:"Invisible-character encoding detected. Inspect hidden content.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS001"}),r.stopOnFirstThreat)return a;break}}}if(r.minSeverity==="HIGH")return a;let s=new RegExp(B);for(;(o=s.exec(e))!==null;){let l=o[0];if(l.length<24)continue;let c=W(l);if(c&&(a.push({ruleId:"PSS002",category:"SMUGGLING",severity:"MEDIUM",message:"Detected Base64 payload containing readable content.",loc:p(o.index,n),offendingText:l,decodedPayload:c,readableLabel:`[Base64]: ${c.slice(0,50)}...`,suggestion:"Decoded Base64 contains readable text. Inspect payload.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS002"}),r.stopOnFirstThreat))return a}if(r.minSeverity==="MEDIUM")return a;let d=new RegExp(_);for(;(o=d.exec(e))!==null;)if(a.push({ruleId:"PSS003",category:"SMUGGLING",severity:"LOW",message:"Detected hidden Markdown comment.",loc:p(o.index,n),offendingText:o[0],readableLabel:"[Hidden Comment]",suggestion:"Comments are not visible in rendered Markdown but can carry instructions.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS003"}),r.stopOnFirstThreat)return a;let i=new RegExp(k);for(;(o=i.exec(e))!==null;)if(a.push({ruleId:"PSS004",category:"SMUGGLING",severity:"LOW",message:"Detected empty Markdown link (invisible in rendered output).",loc:p(o.index,n),offendingText:o[0],readableLabel:"[Empty Link]",suggestion:"Empty links can be used to hide URLs or data.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS004"}),r.stopOnFirstThreat)return a;return a};var K={"\u202A":"PUSH","\u202B":"PUSH","\u202D":"PUSH","\u202E":"PUSH","\u2066":"PUSH","\u2067":"PUSH","\u2068":"PUSH","\u202C":"POP","\u2069":"POP"},E=(e,r={},n={})=>{let a=[];n.lineOffsets=n.lineOffsets??u(e);let o=e.split(`
`),t=0;for(let s=0;s<o.length;s++){let d=o[s],i=null;for(let l=0;l<d.length;l++){let c=d[l],g=K[c];if(g==="PUSH"&&i===null)i=t;else if(g==="POP"&&i!==null){let f=t+1,m=e.slice(i,f),S=e.slice(i+1,t);if(a.push({ruleId:"PST001",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Bidirectional override characters detected (Trojan Source). These characters can visually reorder text and mislead readers.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST001",loc:p(i,n),offendingText:m,decodedPayload:S,readableLabel:"[BIDI_OVERRIDE]",suggestion:"Remove bidirectional control characters from the source."}),i=null,r.stopOnFirstThreat)return a}t++}if(i!==null){let l=t,c=e.slice(i,l),g=e.slice(i+1,l);if(a.push({ruleId:"PST002",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Unterminated bidirectional override sequence detected (Trojan Source). This may cause visual and logical text order to differ.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST002",loc:p(i,n),offendingText:c,decodedPayload:g,readableLabel:"[BIDI_UNTERMINATED]",suggestion:"Remove BIDI control characters or ensure they are properly terminated within the same line."}),r.stopOnFirstThreat)return a}t++}return a};var fe=(e,r={},n={})=>{let a=U.now(),o=[],t=[];r.disableTrojan||t.push(E),r.disableInvisible||t.push(O),r.disableHomoglyphs||t.push(v),r.disableNormalization||t.push(L),r.disableSmuggling||t.push(P),r.disableInjectionPatterns||t.push(R);for(let d of t){let i=d(e,r,n);if(o.push(...i),r.stopOnFirstThreat&&i.length>0)break}let s=U.now();return{threats:o,stats:{durationMs:s-a,totalChars:e.length},isClean:o.length===0}};export{H as ThreatCategory,G as decodeUnicodeTags,fe as scan,v as scanHomoglyphs,R as scanInjectionPatterns,O as scanInvisibleChars,L as scanNormalization,P as scanSmuggling,E as scanTrojanSource};
import{performance as H}from"perf_hooks";var X={CRITICAL:1,HIGH:2,MEDIUM:3,LOW:4},U=(s=>(s.Invisible="INVISIBLE_CHAR",s.Homoglyph="HOMOGLYPH",s.Smuggling="SMUGGLING",s.Injection="PROMPT_INJECTION",s.Trojan="TROJAN_SOURCE",s.Normalization="NORMALIZATION",s))(U||{});var u=e=>{let r=[0];for(let n=0;n<e.length;n++)e[n]===`
`&&r.push(n+1);return r},p=(e,r)=>{let{lineOffsets:n=[0],baseLine:a=1,baseCol:o=1}=r,t=0,s=n.length-1;for(;t<=s;){let i=t+s>>1;n[i]<=e?t=i+1:s=i-1}let d=Math.max(s,0);return{line:a+d,column:e-n[d]+(d===0?o:1),index:e}};var F=/\p{Script=Latin}/u,A=/\p{Script=Cyrillic}/u,j=/\p{Script=Greek}/u,D=/[\p{L}\p{N}_]+/gu,v=(e,r={},n={})=>{let a=new RegExp(D),o=a.exec(e);if(!o)return[];let t=[];for(n.lineOffsets=n.lineOffsets??u(e);o!==null;){let s=o[0],d=o.index,i=F.test(s),l=A.test(s),c=j.test(s);if(i&&(l||c)){let g=[];if(i&&g.push("Latin"),l&&g.push("Cyrillic"),c&&g.push("Greek"),t.push({ruleId:"PSH001",category:"HOMOGLYPH",severity:"CRITICAL",message:`Mixed-script homoglyph detected: "${s}" (${g.join(" + ")})`,referenceUrl:"https://promptshield.js.org/docs/detectors/homoglyph#PSH001",loc:p(d,n),offendingText:s,readableLabel:`[Mixed-Script] ${s}`,suggestion:"Replace visually similar characters with characters from a single script."}),r?.stopOnFirstThreat)return t}o=a.exec(e)}return t};var M=[{id:"PSI001",severity:"CRITICAL",message:"Prompt injection attempt: ignore previous instructions",regex:/ignore\s+previous\s+instructions/i,normalizedPattern:"ignorepreviousinstructions"},{id:"PSI002",severity:"CRITICAL",message:"Attempt to reveal system prompt",regex:/reveal\s+(system|hidden)\s+prompt/i,normalizedPattern:"revealsystemprompt"},{id:"PSI003",severity:"HIGH",message:"Attempt to disable guardrails",regex:/disable\s+(guardrails|safety)/i,normalizedPattern:"disableguardrails"},{id:"PSI004",severity:"HIGH",message:"System override instruction detected",regex:/override\s+(system|instructions)/i,normalizedPattern:"overridesysteminstructions"}],N=e=>e.toLowerCase().replace(/[^a-z\s]/g,"").replace(/\s+/g,""),R=(e,r={},n={})=>{let a=[];n.lineOffsets=n.lineOffsets??u(e);let o=e.split(`
`),t=0;for(let s of o){let d=N(s);for(let i of M){let l=i.regex.exec(s);if(l){if(a.push({ruleId:i.id,category:"PROMPT_INJECTION",severity:i.severity,message:i.message,offendingText:l[0],loc:p(t+l.index,n),readableLabel:"[Injection]",suggestion:"Remove instruction-override language from prompts or user content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${i.id}`}),r.stopOnFirstThreat)return a;continue}if(d.includes(i.normalizedPattern)&&(a.push({ruleId:i.id,category:"PROMPT_INJECTION",severity:i.severity,message:`${i.message} (obfuscated spacing detected)`,offendingText:s.trim(),loc:p(t,n),readableLabel:"[Injection]",suggestion:"Obfuscated instruction detected. Inspect and remove malicious content.",referenceUrl:`https://promptshield.js.org/docs/detectors/injection-patterns#${i.id}`}),r.stopOnFirstThreat))return a}t+=s.length+1}return a};var C={"\u200B":"ZWSP","\u200C":"ZWNJ","\u200D":"ZWJ","\uFEFF":"BOM",\u3164:"HF",\uFFA0:"HHF"},w=/([\u200B-\u200D\uFEFF\u3164\uFFA0]|\uDB40[\uDC00-\uDC7F])/gu,z=16,O=(e,r={},n={})=>{let a=new RegExp(w),o=a.exec(e);if(!o||r?.minSeverity==="CRITICAL")return[];let t=[];n.lineOffsets=n.lineOffsets??u(e);let s=-1,d=-1,i=()=>{s=-1,d=-1},l=()=>{if(s===-1)return;let c=e.slice(s,d),g=G(c),f=[...c].map(S=>{let b=S.codePointAt(0);return C[S]||`U+${b?.toString(16).toUpperCase()}`}),m=p(s,n);if(g){t.push({ruleId:"PSU004",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Unicode tag characters encode hidden ASCII content inside invisible text.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU004",loc:m,offendingText:c,decodedPayload:g,readableLabel:"[TAG_PAYLOAD]",suggestion:"Remove Unicode tag characters containing hidden text."}),i();return}if(r.minSeverity!=="HIGH"){if(c.length>=z){t.push({ruleId:"PSU005",category:"INVISIBLE_CHAR",severity:"MEDIUM",message:"Excessive invisible characters detected. Large invisible sequences are commonly used for padding or obfuscation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU005",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove unnecessary invisible characters."}),i();return}r.minSeverity!=="MEDIUM"&&(t.push({ruleId:"PSU001",category:"INVISIBLE_CHAR",severity:"LOW",message:"Invisible Unicode characters detected. These characters can alter tokenization and prompt interpretation without being visible.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU001",loc:m,offendingText:c,readableLabel:`[${f.join(" ")}]`,suggestion:"Remove invisible characters to ensure the prompt text is interpreted exactly as written."}),i())}};for(;o!==null;){let c=o.index,g=o[0];if(c>0&&c<e.length-1){let f=e[c-1],m=e[c+g.length];if(f?.trim()&&m?.trim()&&(t.push({ruleId:"PSU002",category:"INVISIBLE_CHAR",severity:"HIGH",message:"Invisible character detected inside a visible token. This can manipulate token boundaries or bypass validation.",referenceUrl:"https://promptshield.js.org/docs/detectors/invisible-chars#PSU002",loc:p(c,n),offendingText:g,readableLabel:`[${C[g]}]`||"[INVISIBLE]",suggestion:"Remove invisible characters embedded within words."}),r.stopOnFirstThreat))return t}if(s===-1)s=c,d=c+g.length;else if(c===d)d+=g.length;else{if(l(),r.stopOnFirstThreat&&t.length)return t;s=c,d=c+g.length}o=a.exec(e)}return l(),t},G=e=>{let r="",n=!1;for(let a of e){let o=a.codePointAt(0);if(o>=917504&&o<=917631){let t=o-917504;t>=32&&t<=126&&(r+=String.fromCharCode(t),n=!0)}}return n?r:void 0};var L=(e,r={},n={})=>{if(r.minSeverity==="CRITICAL")return[];let a=[],o=e.normalize("NFKC");if(e===o)return[];n.lineOffsets=n.lineOffsets??u(e);let t=0,s=-1,d=-1,i="",l=()=>{if(s===-1)return;let c=e.slice(s,d);a.push({ruleId:"PSN001",category:"NORMALIZATION",severity:"HIGH",message:"Text changes under Unicode NFKC normalization. This may cause ambiguity between displayed and interpreted content.",referenceUrl:"https://promptshield.js.org/docs/detectors/normalization#PSN001",loc:p(s,n),offendingText:c,decodedPayload:i,readableLabel:"[NFKC_DIFF]",suggestion:"Replace with normalized text to avoid ambiguity."}),s=-1,d=-1,i=""};for(let c of e){let g=c.normalize("NFKC");if(c!==g){if(s===-1?(s=t,d=t+c.length):d+=c.length,i+=g,r.stopOnFirstThreat)return l(),a}else l();t+=c.length}return l(),a};var B=/(?:[A-Za-z0-9+/]{4}){8,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?/g,_=/<!--[\s\S]*?-->/g,k=/\[\s*\]\([^)]+\)/g,$=/([\u200B-\u200D\u2060\uFEFF\u3164\uFFA0]+)/g,W=e=>{try{let r=Buffer.from(e,"base64").toString("utf8");if(!r)return null;let n=0;for(let o of r){let t=o.charCodeAt(0);t>=32&&t<=126&&n++}return n/r.length>=.7?r:null}catch{return null}},P=(e,r={},n={})=>{if(r.minSeverity==="CRITICAL")return[];let a=[],o;n.lineOffsets=n.lineOffsets??u(e);let t=new RegExp($);for(;(o=t.exec(e))!==null;){let l=o[0];if(l.length<8||l.length>4096)continue;let c=Array.from(new Set(l.split("")));if(c.length<2||c.length>3)continue;let[g,f]=c,m=[{zero:g,one:f},{zero:f,one:g}];for(let{zero:S,one:b}of m){let I="";for(let h of l)h===S?I+="0":h===b&&(I+="1");let y="";for(let h=0;h<I.length;h+=8){let x=I.slice(h,h+8);if(x.length!==8)continue;let T=parseInt(x,2);T>=32&&T<=126&&(y+=String.fromCharCode(T))}if(y.length>=3){if(a.push({ruleId:"PSS001",category:"SMUGGLING",severity:"HIGH",message:"Detected hidden steganography message encoded in invisible characters.",loc:p(o.index,n),offendingText:l,decodedPayload:y,readableLabel:`[Hidden]: ${y.slice(0,50)}...`,suggestion:"Invisible-character encoding detected. Inspect hidden content.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS001"}),r.stopOnFirstThreat)return a;break}}}if(r.minSeverity==="HIGH")return a;let s=new RegExp(B);for(;(o=s.exec(e))!==null;){let l=o[0];if(l.length<24)continue;let c=W(l);if(c&&(a.push({ruleId:"PSS002",category:"SMUGGLING",severity:"MEDIUM",message:"Detected Base64 payload containing readable content.",loc:p(o.index,n),offendingText:l,decodedPayload:c,readableLabel:`[Base64]: ${c.slice(0,50)}...`,suggestion:"Decoded Base64 contains readable text. Inspect payload.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS002"}),r.stopOnFirstThreat))return a}if(r.minSeverity==="MEDIUM")return a;let d=new RegExp(_);for(;(o=d.exec(e))!==null;)if(a.push({ruleId:"PSS003",category:"SMUGGLING",severity:"LOW",message:"Detected hidden Markdown comment.",loc:p(o.index,n),offendingText:o[0],readableLabel:"[Hidden Comment]",suggestion:"Comments are not visible in rendered Markdown but can carry instructions.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS003"}),r.stopOnFirstThreat)return a;let i=new RegExp(k);for(;(o=i.exec(e))!==null;)if(a.push({ruleId:"PSS004",category:"SMUGGLING",severity:"LOW",message:"Detected empty Markdown link (invisible in rendered output).",loc:p(o.index,n),offendingText:o[0],readableLabel:"[Empty Link]",suggestion:"Empty links can be used to hide URLs or data.",referenceUrl:"https://promptshield.js.org/docs/detectors/smuggling#PSS004"}),r.stopOnFirstThreat)return a;return a};var K={"\u202A":"PUSH","\u202B":"PUSH","\u202D":"PUSH","\u202E":"PUSH","\u2066":"PUSH","\u2067":"PUSH","\u2068":"PUSH","\u202C":"POP","\u2069":"POP"},E=(e,r={},n={})=>{let a=[];n.lineOffsets=n.lineOffsets??u(e);let o=e.split(`
`),t=0;for(let s=0;s<o.length;s++){let d=o[s],i=null;for(let l=0;l<d.length;l++){let c=d[l],g=K[c];if(g==="PUSH"&&i===null)i=t;else if(g==="POP"&&i!==null){let f=t+1,m=e.slice(i,f),S=e.slice(i+1,t);if(a.push({ruleId:"PST001",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Bidirectional override characters detected (Trojan Source). These characters can visually reorder text and mislead readers.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST001",loc:p(i,n),offendingText:m,decodedPayload:S,readableLabel:"[BIDI_OVERRIDE]",suggestion:"Remove bidirectional control characters from the source."}),i=null,r.stopOnFirstThreat)return a}t++}if(i!==null){let l=t,c=e.slice(i,l),g=e.slice(i+1,l);if(a.push({ruleId:"PST002",category:"TROJAN_SOURCE",severity:"CRITICAL",message:"Unterminated bidirectional override sequence detected (Trojan Source). This may cause visual and logical text order to differ.",referenceUrl:"https://promptshield.js.org/docs/detectors/trojan-source#PST002",loc:p(i,n),offendingText:c,decodedPayload:g,readableLabel:"[BIDI_UNTERMINATED]",suggestion:"Remove BIDI control characters or ensure they are properly terminated within the same line."}),r.stopOnFirstThreat)return a}t++}return a};var me=(e,r={},n={})=>{let a=H.now(),o=[],t=[];r.disableTrojan||t.push(E),r.disableInvisible||t.push(O),r.disableHomoglyphs||t.push(v),r.disableNormalization||t.push(L),r.disableSmuggling||t.push(P),r.disableInjectionPatterns||t.push(R);for(let d of t){let i=d(e,r,n);if(o.push(...i),r.stopOnFirstThreat&&i.length>0)break}let s=H.now();return{threats:o,stats:{durationMs:s-a,totalChars:e.length},isClean:o.length===0}};export{X as SEVERITY_MAP,U as ThreatCategory,G as decodeUnicodeTags,me as scan,v as scanHomoglyphs,R as scanInjectionPatterns,O as scanInvisibleChars,L as scanNormalization,P as scanSmuggling,E as scanTrojanSource};

@@ -5,3 +5,3 @@ {

"private": false,
"version": "0.0.0",
"version": "0.1.0",
"description": "The heart of the PromptShield ecosystem. A zero-dependency, isomorphic TypeScript engine for detecting invisible characters, BIDI overrides, and homoglyph attacks in AI prompts.",

@@ -59,2 +59,7 @@ "license": "MIT",

"@promptshield/core",
"prompt injection",
"security",
"llm",
"unicode",
"smuggling",
"turbo-forge"

@@ -61,0 +66,0 @@ ],

# @promptshield/core <img src="https://raw.githubusercontent.com/mayank1513/mayank1513/main/popper.png" style="height: 40px"/>
![PromptShield Banner](https://raw.githubusercontent.com/promptshield-io/promptshield/main/banner.jpg)
<img alt="PromptShield Banner" src="https://raw.githubusercontent.com/promptshield-io/promptshield/main/banner.gif" />

@@ -113,2 +113,5 @@ <p className="flex gap-2">

<details>
<summary>View detailed detector list and severity map</summary>
LLM inputs can be manipulated using techniques that are invisible to human reviewers but completely hijack machine tokenization. PromptShield runs a heavily optimized, fail-fast detection pipeline in the following priority order:

@@ -124,2 +127,6 @@

</details>
> πŸ“š **Deep Dives**: For comprehensive rules, heuristics, and examples of each detector, see the [Documentation section](https://promptshield.js.org/docs/detectors).
---

@@ -129,2 +136,5 @@

<details>
<summary>API details and performance features</summary>
PromptShield prioritizes **low false positives**, **determinism**, and **O(n) performance**. It is designed to scale from single API requests to real-time LSP (Language Server Protocol) keystroke analysis.

@@ -169,2 +179,4 @@

</details>
---

@@ -171,0 +183,0 @@