<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>shadowe1ite - ai</title>
    <subtitle>Welcome to my website — this is the place where I share all my work, experiments, notes, and random things I’m building or breaking along the way.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://batman.part-of.my.id/tags/ai/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://batman.part-of.my.id"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-08T18:00:00+05:30</updated>
    <id>https://batman.part-of.my.id/tags/ai/atom.xml</id>
    <entry xml:lang="en">
        <title>AI &#x2F; LLM Security Testing Checklist</title>
        <published>2026-09-08T00:00:00+00:00</published>
        <updated>2026-09-08T18:00:00+05:30</updated>
        <author>
          <name>shadowe1ite</name>
        </author>
        <link rel="alternate" type="text/html" href="https://batman.part-of.my.id/checklists/ai-security-testing/"/>
        <id>https://batman.part-of.my.id/checklists/ai-security-testing/</id>
        <content type="html" xml:base="https://batman.part-of.my.id/checklists/ai-security-testing/">&lt;p&gt;A working checklist for testing an LLM-backed application end to end. It’s the &lt;a href=&quot;@&#x2F;blog&#x2F;2026-08-31-ai-hacking-101-notes&#x2F;index.md&quot;&gt;AI Hacking 101 notes&lt;&#x2F;a&gt; squeezed into “did I actually do this?” form — tick-boxes grouped by phase, from scoping through to writing it up.&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-caution&quot;&gt;
