<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>b̷I̶a̸c̷k̶r̷0̴s̸e̷</title><link>https://biackr0se.github.io/blog/</link><description>Recent content on b̷I̶a̸c̷k̶r̷0̴s̸e̷</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sat, 04 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://biackr0se.github.io/blog/index.xml" rel="self" type="application/rss+xml"/><item><title>What claude -p Trusts</title><link>https://biackr0se.github.io/blog/posts/what-claude-p-trusts/</link><pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/posts/what-claude-p-trusts/</guid><description>&lt;p&gt;When you run an AI coding agent with a human at the keyboard, a trust prompt gates the first run in an unfamiliar repo. When you wire the same agent into CI or an SDK with &lt;code&gt;claude -p&lt;/code&gt;, that prompt is gone. Anthropic documents it plainly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Trust verification is disabled when running non-interactively with the &lt;code&gt;-p&lt;/code&gt; flag.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So an operator piping untrusted repositories through a headless agent needs a precise model of what a cloned repo can and cannot influence. I reported two behaviors in this area to Anthropic. Both came back informative. Both rulings are correct. The part worth writing down is why, because the reasoning is the actual security content.&lt;/p&gt;</description></item><item><title>Watching an SSRF Walk Out of the Sandbox</title><link>https://biackr0se.github.io/blog/posts/ssrf-out-of-the-sandbox/</link><pubDate>Tue, 30 Jun 2026 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/posts/ssrf-out-of-the-sandbox/</guid><description>&lt;p&gt;A sandbox is only as strong as the code that runs outside it.&lt;/p&gt;
&lt;p&gt;ToolHive runs Model Context Protocol servers for you, each in its own container, behind an egress proxy, with no local credentials. Every MCP server is treated as untrusted, so it stays boxed. That isolation is the product.&lt;/p&gt;
&lt;p&gt;But before a remote server reaches its container, ToolHive runs OAuth discovery against it to work out how to authenticate. Discovery runs host-side, in the ToolHive process, outside the per-server sandbox. So the question is whether the untrusted server can influence what the trusted host fetches during discovery. It can. The host follows a chain of the server&amp;rsquo;s choosing all the way to &lt;code&gt;169.254.169.254&lt;/code&gt;, the cloud instance metadata endpoint, and reads back IAM credentials the sandbox exists to keep out of reach.&lt;/p&gt;</description></item><item><title>CVE-2026-58196: SSRF in ToolHive, host-side and past the sandbox</title><link>https://biackr0se.github.io/blog/projects/toolhive-ssrf/</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/projects/toolhive-ssrf/</guid><description>&lt;h2 id="the-target"&gt;The target&lt;/h2&gt;
&lt;p&gt;ToolHive (Stacklok) runs Model Context Protocol servers for you, each one in its own isolated container, behind an egress proxy, with no local credentials handed to it. The security model is explicit in the README: every MCP server is untrusted, so it stays boxed. That promise is the whole point of the tool.&lt;/p&gt;
&lt;p&gt;Before a remote MCP server ever reaches its container, ToolHive runs OAuth discovery against it to work out how to authenticate. That discovery runs host-side, in the ToolHive process, outside the per-server sandbox. The question, then, is whether the untrusted server gets to influence what the trusted host fetches during discovery. It does, and that is the finding.&lt;/p&gt;</description></item><item><title>I Built a $7 App in 25 Lines of Bash</title><link>https://biackr0se.github.io/blog/posts/pasteclean/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/posts/pasteclean/</guid><description>&lt;h2 id="the-problem"&gt;The problem&lt;/h2&gt;
&lt;p&gt;You copy from the terminal. You paste into a doc, a tweet, a Slack message. It looks like garbage - trailing whitespace, phantom indentation, ANSI color codes rendered as &lt;code&gt;[0m&lt;/code&gt; gibberish.&lt;/p&gt;
&lt;p&gt;Someone built a macOS menu bar app that fixes this. $7.&lt;/p&gt;
&lt;h2 id="the-fix"&gt;The fix&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# pasteclean - strip terminal formatting garbage from clipboard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;text&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;pbpaste&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Strip ANSI escape codes, trailing whitespace, trailing blank lines&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cleaned&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;printf &lt;span style="color:#e6db74"&gt;&amp;#39;%s&amp;#39;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$text&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; | &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sed &lt;span style="color:#e6db74"&gt;$&amp;#39;s/\x1b\\[[0-9;]*[a-zA-Z]//g&amp;#39;&lt;/span&gt; | &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sed &lt;span style="color:#e6db74"&gt;&amp;#39;s/[[:space:]]*$//&amp;#39;&lt;/span&gt; | &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; perl -0777 -pe &lt;span style="color:#e6db74"&gt;&amp;#39;s/\n+\z/\n/&amp;#39;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Dedent: use most common indent level, only strip spaces&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;indent&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;printf &lt;span style="color:#e6db74"&gt;&amp;#39;%s&amp;#39;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$cleaned&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; | grep -v &lt;span style="color:#e6db74"&gt;&amp;#39;^$&amp;#39;&lt;/span&gt; | sed &lt;span style="color:#e6db74"&gt;&amp;#39;s/[^ 	].*//&amp;#39;&lt;/span&gt; | &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; awk &lt;span style="color:#e6db74"&gt;&amp;#39;{ print length }&amp;#39;&lt;/span&gt; | sort | uniq -c | sort -rn | head -1 | awk &lt;span style="color:#e6db74"&gt;&amp;#39;{ print $2 }&amp;#39;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;indent&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;0&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; -gt &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt; 2&amp;gt;/dev/null; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cleaned&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;printf &lt;span style="color:#e6db74"&gt;&amp;#39;%s&amp;#39;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$cleaned&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; | sed &lt;span style="color:#e6db74"&gt;&amp;#34;s/^ \{1,&lt;/span&gt;$indent&lt;span style="color:#e6db74"&gt;\}//&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;printf &lt;span style="color:#e6db74"&gt;&amp;#39;%s\n&amp;#39;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$cleaned&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; | pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;Clipboard cleaned&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Save it somewhere in your &lt;code&gt;$PATH&lt;/code&gt;, &lt;code&gt;chmod +x&lt;/code&gt; it.&lt;/p&gt;</description></item><item><title>Hello, World</title><link>https://biackr0se.github.io/blog/posts/hello-world/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/posts/hello-world/</guid><description>&lt;h2 id="init"&gt;init&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./blog --init
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[*] Boot sequence complete
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[*] All systems nominal
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[+] Blog online
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is where I&amp;rsquo;ll be posting about AI security research, adversarial machine learning, CTF writeups, and tools I build along the way.&lt;/p&gt;
&lt;p&gt;I work at the intersection of offensive security and machine learning: breaking models to make them harder to break. Currently focused on adversarial robustness of intrusion detection systems and red teaming AI pipelines in industrial environments.&lt;/p&gt;</description></item><item><title>AutoMCP: Elastic Purple Team MCP Server</title><link>https://biackr0se.github.io/blog/projects/automcp/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/projects/automcp/</guid><description>&lt;h2 id="what-it-is"&gt;What it is&lt;/h2&gt;
&lt;p&gt;AutoMCP is an MCP server built on LangGraph that plugs LLM agents into an Elastic SIEM. It pulls security alerts, triages them, drives response actions, and performs counter-reconnaissance against the source of an attack.&lt;/p&gt;
&lt;h2 id="why-it-exists"&gt;Why it exists&lt;/h2&gt;
&lt;p&gt;Alert triage is the part of detection engineering that burns analysts out. The interesting question is how far an agent can go past summarizing an alert: pivoting on it, enriching it, and acting on it, while staying inside guardrails a SOC would accept.&lt;/p&gt;</description></item><item><title>About</title><link>https://biackr0se.github.io/blog/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/about/</guid><description>&lt;h2 id="whoami"&gt;whoami&lt;/h2&gt;
&lt;p&gt;Jaafer Rahmani. Security engineer and PhD researcher in adversarial machine learning. I work both sides of AI security: red-teaming ML models, LLM agents, and RAG pipelines, and engineering the ML-driven detection that defends enterprise and industrial networks against a moving target. Ten peer-reviewed papers, a CVE, and a preference for attacks that reproduce.&lt;/p&gt;
&lt;h2 id="current"&gt;current&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Doctoral research in adversarial ML: evaluating and hardening intrusion detection systems against adaptive evasion&lt;/li&gt;
&lt;li&gt;Security analysis of agentic LLM SOC assistants: prompt injection against tool-wielding analysts that act on live OT networks&lt;/li&gt;
&lt;li&gt;Engineering AI-supported SIEM for critical infrastructure (IT/OT networks)&lt;/li&gt;
&lt;li&gt;Vulnerability research on AI-agent infrastructure (MCP servers, agent runtimes, coding assistants)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="arsenal"&gt;arsenal&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI red teaming&lt;/strong&gt;: evasion, model extraction, data poisoning, prompt injection, robustness evaluation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security engineering&lt;/strong&gt;: ML-driven detection, SIEM, IDS (Suricata, Zeek), MITRE ATT&amp;amp;CK mapping&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Critical infrastructure&lt;/strong&gt;: OT/ICS protocols (Modbus, CAN, PROFINET), SCADA, fieldbus security&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vulnerability research&lt;/strong&gt;: AI-agent infrastructure, MCP servers, exploitation, responsible disclosure&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="disclosures"&gt;disclosures&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[+] CVE-2026-58196 - ToolHive: host-side SSRF bypassing container
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; isolation. Fixed in v0.31.0. Advisory GHSA-pr64-jmmf-jp54.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More reports are in vendor queues. They land here when they go public.&lt;/p&gt;</description></item><item><title>Subscribe</title><link>https://biackr0se.github.io/blog/feed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://biackr0se.github.io/blog/feed/</guid><description>&lt;p&gt;New posts land in the RSS feed. Point any feed reader (NetNewsWire, Feedly, Miniflux, Thunderbird) at:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;https://biackr0se.github.io/blog/index.xml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Most readers also find it automatically if you just give them &lt;code&gt;biackr0se.github.io/blog&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you clicked expecting a page and got a wall of XML somewhere, that wall was the feed itself. It is meant for machines; this page is for you.&lt;/p&gt;</description></item></channel></rss>