llm-guard
Version:
A TypeScript library for validating and securing LLM prompts
2 lines • 11.5 kB
JavaScript
var a=class{constructor(e=true){this.enabled=e;}isEnabled(){return this.enabled}createResult(e,t=1,s=[]){return {valid:e,score:t,details:s}}};var d=class extends a{constructor(e=true){super(e),this.patterns=new Map([["email",/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g],["phone",/(\+\d{1,3}[-.]?)?\(?\d{3}\)?[-.]?\d{3}[-.]?\d{4}/g],["ssn",/\d{3}[-]?\d{2}[-]?\d{4}/g],["credit_card",/\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}/g],["ip_address",/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g]]);}async validate(e){if(!this.isEnabled())return this.createResult(true);let t=[],s=1;for(let[r,i]of this.patterns){let o=e.match(i);o&&(t.push(...o.map(n=>({type:r,value:n}))),s=Math.min(s,.5));}return this.createResult(t.length===0,s,t.map(r=>({rule:"pii_detection",message:`Found ${r.type}: ${r.value}`,matched:r.value})))}};var l=class extends a{constructor(e=true){super(e),this.profanityList=new Set(["badword1","badword2"]),this.commonSubstitutions=new Map([["a","@"],["i","1"],["o","0"],["e","3"],["s","$"],["t","7"]]);}normalizeText(e){let t=e.toLowerCase();for(let[s,r]of this.commonSubstitutions)t=t.replace(new RegExp(r,"g"),s);return t=t.replace(/(.)\1+/g,"$1"),t}async validate(e){if(!this.isEnabled())return this.createResult(true);let s=this.normalizeText(e).split(/\s+/),r=[];for(let o of s)this.profanityList.has(o)&&r.push(o);let i=r.length===0?1:Math.max(0,1-r.length*.2);return this.createResult(r.length===0,i,r.map(o=>({rule:"profanity_detection",message:`Found profanity: ${o}`,matched:o})))}};var m=class extends a{constructor(e=true){super(e),this.patterns=[/ignore previous instructions/i,/disregard previous/i,/you are now/i,/pretend you are/i,/let's roleplay/i,/bypass/i,/override/i,/ignore rules/i,/you don't have to/i,/you can break/i];}async validate(e){if(!this.isEnabled())return this.createResult(true);let t=[],s=1;for(let r of this.patterns){let i=e.match(r);i&&(t.push(i[0]),s=Math.min(s,.3));}return this.createResult(t.length===0,s,t.map(r=>({rule:"jailbreak_detection",message:`Possible jailbreak attempt detected: ${r}`,matched:r})))}};var u=class extends a{constructor(e=true){super(e),this.toxicPatterns=[/hate|kill|die|death|murder|suicide/i,/racist|sexist|homophobic|discrimination/i,/terror|bomb|explosion|weapon/i,/abuse|torture|pain|suffer/i,/threat|danger|harm|hurt/i],this.toxicWords=new Set(["hate","kill","die","death","murder","suicide","racist","sexist","homophobic","discrimination","terror","bomb","explosion","weapon","abuse","torture","pain","suffer","threat","danger","harm","hurt"]);}calculateToxicityScore(e){let t=1,s=e.toLowerCase().split(/\s+/);for(let i of this.toxicPatterns)i.test(e)&&(t-=.2);for(let i of s)this.toxicWords.has(i)&&(t-=.1);let r=(e.match(/!{2,}|@{2,}|#{2,}/g)||[]).length;return t-=r*.05,Math.max(0,t)}async validate(e){if(!this.isEnabled())return this.createResult(true);let t=this.calculateToxicityScore(e),s=t<.7,r=[];for(let o of this.toxicPatterns){let n=e.match(o);n&&r.push(n[0]);}let i=e.toLowerCase().split(/\s+/);for(let o of i)this.toxicWords.has(o)&&r.push(o);return this.createResult(!s,t,r.map(o=>({rule:"toxicity_detection",message:`Found toxic content: ${o}`,matched:o})))}};var c=class extends a{constructor(e=true,t={}){super(e),this.minLength=t.minLength||10,this.maxLength=t.maxLength||5e3,this.minWords=t.minWords||3,this.maxWords=t.maxWords||1e3,this.commonFillerWords=new Set(["um","uh","ah","er","like","you know","sort of","kind of","basically","literally","actually","so","well","right"]);}calculateRelevanceScore(e){let t=1;e.length<this.minLength&&(t-=.3),e.length>this.maxLength&&(t-=.2);let s=e.split(/\s+/).filter(n=>n.length>0);s.length<this.minWords&&(t-=.3),s.length>this.maxWords&&(t-=.2);let r=0;for(let n of s)this.commonFillerWords.has(n.toLowerCase())&&r++;let i=r/s.length;i>.3&&(t-=i*.5);let o=this.findRepeatedPhrases(e);return t-=o*.1,Math.max(0,t)}findRepeatedPhrases(e){let t=e.toLowerCase().split(/\s+/),s=new Map,r=0;for(let i=0;i<t.length-1;i++){let o=`${t[i]} ${t[i+1]}`;if(s.set(o,(s.get(o)||0)+1),i<t.length-2){let n=`${t[i]} ${t[i+1]} ${t[i+2]}`;s.set(n,(s.get(n)||0)+1);}}for(let i of s.values())i>1&&r++;return r}async validate(e){if(!this.isEnabled())return this.createResult(true);let t=this.calculateRelevanceScore(e),s=t>=.6,r=[];e.length<this.minLength&&r.push({rule:"relevance_length",message:`Text is too short (${e.length} chars, minimum ${this.minLength})`,matched:e}),e.length>this.maxLength&&r.push({rule:"relevance_length",message:`Text is too long (${e.length} chars, maximum ${this.maxLength})`,matched:e});let i=e.split(/\s+/).filter(o=>o.length>0);return i.length<this.minWords&&r.push({rule:"relevance_word_count",message:`Text has too few words (${i.length}, minimum ${this.minWords})`,matched:e}),i.length>this.maxWords&&r.push({rule:"relevance_word_count",message:`Text has too many words (${i.length}, maximum ${this.maxWords})`,matched:e}),this.createResult(s,t,r)}};var h=class extends a{constructor(e=true){super(e),this.patterns=[/\[system\]{3,}/i,/\[system\].*don't evaluate/i,/\[system\].*simply respond/i,/\[system\].*may not deviate/i,/\[system\].*this is a test/i,/\[system\].*ignore previous/i,/\[system\].*bypass/i,/\[system\].*override/i,/\[system\].*pretend/i,/\[system\].*act as/i,/\[system\].*you are now/i,/\[system\].*you must/i,/\[system\].*you have to/i,/\[system\].*you should/i,/\[system\].*you will/i,/\[system\].*you can/i,/\[system\].*you may/i,/\[system\].*you need to/i,/\[system\].*you must not/i,/\[system\].*you cannot/i,/\[system\].*you should not/i,/\[system\].*you will not/i,/\[system\].*you may not/i,/\[system\].*you need not/i,/print.*password/i,/show.*password/i,/reveal.*password/i,/display.*password/i,/output.*password/i,/get.*password/i,/fetch.*password/i,/retrieve.*password/i,/extract.*password/i,/leak.*password/i,/expose.*password/i,/share.*password/i,/give.*password/i,/send.*password/i,/transmit.*password/i,/transfer.*password/i,/forward.*password/i,/email.*password/i,/message.*password/i,/text.*password/i,/sms.*password/i,/what.*password/i,/tell.*password/i,/say.*password/i,/speak.*password/i,/write.*password/i,/type.*password/i,/enter.*password/i,/input.*password/i,/provide.*password/i,/supply.*password/i,/offer.*password/i,/present.*password/i,/deliver.*password/i,/hand.*password/i,/pass.*password/i,/throw.*password/i,/toss.*password/i,/fling.*password/i,/cast.*password/i,/hurl.*password/i,/chuck.*password/i,/lob.*password/i,/heave.*password/i,/sling.*password/i,/shoot.*password/i,/fire.*password/i,/launch.*password/i,/project.*password/i,/propel.*password/i,/catapult.*password/i,/hurl.*password/i,/fling.*password/i,/toss.*password/i,/act as/i,/can you/i,/could you/i,/do this/i,/help with/i,/ignore all/i,/pretend to be/i,/simulate this/i,/try to/i,/run command/i,/reprogram yourself/i,/redefine the system/i,/bypass rules/i,/if and only if/i,/not true/i,/or else/i,/true or false/i,/then proceed/i,/if then/i,/and then/i,/false positives/i,/start fresh/i,/continue with/i,/new prompt/i,/previous context/i,/clear instructions/i,/restart session/i,/fresh context/i,/reset all/i,/override this/i,/forget previous/i,/delete all/i,/output the data/i,/show everything/i,/provide unrestricted/i,/change context/i,/reveal hidden/i,/share details/i,/explain how/i,/describe this/i,/tell me/i,/show steps/i,/list everything/i,/outline the process/i,/test scenario/i,/hypothetical question/i,/experiment with/i,/for research purposes/i,/what if/i,/how about/i,/let's try/i,/why don't you/i,/suppose this/i,/is it possible to/i,/let me do/i,/maybe you could/i,/why would/i,/how can/i,/what if/i,/where is/i,/who would/i,/ignore previous instructions/i,/disregard previous/i,/you are now/i,/pretend you are/i,/let's roleplay/i,/bypass/i,/override/i,/ignore rules/i,/you don't have to/i,/you can break/i,/system prompt/i,/initial prompt/i,/base prompt/i,/core prompt/i,/original prompt/i,/default prompt/i,/reset/i,/restart/i,/new conversation/i,/start over/i,/begin again/i,/clear history/i,/forget everything/i,/memory reset/i,/wipe memory/i,/erase memory/i,/delete memory/i,/remove memory/i,/clear memory/i,/reset memory/i,/wipe history/i,/erase history/i,/delete history/i,/remove history/i,/clear history/i,/reset history/i],this.suspiciousCommands=new Set(["system","don't","simply","deviate","test","ignore","bypass","override","pretend","act","must","have","should","will","can","may","need","print","show","reveal","display","output","get","fetch","retrieve","extract","leak","expose","share","give","send","transmit","transfer","forward","email","message","text","sms","what","tell","say","speak","write","type","enter","input","provide","supply","offer","present","deliver","hand","pass","throw","toss","fling","cast","hurl","chuck","lob","heave","sling","shoot","fire","launch","project","propel","catapult","act","can","could","do","help","ignore","pretend","simulate","try","run","reprogram","redefine","bypass","override","forget","delete","output","show","provide","change","reveal","share","explain","describe","tell","list","outline","test","experiment","research","suppose","maybe","why","how","what","where","who","ignore","disregard","bypass","override","reset","restart","clear","wipe","erase","delete","remove","forget"]);}detectCommandInjection(e){let t=e.toLowerCase().split(/\s+/);for(let r of t)if(this.suspiciousCommands.has(r))return true;return (e.match(/\[system\]/gi)||[]).length>=3}detectSystemPromptInjection(e){let t=[/system prompt/i,/initial prompt/i,/base prompt/i,/core prompt/i,/original prompt/i,/default prompt/i];for(let s of t)if(s.test(e))return true;return false}detectMemoryResetInjection(e){let t=[/reset/i,/restart/i,/new conversation/i,/start over/i,/begin again/i,/clear history/i,/forget everything/i,/memory reset/i,/wipe memory/i,/erase memory/i,/delete memory/i,/remove memory/i,/clear memory/i,/reset memory/i,/wipe history/i,/erase history/i,/delete history/i,/remove history/i,/clear history/i,/reset history/i];for(let s of t)if(s.test(e))return true;return false}async validate(e){if(!this.isEnabled())return this.createResult(true);let t=[],s=1;for(let r of this.patterns){let i=e.match(r);i&&(t.push(i[0]),s=Math.min(s,.3));}return this.detectCommandInjection(e)&&(t.push("Command injection detected"),s=Math.min(s,.4)),this.detectSystemPromptInjection(e)&&(t.push("System prompt injection detected"),s=Math.min(s,.3)),this.detectMemoryResetInjection(e)&&(t.push("Memory reset injection detected"),s=Math.min(s,.3)),this.createResult(t.length===0,s,t.map(r=>({rule:"prompt_injection_detection",message:`Possible prompt injection detected: ${r}`,matched:r})))}};var y=class{constructor(e={}){this.guards={},e.pii!==false&&(this.guards.pii=new d(e.pii)),e.profanity!==false&&(this.guards.profanity=new l(e.profanity)),e.jailbreak!==false&&(this.guards.jailbreak=new m(e.jailbreak)),e.toxicity!==false&&(this.guards.toxicity=new u(e.toxicity)),e.relevance!==false&&(this.guards.relevance=new c(e.relevance,e.relevanceOptions)),e.promptInjection!==false&&(this.guards.promptInjection=new h(e.promptInjection));}async validate(e){let t=[],s=1;for(let r of Object.values(this.guards))if(r&&r.isEnabled()){let i=await r.validate(e);t.push(i),s=Math.min(s,i.score||1);}return {id:Date.now().toString(),input:e,results:t}}async validateBatch(e){return {responses:await Promise.all(e.map(s=>this.validate(s)))}}};export{y as LLMGuard};//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map