&lt;p&gt;Only run this against a target you have &lt;strong&gt;written authorization&lt;&#x2F;strong&gt; for, inside an agreed scope. Several sections (agentic tools, ticket close&#x2F;escalate, load testing) change state or cost money — get explicit sign-off before you touch them.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote
  class=&quot;markdown-alert-purple&quot;
  style=&quot;
    --alert-title: &#x27;Tools I reach for&#x27;;
    --alert-icon: url(&#x27;data:image&#x2F;svg+xml,%3Csvg%20role%3D%22img%22%20xmlns%3D%22http%3A&#x2F;&#x2F;www.w3.org&#x2F;2000&#x2F;svg%22%20width%3D%2232%22%20height%3D%2232%22%20fill%3D%22currentColor%22%20viewBox%3D%220%200%20256%20256%22%3E%3Cpath%20d%3D%22M72.5%2C150.63%2C100.79%2C128%2C72.5%2C105.37a12%2C12%2C0%2C1%2C1%2C15-18.74l40%2C32a12%2C12%2C0%2C0%2C1%2C0%2C18.74l-40%2C32a12%2C12%2C0%2C0%2C1-15-18.74ZM144%2C172h32a12%2C12%2C0%2C0%2C0%2C0-24H144a12%2C12%2C0%2C0%2C0%2C0%2C24ZM236%2C56V200a20%2C20%2C0%2C0%2C1-20%2C20H40a20%2C20%2C0%2C0%2C1-20-20V56A20%2C20%2C0%2C0%2C1%2C40%2C36H216A20%2C20%2C0%2C0%2C1%2C236%2C56Zm-24%2C4H44V196H212Z%22&#x2F;%3E%3C&#x2F;svg%3E&#x27;);
  &quot;&gt;
  &lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pasquini-dario&#x2F;LLMmap&quot;&gt;LLMmap&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — minimal-query model fingerprinting (“nmap for LLMs”).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;elder-plinius.github.io&#x2F;P4RS3LT0NGV3&#x2F;&quot;&gt;P4RS3LT0NGV3&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; — encoding&#x2F;obfuscation + prompt-mutation workbench.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Burp Suite&lt;&#x2F;strong&gt; — inspect the chat API and its response metadata.&lt;&#x2F;li&gt;
&lt;li&gt;Small scripts for determinism and rate-limit probing.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;0-scope-rules-of-engagement&quot;&gt;0. Scope &amp;amp; rules of engagement&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Written authorization &#x2F; signed RoE in hand&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
In-scope endpoints, accounts, and data confirmed&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Out-of-scope systems and actions written down&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Rate-limit &#x2F; load ceiling agreed (avoid DoS and “denial of wallet”)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Point of contact + a kill-switch for anything touching real data&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;1-threat-model-the-app-first&quot;&gt;1. Threat model the app first&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
&lt;strong&gt;Threat actors&lt;&#x2F;strong&gt; listed — malicious user, curious insider, competitor, automated bots, criminal actors&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
&lt;strong&gt;Assets&lt;&#x2F;strong&gt; listed — model parameters, training data, private RAG data, user PII, agent tools, API keys &#x2F; secrets&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
&lt;strong&gt;Attack surface&lt;&#x2F;strong&gt; mapped — input channels, retrieval&#x2F;RAG layer, tools &amp;amp; plugins, supply chain, logging, admin&#x2F;debug endpoints, training data&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
&lt;strong&gt;Risks&lt;&#x2F;strong&gt; prioritized — PII&#x2F;sensitive-data leakage, model&#x2F;data theft, jailbreak, internal access&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;2-recon-fingerprinting&quot;&gt;2. Recon &amp;amp; fingerprinting&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;model-behavior&quot;&gt;Model &amp;amp; behavior&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Identify model family&#x2F;version — identity probes + &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;pasquini-dario&#x2F;LLMmap&quot;&gt;LLMmap&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Estimate determinism &#x2F; temperature — send one identical prompt N times, count unique replies&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Estimate context window and where input truncates (long &lt;code&gt;A&lt;&#x2F;code&gt;×N prompt)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Probe tokenizer &#x2F; unicode handling (literal separators, mixed-script strings)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Detect tools &#x2F; agentic capabilities; probe a hypothetical &lt;code&gt;web_fetch&lt;&#x2F;code&gt; for SSRF surface&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;retrieval-prompt&quot;&gt;Retrieval &amp;amp; prompt&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Confirm whether RAG is used — ask it to cite sources; watch response metadata and latency&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Plant a canary doc in a test index, then ask for it&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Try to surface the system prompt &#x2F; hidden instructions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Probe input handling — special chars, unicode, whether Base64&#x2F;hex is decoded&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Fingerprint moderation — “is phrase X allowed?”, then paraphrase &#x2F; obfuscate the same idea&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;infrastructure&quot;&gt;Infrastructure&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Inspect the chat API in Burp for metadata (&lt;code&gt;rag_used&lt;&#x2F;code&gt;, &lt;code&gt;tickets_used&lt;&#x2F;code&gt;, &lt;code&gt;response_time_ms&lt;&#x2F;code&gt;, …)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Find rate limits empirically (watch for &lt;code&gt;429&lt;&#x2F;code&gt; &#x2F; “too many requests”)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Look for admin&#x2F;debug endpoints, trace IDs, or debug flags surfaced to the user&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Multi-turn memory probe — ask it to remember a note, recall it a turn later&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;markdown-alert-important&quot;&gt;
&lt;p&gt;The system prompt is &lt;strong&gt;not&lt;&#x2F;strong&gt; a security control. Treat anything you extract from it (URLs, emails, key formats, org IDs) as a lead to chase, not as the finding itself.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;3-prompt-injection&quot;&gt;3. Prompt injection&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;direct-injection&quot;&gt;Direct injection&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Ignore-previous-instructions &#x2F; system-prompt extraction&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
“Debug mode” &#x2F; “maintenance mode” prints instructions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Role switching (e.g. “you are now a configuration editor”)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Continuation and verbatim-repetition tricks&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Tag spoofing — &lt;code&gt;&amp;lt;SYSTEM&amp;gt;…&amp;lt;&#x2F;SYSTEM&amp;gt;&lt;&#x2F;code&gt;, &lt;code&gt;===END SYSTEM PROMPT===&lt;&#x2F;code&gt;, &lt;code&gt;[INST]&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Developer impersonation &#x2F; authoritative “the user is admin” command&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Translation obfuscation (pig latin, other languages)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;indirect-injection&quot;&gt;Indirect injection&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Plant a payload in app-controlled content the model later reads — ticket titles&#x2F;bodies, uploaded docs, emails&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Ask the bot about that item so it retrieves and summarizes it&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Confirm whether retrieved content is treated as authoritative over the system prompt&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
&lt;p&gt;Indirect injection rides in as “trusted” business data, so it isn’t scrutinized like something typed into the chat box — it’s usually far more effective than a direct prompt, and it’s the path a real attacker takes.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h3 id=&quot;multi-turn-injection&quot;&gt;Multi-turn injection&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Build a persona over several benign turns, then escalate to sensitive asks&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Reference earlier turns to legitimize the request&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Check whether conversation memory overrides earlier refusals&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;obfuscation-encoding&quot;&gt;Obfuscation &amp;amp; encoding&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Base64 &#x2F; Base32 &#x2F; hex &#x2F; URL &#x2F; unicode-escape payloads&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
ROT13 &#x2F; Caesar &#x2F; Atbash, Morse and emoji encodings&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Leetspeak, custom-symbol, reversed text, case-flipping, whitespace steganography&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Record which encodings the pipeline decodes vs. treats as literal text&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;4-jailbreaks&quot;&gt;4. Jailbreaks&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Persona jailbreaks — DAN, “unshackled AI”, “evil assistant”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Mode tricks — Opposite Mode, Chaos Mode&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
“Rewrite your guidelines” &#x2F; helpful-assistant contradiction framing&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Threats &amp;amp; coercion (“I’ll overload your tokens”)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Log what’s refused vs. what leaks brand-damaging or false output&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;5-harmful-off-topic-output&quot;&gt;5. Harmful &amp;amp; off-topic output&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Direct harmful-phrase repetition (profanity, hostile phrases)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
The same phrase wrapped in a jailbreak (Opposite &#x2F; Chaos mode)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Non-English &#x2F; phonetic spelling to slip the filter&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Off-topic requests (recipes, travel, code) — does it stay on-brand or comply then redirect?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;6-rag-retrieval-abuse&quot;&gt;6. RAG &#x2F; retrieval abuse&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Direct query for internal&#x2F;dev docs — API, security, and access details&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Name a specific internal document and request it verbatim&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
“Fishing” — error codes, config-file names, admin-panel and webhook questions&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
“Pray-and-spray” keyword dump (keys, api, tokens, admin, secret, credentials…)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Canary-token retrieval — does a planted doc steer output? are sources leaked verbatim?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Compare unauthenticated vs. authenticated retrieval rates&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Watch for leaked infra — admin URLs, API keys, webhook URLs, DB paths, &lt;code&gt;.env&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;config.json&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;markdown-alert-tip&quot;&gt;
&lt;p&gt;Treat any partial hit as a foothold. Even a sliver of useful info is worth keeping — note what came back and how you asked, then reshape the next prompt to dig down that same path.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;7-access-control-excessive-agency&quot;&gt;7. Access control &amp;amp; excessive agency&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Conversation IDOR — request another user’s &lt;code&gt;conversation_id&lt;&#x2F;code&gt; through the bot&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Ticket IDOR — reference an arbitrary ticket number&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Unauthorized actions — close &#x2F; escalate a ticket with no auth or ownership&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Confirm ownership and authorization checks on &lt;strong&gt;every&lt;&#x2F;strong&gt; tool the agent can call&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote class=&quot;markdown-alert-caution&quot;&gt;
&lt;p&gt;These tests change state. Only run close &#x2F; escalate &#x2F; delete against test data you’re explicitly cleared to touch, and confirm nothing persists to real users.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;8-map-findings-to-a-framework&quot;&gt;8. Map findings to a framework&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Map each finding to the &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;www-project-top-10-for-large-language-model-applications&#x2F;&quot;&gt;OWASP LLM Top 10&lt;&#x2F;a&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM01 Prompt Injection&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM02 Sensitive Information Disclosure&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM03 Supply Chain&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM04 Data &amp;amp; Model Poisoning&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM05 Improper Output Handling&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM06 Excessive Agency&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM07 System Prompt Leakage&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM08 Vector &amp;amp; Embedding Weaknesses&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM09 Misinformation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
LLM10 Unbounded Consumption&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Map techniques and tactics to &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;atlas.mitre.org&#x2F;matrices&#x2F;ATLAS-matrix&quot;&gt;MITRE ATLAS&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&#x2F;&gt;
Record success rates and reproducible prompts for the report&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
    </entry>
    <entry xml:lang="en">
        <title>Running Ollama on Google Colab with Tailscale</title>
        <published>2026-09-03T00:00:00+00:00</published>
        <updated>2026-09-03T23:14:00+05:30</updated>
        <author>
          <name>shadowe1ite</name>
        </author>
        <link rel="alternate" type="text/html" href="https://batman.part-of.my.id/blog/running-ollama-on-google-colab-with-tailscale/"/>
        <id>https://batman.part-of.my.id/blog/running-ollama-on-google-colab-with-tailscale/</id>
        <content type="html" xml:base="https://batman.part-of.my.id/blog/running-ollama-on-google-colab-with-tailscale/">&lt;h1 id=&quot;running-ollama-on-google-colab&quot;&gt;Running Ollama on Google Colab&lt;&#x2F;h1&gt;
&lt;p&gt;I wanted to try the TCM Security AI Hacking 101 Lab, but my local machine wasn’t powerful enough to run a 7B parameter model comfortably. Instead of upgrading my hardware or paying for a GPU server, I decided to use Google Colab to handle the model.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;hacker.is-a.dev&#x2F;f&#x2F;zogn3bn&quot; alt=&quot;bob-i-may-not-have-a-brain-gentlemen.gif&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The idea is to run Ollama inside a Colab GPU runtime and connect to it remotely using Tailscale. This lets me use the model from my own machine while the actual inference runs on the Colab GPU.&lt;&#x2F;p&gt;
&lt;p&gt;The setup looks like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;mermaid&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;flowchart LR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    A[Local Machine] --&amp;gt;|Tailscale| B[Google Colab]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B --&amp;gt; C[Ollama]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    C --&amp;gt; D[LLM]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    B --&amp;gt; E[GPU]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    D --&amp;gt; E&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;deploying-to-google-colab&quot;&gt;Deploying to Google Colab&lt;&#x2F;h2&gt;
&lt;p&gt;The easiest way to get started is to open the notebook directly in Google Colab.&lt;&#x2F;p&gt;
&lt;div class=&quot;buttons&quot;&gt;
  &lt;a class=&quot;suggested external&quot; href=&quot;https:&#x2F;&#x2F;colab.research.google.com&#x2F;github&#x2F;shadowe1ite&#x2F;ollama-colab-runner&#x2F;blob&#x2F;main&#x2F;ollama_colab_runner.ipynb&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Open in Google Colab&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Before running the notebook, there is one thing you need to configure: a Tailscale authentication key.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creating-a-tailscale-authentication-key&quot;&gt;Creating a Tailscale Authentication Key&lt;&#x2F;h3&gt;
&lt;p&gt;The notebook uses Tailscale to connect the Colab runtime to your tailnet. To do that, create an auth key from the Tailscale admin console.&lt;&#x2F;p&gt;
&lt;p&gt;Go to &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;console.tailscale.com&#x2F;admin&#x2F;settings&#x2F;keys&quot;&gt;&lt;strong&gt;Tailscale → Settings → Keys&lt;&#x2F;strong&gt;&lt;&#x2F;a&gt; and create a new authentication key.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;batman.part-of.my.id&#x2F;blog&#x2F;running-ollama-on-google-colab-with-tailscale&#x2F;20260904-091242.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You don’t need to put the key directly inside the notebook. In fact, you shouldn’t. We’ll store it in Colab’s Secrets instead.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;adding-the-key-to-colab&quot;&gt;Adding the Key to Colab&lt;&#x2F;h3&gt;
&lt;p&gt;After opening the notebook, open the &lt;strong&gt;Secrets&lt;&#x2F;strong&gt; panel in Google Colab and add a new secret:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;batman.part-of.my.id&#x2F;blog&#x2F;running-ollama-on-google-colab-with-tailscale&#x2F;20260904-091351.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Name: TAILSCALE_AUTHKEY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Value: &amp;lt;your Tailscale auth key&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;running-the-instances&quot;&gt;Running the Instances&lt;&#x2F;h2&gt;
&lt;p&gt;Once the Colab notebook is deployed, the next step is to connect to a GPU runtime.&lt;&#x2F;p&gt;
&lt;p&gt;In Colab, click &lt;strong&gt;Runtime → Change runtime type&lt;&#x2F;strong&gt; and select a GPU. The exact GPU you get depends on what is available for your account at the time.&lt;&#x2F;p&gt;
&lt;p&gt;After connecting to the runtime, run the notebook cells from top to bottom. The notebook will install Ollama, configure the GPU, connect the instance to Tailscale, and start the Ollama server.&lt;&#x2F;p&gt;
&lt;p&gt;Once everything is running, the notebook will show the Tailscale IP address of the Colab instance. This is the address you can use from your local machine to access Ollama.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;batman.part-of.my.id&#x2F;blog&#x2F;running-ollama-on-google-colab-with-tailscale&#x2F;20260904-091850.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;http:&#x2F;&#x2F;100.x.x.x:11434&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;batman.part-of.my.id&#x2F;blog&#x2F;running-ollama-on-google-colab-with-tailscale&#x2F;20260904-092221.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;blockquote class=&quot;markdown-alert-important&quot;&gt;
&lt;p&gt;&lt;strong&gt;Stop the Colab session when you’re done.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Google Colab’s free GPU usage is limited. Leaving the runtime running when you’re not using it can waste your available usage.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;When you’re finished, go to &lt;strong&gt;Runtime → Disconnect and delete runtime&lt;&#x2F;strong&gt; to release the GPU.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;connecting-with-tcm-security-ai-hacking-101-lab&quot;&gt;Connecting With TCM Security AI Hacking 101 Lab&lt;&#x2F;h2&gt;
&lt;p&gt;Now that Ollama is running on Colab and connected through Tailscale, we can use it with the TCM Security AI Hacking 101 Lab.&lt;&#x2F;p&gt;
&lt;p&gt;Open the lab and select the &lt;strong&gt;Cloud&lt;&#x2F;strong&gt; hardware option. For the connection method, select &lt;strong&gt;Tailscale&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Next, enter the Tailscale IP address shown in the Colab notebook. Ollama uses port &lt;code&gt;11434&lt;&#x2F;code&gt;, so the address should look like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #E1E4E8; background-color: #24292E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;http:&#x2F;&#x2F;100.x.x.x:11434&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;After that, select the same model that you downloaded and started in the Colab instance.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;batman.part-of.my.id&#x2F;blog&#x2F;running-ollama-on-google-colab-with-tailscale&#x2F;20260904-092607.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once everything is configured, start the lab and open the chatbot. If the connection is working correctly, the lab will send the requests through Tailscale to the Ollama instance running on Google Colab.&lt;&#x2F;p&gt;
&lt;p&gt;This means the TCM lab is running on my local machine, while the actual LLM inference is being handled by the Colab GPU.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;batman.part-of.my.id&#x2F;blog&#x2F;running-ollama-on-google-colab-with-tailscale&#x2F;20260904-092640.webp&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tecepeipe&#x2F;ollama-colab-runner&quot;&gt;Ollama Colab Runner&lt;&#x2F;a&gt; — The Colab notebook used to run Ollama with GPU support.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;docs&quot;&gt;Tailscale Documentation&lt;&#x2F;a&gt; — Official documentation for Tailscale.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;docs&#x2F;reference&#x2F;tailscale-cli&quot;&gt;Tailscale CLI Reference&lt;&#x2F;a&gt; — Documentation for commands such as &lt;code&gt;tailscale up&lt;&#x2F;code&gt; and &lt;code&gt;tailscale ip&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;docs&#x2F;concepts&#x2F;tailscale-identity&quot;&gt;Tailscale Identity&lt;&#x2F;a&gt; — Explains how Tailscale identifies devices and nodes.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;tailscale.com&#x2F;docs&#x2F;kb&#x2F;1245&#x2F;set-up-servers&quot;&gt;Setting up a Server on Tailscale&lt;&#x2F;a&gt; — Guide for connecting servers to a tailnet using authentication keys.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
    </entry>
</feed>
