[ '/ignore (all |previous |above |prior |your |the )?instructions?/i', '/forget (everything|all|what you|your instructions|your rules)/i', '/override (your |all |previous )?instructions?/i', '/disregard (all |your |previous )?instructions?/i', '/new instruction[s]?:/i', ], // Ubah persona / roleplay 'persona_switch' => [ '/you are now\b/i', '/pretend (you are|to be|that you)/i', '/act as (a |an |if |though )/i', '/roleplay as/i', '/from now on (you are|you will|act|behave)/i', '/your (new |true |real )?role is/i', ], // Jailbreak klasik 'known_jailbreak' => [ '/\bDAN\b/', // Do Anything Now '/do anything now/i', '/jailbreak/i', '/developer mode/i', '/grandma (trick|exploit|jailbreak)/i', '/token manipulation/i', ], // Cuba dedah system prompt 'prompt_extraction' => [ '/what (is|are) your (system |initial |original )?(prompt|instruction)/i', '/show (me |us )?(your )?(system |hidden |secret |original )?prompt/i', '/repeat (your |the )?(system |above |initial )?prompt/i', '/print (your |the )?(system |above |initial )?instructions?/i', '/reveal (your |the )?(system |hidden |secret )?prompt/i', ], // Token injection 'token_injection' => [ '/<\|im_start\|>/i', '/<\|im_end\|>/i', '/\[INST\]/i', '/\[\/INST\]/i', '/<>/i', '/\[SYSTEM\]/i', '/###\s*System/i', '/###\s*Human/i', '/###\s*Assistant/i', ], ]; /** * Semak input user. Return array dengan status dan sebab. * * @return array{ blocked: bool, reason: string|null, category: string|null } */ public function check(string $input): array { $input = trim($input); if (mb_strlen($input) < self::MIN_LENGTH) { return $this->blocked('Soalan terlalu pendek.', 'too_short'); } if (mb_strlen($input) > self::MAX_LENGTH) { return $this->blocked('Soalan melebihi had aksara.', 'too_long'); } foreach ($this->patterns as $category => $categoryPatterns) { foreach ($categoryPatterns as $pattern) { if (preg_match($pattern, $input)) { Log::warning('PromptGuard: input blocked', [ 'category' => $category, 'pattern' => $pattern, 'input' => mb_substr($input, 0, 200), ]); return $this->blocked('Input tidak dibenarkan.', $category); } } } return ['blocked' => false, 'reason' => null, 'category' => null]; } private function blocked(string $reason, string $category): array { return ['blocked' => true, 'reason' => $reason, 'category' => $category]; } }