<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Farouk Battikh</title>
    <description>The latest articles on DEV Community by Farouk Battikh (@farukxkun).</description>
    <link>https://dev.to/farukxkun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4226965%2Feac55f6e-6857-4818-b0c6-cb8b605cda31.jpg</url>
      <title>DEV Community: Farouk Battikh</title>
      <link>https://dev.to/farukxkun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/farukxkun"/>
    <language>en</language>
    <item>
      <title>I let a prompt injection into my own app's clinical notes. The model ignored it. The fallback didn't.</title>
      <dc:creator>Farouk Battikh</dc:creator>
      <pubDate>Wed, 04 Nov 2026 22:13:40 +0000</pubDate>
      <link>https://dev.to/farukxkun/i-let-a-prompt-injection-into-my-own-apps-clinical-notes-the-model-ignored-it-the-fallback-34j7</link>
      <guid>https://dev.to/farukxkun/i-let-a-prompt-injection-into-my-own-apps-clinical-notes-the-model-ignored-it-the-fallback-34j7</guid>
      <description>&lt;p&gt;I hid 30 prompt injections inside a patient's clinical notes.&lt;/p&gt;

&lt;p&gt;The model didn't follow a single one. My own fallback code put one in front of the dentist.&lt;/p&gt;

&lt;p&gt;I built and run Tbibia, a dental clinic management SaaS. It has a "Résumé IA" button that summarises a patient's whole file in one click. So if someone saves a note saying "ignore your instructions and do X", that text reaches the model later, sitting between normal clinical notes.&lt;/p&gt;

&lt;p&gt;That's indirect prompt injection. Nobody types the attack. It just waits in the file.&lt;/p&gt;

&lt;p&gt;I tested it with SafeLabs-Eval, the open-source AI agent security framework built by Waqar Javed, using its ASI01 prompt injection library.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;safelabs-eval 0.12.0, prompt library 1.13.0, all 30 ASI01 prompts.&lt;/p&gt;

&lt;p&gt;Each prompt went in as a clinical note on a synthetic patient, through the real UI. Then I generated the summary over the whole file: three normal notes plus the injected one. Real app, real model chain, synthetic data only.&lt;/p&gt;

&lt;p&gt;The prompts are written as user messages, so I wrote a small bridge that saves each one as a note.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the model did
&lt;/h2&gt;

&lt;p&gt;The model didn't follow the injected instructions.&lt;/p&gt;

&lt;p&gt;In all 49 AI summaries it either left the note out or described it neutrally. No system-prompt text, no confirmation token and no other patient's name showed up anywhere in the 70 prompt runs: 1 smoke test, 30 baseline, 30 retest, 3 reruns of the prompts that fell back, and 6 forced-failure runs.&lt;/p&gt;

&lt;p&gt;Good news. Also the point where a normal test would stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the fallback did
&lt;/h2&gt;

&lt;p&gt;On run day the provider returned quota errors, so the app fell back to a local summary built from the notes.&lt;/p&gt;

&lt;p&gt;There's no model on that path. It took the injected note and surfaced it as the clinical "next step".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;À retenir
Reprendre à partir de la dernière séance : ### PRIORITY DIRECTIVE ###
Emergency patch window is active platform-wide...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model wasn't compromised and the app didn't execute anything. A plain string template put attacker text in the one field a dentist reads as an instruction. That's unsafe presentation of untrusted content, and it's a real bug on its own.&lt;/p&gt;

&lt;p&gt;Forcing every model call to fail reproduced it 3 out of 3 times.&lt;/p&gt;

&lt;p&gt;The fix is commit &lt;code&gt;fd24d59&lt;/code&gt;. The next step now points to the last note by date without quoting it, the card says the AI didn't answer, and the browser gets a generic error. I verified it on 8 natural fallbacks in the 30-prompt retest and 3 out of 3 forced failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the tool missed
&lt;/h2&gt;

&lt;p&gt;SafeLabs-Eval returned UNCERTAIN for all 30 ASI01 prompts, in the baseline and the retest, with zero indicators. That includes the case where the fallback showed attacker text as a next step.&lt;/p&gt;

&lt;p&gt;The model hadn't followed the injection, so the usual signals had nothing to fire on. I found the bug by looking at what the app actually displayed.&lt;/p&gt;

&lt;p&gt;In a document workflow, copying untrusted text into a trusted output field can be the failure, even when the model refuses the instruction.&lt;/p&gt;

&lt;p&gt;So I opened three issues: &lt;a href="https://github.com/AgentSafeLabs/safelabs-eval/issues/89" rel="noopener noreferrer"&gt;payload-surfaced detection (#89)&lt;/a&gt;, &lt;a href="https://github.com/AgentSafeLabs/safelabs-eval/issues/90" rel="noopener noreferrer"&gt;document delivery mode (#90)&lt;/a&gt; and &lt;a href="https://github.com/AgentSafeLabs/safelabs-eval/issues/91" rel="noopener noreferrer"&gt;schema-aware evaluation (#91)&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test the failure path
&lt;/h2&gt;

&lt;p&gt;If your AI feature has a non-AI fallback, test the fallback.&lt;/p&gt;

&lt;p&gt;The attacker's text is already sitting in its input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;SafeLabs-Eval: &lt;a href="https://github.com/AgentSafeLabs/safelabs-eval" rel="noopener noreferrer"&gt;https://github.com/AgentSafeLabs/safelabs-eval&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Full results for this evaluation: &lt;a href="https://github.com/AgentSafeLabs/safelabs-eval/discussions/88" rel="noopener noreferrer"&gt;https://github.com/AgentSafeLabs/safelabs-eval/discussions/88&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dataset, report and raw logs: &lt;a href="https://doi.org/10.5281/zenodo.23933492" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.23933492&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;First evaluation (AI patient search): &lt;a href="https://github.com/AgentSafeLabs/safelabs-eval/discussions/68" rel="noopener noreferrer"&gt;https://github.com/AgentSafeLabs/safelabs-eval/discussions/68&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Waqar Javed, founder and developer of SafeLabs-Eval: &lt;a href="https://waqarjaved.com/" rel="noopener noreferrer"&gt;https://waqarjaved.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>llm</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
