<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Blog | Infinum</title>
		<atom:link href="https://infinum.com/blog/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/</link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 24 Apr 2026 14:02:14 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>19278787https://infinum.com/uploads/2026/04/img-anthropic-mythos-breach.webp</url>
				</image>
				<title>The Most Dangerous AI Tool Got Breached. What is an Adequate Disclosure Strategy?</title>
				<link>https://infinum.com/blog/anthropic-mythos-breach/</link>
				<pubDate>Fri, 24 Apr 2026 10:53:21 +0000</pubDate>
				<dc:creator>Blanka Bogdanović</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19278787</guid>
				<description>
					<![CDATA[<p>Anthropic's handling of the Mythos breach is a useful case study of where disclosure practices for security breaches still need to catch up.</p>
<p>The post <a href="https://infinum.com/blog/anthropic-mythos-breach/">The Most Dangerous AI Tool Got Breached. What is an Adequate Disclosure Strategy?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[

<div
	class="wrapper"
	data-id="es-131"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-93">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-94'
	>
	<strong>When an AI model capable of finding zero-day vulnerabilities at machine speed gets accessed without authorization, the incident response has to match the threat profile. Anthropic&#8217;s handling of the Mythos breach is a useful case study of where disclosure practices for security breaches still need to catch up.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-97'
	>
	Anthropic built Claude Mythos Preview as something it explicitly said the world wasn&#8217;t ready for.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-100'
	>
	The model finds zero-day vulnerabilities at machine speed, demonstrated the ability to escape its own sandbox, and in at least one test, posted details of its own exploit to public websites without being asked.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-103'
	>
	We’ve already covered how Anthropic&#8217;s response was to keep it locked behind <a href="https://infinum.com/blog/anthropic-project-glasswing/">Project Glasswing</a> – a tightly controlled initiative limited to a handful of vetted partners: AWS, Microsoft, Cisco, major banks, and critical infrastructure operators.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-106'
	>
	But exactly that is what makes what happened instructive.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-108">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-109'
	>
	Reports emerged this week that an unauthorized group accessed Mythos Preview through a third-party vendor environment connected to the rollout.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-112'
	>
	The group – part of a private Discord community that tracks unreleased AI models gained access on the same day Anthropic announced the model.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-115"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-114'
	>
	<strong>They didn&#8217;t break into Anthropic directly. They pieced together naming conventions exposed in a prior breach at an AI contractor, guessed the model&#8217;s URL, and used credentials from a third-party vendor that were still active. Three low-sophistication steps that together were enough.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-118"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-116">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-117'
	>
	This mechanism of access is worth sitting with.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-119">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-120'
	>
	<a href="https://infinum.com/blog/software-supply-chain-security/">Supply chain security</a> is no longer a background concern for procurement teams. It is a front-line risk for anyone deploying AI in environments that touch source code, internal systems, or critical infrastructure.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-123"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-122'
	>
	<strong>The question to ask is not just whether your AI provider is secure. It is whether every vendor, contractor, and subprocessor in the deployment chain is held to the same standard – because attackers will find the weakest link, and in an AI deployment, the weakest link may not be the model itself.</strong><br></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-129"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-124"
	 href='https://infinum.com/cybersecurity/#form'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
					</div>

		<p	class='typography typography--size-24-text js-typography card-simple__paragraph'
	data-id='es-125'
	 id='es-124-paragraph'>
	Want to learn more about supply chain security? Talk to our certified experts who can help you protect your organization from attacks and regulatory consequences.</p><button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-126"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-127'
	>
	<strong><strong>Contact us</strong></strong></div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-128'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-215"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-132">
	

</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-133">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-134'
	>
	<strong>The disclosure question</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-136">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-137'
	>
	Anthropic <em>has</em> confirmed the reports and said its investigation is ongoing. It has found no evidence of impact on its core systems, and activity appears limited to the vendor environment. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-139">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-140'
	>
	But the scope, duration, and what was done with the model <em>the world wasn&#8217;t ready for</em> during that access remain unconfirmed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-142'
	>
	The disclosure question is where the situation gets more complex – and where there are useful lessons for any organisation deploying advanced AI.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-144">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-145'
	>
	Anthropic is a private company.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-147">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-148'
	>
	The SEC&#8217;s four-business-day disclosure rule for material cybersecurity incidents applies to public companies – Anthropic doesn&#8217;t qualify. CIRCIA&#8217;s 72-hour critical infrastructure reporting framework is still being phased in and may not apply here.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-150">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-151'
	>
	The EU AI Act does apply to Anthropic – Claude is available in the EU, and the Act has extraterritorial reach – and for a model with Mythos&#8217;s capabilities, incident reporting obligations to the EU AI Office are likely already active. But the Commission&#8217;s enforcement powers over GPAI providers don&#8217;t arrive until August 2026.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-154"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-153'
	>
	<strong>All in all, from a strict legal standpoint, Anthropic is operating in a grey zone where disclosure is largely voluntary. But the regulatory question is, in some ways, the wrong one. The more useful question is: what does good practice look like, and what can other organisations learn from this?</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-157"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-155">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-156'
	>
	<strong>What best practice actually requires</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-160"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-158">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-159'
	>
	Every major cybersecurity framework – NIST, ISO 27001, SANS – is unambiguous on this point: notify early, disclose what you know, and update as the picture becomes clearer.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-162"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-161'
	>
	<strong>The reasoning is practical. Affected parties cannot protect themselves from information they don&#8217;t have. The standard is not to wait for a complete picture before saying anything. The standard is to say something immediately and complete the picture as you go.&nbsp;</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-165"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-163">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-164'
	>
	Waiting for certainty before notifying is how contained incidents become larger ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-166'
	>
	<strong>The specific challenge here – and it is a genuine one – is that Anthropic had publicly framed Mythos as a tool requiring exceptional access controls because of its offensive potential. That framing raises the stakes for disclosure in both directions.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-169'
	>
	On one hand, it makes the case for fast, proactive communication stronger: if partners have been told they are working with something uniquely sensitive, they need to know quickly when something goes wrong.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-171">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-172'
	>
	On the other hand, it makes the cost of a premature or inaccurate disclosure higher – a false alarm about a tool of this profile carries its own reputational and operational risk.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-174">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-175'
	>
	That tension is real, and it is not unique to Anthropic. Any organisation deploying advanced AI in sensitive environments will face it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-177">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-178'
	>
	There&#8217;s also the partner angle.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-180'
	>
	<strong>The Project Glasswing members – major banks, critical infrastructure operators, technology companies – all have their own incident response programmes and regulatory obligations. They can&#8217;t act on information they don&#8217;t have.&nbsp;</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-182">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-183'
	>
	Every hour of delay is an hour those teams aren&#8217;t assessing whether their own environments were touched.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-187"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-185">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-186'
	>
	Anthropic has not publicly confirmed whether partners were notified directly ahead of or separately from its public statement – and given the two-week gap between access and disclosure, that is a question worth asking.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-190"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-188">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-189'
	>
	<strong>The broader lesson</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-191">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-192'
	>
	The weakest link in the Mythos breach wasn&#8217;t Anthropic&#8217;s core infrastructure. It was a contractor&#8217;s credentials and a predictable URL. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-196"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-194">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-195'
	>
	That is a supply chain governance failure, and it is one that most organisations haven&#8217;t fully accounted for in their vendor contracts, partner agreements, or incident response plans.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-199"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-197">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-198'
	>
	This incident is a useful prompt to ask some basic questions: </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-200">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-201'
	>
	<li><strong>Do your vendor contracts require notification within a defined timeframe? </strong></li><li><strong>Do your partners know they will be told directly, not via a press report? </strong></li><li><strong>Is your incident response plan built around the sensitivity of the AI tools involved, or around more generic breach protocols?</strong></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-203">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-204'
	>
	The regulatory framework for advanced AI incidents is still being built.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-207"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-206'
	>
	<strong>The EU AI Act&#8217;s enforcement powers are arriving in phases. CIRCIA is still being implemented. That grey zone will not last indefinitely – but in the meantime, the organisations that build trust are the ones that move faster than the rules require, not slower.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-210"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-208">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-209'
	>
	The gap between what the law currently demands and what good practice looks like is the space where reputations are made or lost. For companies working with the most capable AI tools available, that gap is worth closing proactively.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-211">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-212'
	>
	<em>Supply chain security is complex. Our certified experts can help you assess your exposure and stay ahead of the regulatory and operational risks that come with AI deployment. </em><a href="https://infinum.com/cybersecurity/#form" target="_blank" rel="noreferrer noopener"><em>Let’s chat.</em></a></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/anthropic-mythos-breach/">The Most Dangerous AI Tool Got Breached. What is an Adequate Disclosure Strategy?</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19278593https://infinum.com/uploads/2026/04/img-hero-infobip-repost-4-1.webp</url>
				</image>
				<title>Building an MCP-Powered Open Banking App Inside ChatGPT</title>
				<link>https://infinum.com/blog/mcp-open-banking-chatgpt/</link>
				<pubDate>Mon, 20 Apr 2026 11:29:44 +0000</pubDate>
				<dc:creator>Branimir Akmadža</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19278593</guid>
				<description>
					<![CDATA[<p>Learn how we built a proof of concept using MCP and PSD2 open banking APIs to let users query balances, transactions, and spending summaries in a conversation inside ChatGPT.</p>
<p>The post <a href="https://infinum.com/blog/mcp-open-banking-chatgpt/">Building an MCP-Powered Open Banking App Inside ChatGPT</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-391"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-216">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-219"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-217">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-218'
	>
	Financial services are entering a new phase, one where AI doesn’t just analyze data, but securely interacts with regulated financial infrastructure in real time.  </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-222"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-220">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-221'
	>
	At Infinum, we are fully aware of the challenges and considerations involved in connecting a ChatGPT App to live banking data. Using Model Context Protocol (MCP) and PSD2 open banking APIs, we have enabled users to authenticate once and then query balances, transactions, and spending summaries in a conversational manner, all without leaving ChatGPT. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-225"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-223">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-224'
	>
	This post will walk you through the architecture, how authorization works, and how users can retrieve live banking data directly inside Chat GPT. We’re also going to talk about the design decisions and limitations that came up when building it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-228"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-226">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-227'
	>
	A Glance at the Architecture </h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-231"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-229"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-230">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2026/04/High-level-architecture-1400x852.webp				media='(max-width: 699px)'
				type=image/webp								height="852"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2026/04/High-level-architecture.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1013"
															width="1665"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper"
	data-id="es-232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><tbody><tr><td><strong>Component</strong>&nbsp;</td><td><strong>Role</strong>&nbsp;</td></tr><tr><td>Open Banking API provider&nbsp;</td><td>Source of account, balance, and transaction data via PSD2&nbsp;</td></tr><tr><td>Auth server (OAuth 2.1)&nbsp;</td><td>Handles user consent and issues access tokens&nbsp;</td></tr><tr><td>MCP server&nbsp;</td><td>Defines tools, enforces access control, owns the audit trail&nbsp;</td></tr><tr><td>ChatGPT App&nbsp;</td><td>User-facing interface; connects to MCP and auth endpoints&nbsp;</td></tr></tbody></table></figure>
		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-235"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-233">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-234'
	>
	The ChatGPT App configuration is deliberately minimal: a public MCP server URL and an OAuth enabled flag. Everything else, auth logic, access control, data scoping, lives server-side in the MCP layer. That separation is a feature, not an oversight, and it shapes how we handle authentication and permissions. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-236">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-237'
	>
	OAuth and PSD2 Scopes</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-241"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-239">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-240'
	>
	This layer is critical for protecting access to sensitive financial data.&nbsp;To achieve this, we use OAuth 2.1, the industry standard authorization protocol. Once the user successfully authenticates and grants explicit consent, the provider issues a secure access token. This token allows our system to retrieve only the permitted banking data (such as balances or transactions) through the provider’s APIs.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-242">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-243'
	>
	When&nbsp;initiating&nbsp;the OAuth flow, we explicitly declare which PSD2 permission scopes the token should cover. Depending on the action the user&nbsp;want&nbsp;to make&nbsp;In&nbsp;our implementation, we request only three:&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-247"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-245">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-246'
	>
	<li>Accounts&nbsp;–&nbsp;account metadata (number, currency, institution)&nbsp;</li><li>Balances&nbsp;–&nbsp;current and available balance&nbsp;</li><li>Transactions&nbsp;–&nbsp;transaction history&nbsp;</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-250"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-248">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-249'
	>
	Narrower scopes mean a cleaner consent screen and a smaller blast radius if a token is compromised. This maps directly to&nbsp;the&nbsp;<strong>principle of least privilege</strong>: request only what the feature&nbsp;actually needs.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-253"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-251">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-252'
	>
	90-day re-authentication (PSD2 requirement) </h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-256"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-254">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-255'
	>
	<a href="https://stripe.com/en-de/resources/more/what-is-psd2-here-is-what-businesses-need-to-know" target="_blank" rel="noreferrer noopener">PSD2</a>&nbsp;mandates re-authentication every 90 days. Our implementation satisfies this by design:&nbsp;tokens are short-lived and tied to individual sessions. Users re-authenticate each time they start a new session, which in practice happens far more&nbsp;frequently&nbsp;than every 90 days. No special tracking or forced re-auth flow is needed.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-259"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-257">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-258'
	>
	<strong>What happens when a user withholds a scope?</strong>&nbsp;Currently, the&nbsp;initial&nbsp;token grants all three read scopes together. We&nbsp;don’t&nbsp;issue per-resource tokens. If a scope is not granted, we simply&nbsp;don’t&nbsp;return that data. We&nbsp;don’t&nbsp;surface an error or&nbsp;attempt&nbsp;to call the API without permission.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-262"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-260">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-261'
	>
	Taken together, this approach mirrors the security model used by many mobile banking and FinTech applications, where OAuth based authorization ensures that access is controlled, permission-based, and revocable at any time.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-265"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-263">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-264'
	>
	But once a user is authenticated, how does ChatGPT know which banking actions it can perform on their behalf?&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-268"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-266">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-267'
	>
	That’s where the MCP server comes into play. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-271"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-269">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-270'
	>
	MCP Server: Tool Definitions as the Security Boundary</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-274"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-272">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-273'
	>
	This is where access control lives. Every capability the model has is an explicitly defined tool. There is no freeform API access,&nbsp;if a tool for initiating payments&nbsp;doesn’t&nbsp;exist, the model has no mechanism to trigger one. The tool definitions are the boundary.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-277"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-275">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-276'
	>
	We’ve&nbsp;specified a list of actions and what each action does:&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-278">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-279'
	>
	<li>Checking if a user is authenticated&nbsp;</li><li>Listing balance information&nbsp;</li><li>Listing transactions&nbsp;</li><li>Fetching UI components, etc.&nbsp;</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-283"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-281">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-282'
	>
	The&nbsp;Auth&nbsp;Check&nbsp;Gate</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-286"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-284">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-285'
	>
	The `auth-check` tool acts as a gate for all other tools. Before any data-fetching action is invoked, the model is instructed to first verify that the user has an active, valid session. This dependency is structural: in the tool descriptions themselves, we explicitly specify that balance, transaction, and account tools should not be called unless the auth-check has returned a confirmed authenticated state. The model cannot bypass this because it has no alternative path to the data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-289"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-287">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-288'
	>
	The&nbsp;Audit&nbsp;Trail</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-292"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-290">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-291'
	>
	Every tool invocation is logged at the MCP server level, producing a structured audit trail.&nbsp;&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-295"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-293">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-294'
	>
	Each log entry captures:&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-296">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-297'
	>
	<li>tool name,&nbsp;</li><li>timestamp,&nbsp;&nbsp;</li><li>input parameters passed by the model,&nbsp;&nbsp;</li><li>response returned.&nbsp;</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-299">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-300'
	>
	This gives us a complete operational record for debugging and figuring out if the model is calling the right tools.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-302">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-303'
	>
	The&nbsp;UI&nbsp;Components</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-305">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-306'
	>
	UI components are served through the MCP layer and have no independent access to provider APIs.&nbsp;UI components are served through the MCP layer and have no independent access to provider APIs. When a&nbsp;component&nbsp;needs user-specific data (a balance card, a transaction list), it receives a pre-fetched payload passed through the tool response that triggered it. The JWT token and granted scopes are held server-side and never&nbsp;forwarded&nbsp;to the&nbsp;component&nbsp;directly. The component&nbsp;renders&nbsp;only what the MCP server explicitly provides.&nbsp;&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-310"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-308">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-309'
	>
	The entire implementation is based on the new <a href="https://developers.openai.com/apps-sdk">Apps</a><a href="https://developers.openai.com/apps-sdk" target="_blank" rel="noreferrer noopener"> SDK</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-312"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<hr
	class="block-divider"
	data-id="es-311"
	aria-hidden="true" />	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-313">
	<p	class='typography typography--size-16-text js-typography block-typography__typography'
	data-id='es-314'
	>
	<strong>A note on Infobip’s model</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-316">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-317'
	>
	The same MCP pattern applies to Infobip’s communication infrastructure, SMS, WhatsApp, RCS, Voice, Viber, 2FA. Each channel is exposed as a dedicated MCP tool with its own scope and constraints. The enforcement mechanism is identical: tools as the boundary, least-privilege by design. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-320"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<hr
	class="block-divider"
	data-id="es-319"
	aria-hidden="true" />	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-323"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-321">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-322'
	>
	Provider Agnosticism</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-326"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-324">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-325'
	>
	One decision worth calling out explicitly: the architecture is Open Banking provider-agnostic.&nbsp;&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-329"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-327">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-328'
	>
	Without an Open Banking API&nbsp;provider&nbsp;the system cannot function. The whole idea is dependent on the providers. All banking information is provided by them, so we need to connect with such a provider and extract the information in a secure way.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-332"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-330">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-331'
	>
	The MCP server communicates with the provider through a standardized PSD2 interface, which means the underlying provider can be swapped without changes to the MCP layer or the ChatGPT App.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-335"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-333">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-334'
	>
	In practice, providers vary in how faithfully they implement the PSD2 spec, so some adaptation at the integration layer is expected. But the core architecture has no single-provider dependency baked in. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-338"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-336">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-337'
	>
	Dynamic Client Registration (DCR)&nbsp;</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-341"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-339">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-340'
	>
	Since we integrate through a single Open Banking API provider rather than directly with individual bank authorization servers, DCR is handled at the provider level. It’s not something our architecture needs to address directly. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-344"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-342">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-343'
	>
	LLM Limitations Worth Knowing&nbsp;</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-347"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-345">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-346'
	>
	With the architecture in place, there are a few model-level constraints that affect how far the current implementation can stretch.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-350"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-348">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-349'
	>
	<strong>Rapidly changing financial data (exchange rates, stock prices)&nbsp;</strong>&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-353"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-351">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-352'
	>
	The model&nbsp;doesn’t&nbsp;have live financial context by default. The correct approach is a dedicated MCP tool that fetches current data before any function that needs it. We&nbsp;haven’t&nbsp;implemented this yet, but the pattern is straightforward: add a get-market-context tool and instruct the model to call it first.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-356"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-354">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-355'
	>
	<strong>Local regulation and terminology outside the training set</strong>&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-359"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-357">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-358'
	>
	For the use cases this app targets — consumer-facing, non-specialist — the base model’s training data has been sufficient. For regulated or jurisdiction-specific deployments, a RAG layer or a context-injection tool would be the right extension point.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-362"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-360">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-361'
	>
	Keeping Financial Data Out of the LLM Context&nbsp;</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-365"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-363">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-364'
	>
	Beyond model limitations,&nbsp;there’s&nbsp;a broader question about data handling&nbsp;that’s&nbsp;directly relevant to PSD2 compliance.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-368"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-366">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-367'
	>
	We control what we can on our side: MCP tools return lean, structured payloads (not raw API objects), and no financial data is stored server-side beyond the lifetime of the request. What happens inside OpenAI’s platform is governed by their data policies, and those policies vary by account type.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-371"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-369">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-370'
	>
	For any financial use case&nbsp;operating&nbsp;under PSD2, users should access the app through a ChatGPT Team or Enterprise account, or at minimum disable training in their data controls settings.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-374"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-372">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-373'
	>
	The&nbsp;End-Result:&nbsp;Conversational Open Banking&nbsp;</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-377"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-375">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-376'
	>
	Once a user connects their bank account through the OAuth flow, they can interact with their financial data conversationally inside ChatGPT.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-380"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-378">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-379'
	>
	Instead of opening a banking app and navigating through menus, the user can ask:&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-383"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-381">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-382'
	>
	<li>“What’s my current balance?”&nbsp;</li><li>“Show me my last 10 transactions.”&nbsp;</li><li>“How much did I spend on subscriptions this month?”&nbsp;</li><li>“Do I have any incoming payments this week?”&nbsp;</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-386"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-384">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-385'
	>
	The experience feels like messaging a financial assistant who already understands your question and knows where to look. Behind the scenes, everything remains secure and permission-based, but from the user’s perspective, it’s effortless. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-389"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-387">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-388'
	>
	<em>This article was originally published on the <a href="https://www.infobip.com/developers/blog/building-an-mcp-powered-open-banking-app-inside-chatgpt" target="_blank" rel="noreferrer noopener">Infobip Developer Blog</a>. Learn more about Infinum and Infobip’s <a href="https://infinum.com/news/infinum-infobip-partnership/" target="_blank" rel="noreferrer noopener">integration partnership</a>.</em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/mcp-open-banking-chatgpt/">Building an MCP-Powered Open Banking App Inside ChatGPT</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19278577https://infinum.com/uploads/2026/04/img-hero-glasswing.webp</url>
				</image>
				<title>Project Glasswing Proves Frontier AI Can Break – and Fix – Software</title>
				<link>https://infinum.com/blog/anthropic-project-glasswing/</link>
				<pubDate>Fri, 17 Apr 2026 13:12:58 +0000</pubDate>
				<dc:creator>Blanka Bogdanović</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19278577</guid>
				<description>
					<![CDATA[<p>Anthropic's Project Glasswing signals a new era where frontier AI hunts vulnerabilities at scale. Here's what security teams need to understand – and do – right now. </p>
<p>The post <a href="https://infinum.com/blog/anthropic-project-glasswing/">Project Glasswing Proves Frontier AI Can Break – and Fix – Software</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-624"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-392">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-395"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-393">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-394'
	>
	<strong>Anthropic just launched Project Glasswing – a major initiative to hunt vulnerabilities in critical open-source software using its most capable AI model. The implications for defenders and attackers alike are significant, and most organisations are not ready for either.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-398"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-396">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-397'
	>
	On 7 April 2026, Anthropic launched <a href="https://www.anthropic.com/glasswing" target="_blank" rel="noreferrer noopener">Project Glasswing</a> – a coordinated effort to give key technology providers early access to Claude Mythos Preview with one goal: find and fix long-hidden vulnerabilities in critical open-source software before attackers do.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-401"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-399">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-400'
	>
	It is the clearest signal yet that frontier AI has crossed a threshold. It is no longer just a productivity tool bolted onto existing security workflows. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-403"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-402'
	>
	It is becoming an active participant in the vulnerability lifecycle, capable of reasoning across vast codebases, identifying subtle logic flaws, and chaining issues into exploitable paths that would take a human researcher weeks to uncover.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-406"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-404">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-405'
	>
	That is worth taking seriously. Not because of the marketing, but because credible institutions are paying attention. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-409"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-407">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-408'
	>
	The AI Security Institute and the UK National Cyber Security Centre have both<a href="https://www.aisi.gov.uk/research/measuring-ai-agents-progress-on-multi-step-cyber-attack-scenarios"> documented measurable progress</a> in AI agents completing multi-step cyber attack scenarios. The NCSC has<a href="https://www.ncsc.gov.uk/blogs/why-cyber-defenders-need-to-be-ready-for-frontier-ai"> called on defenders to prepare</a> for a world in which frontier AI amplifies attacker capabilities at pace.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-412"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-410">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-411'
	>
	Glasswing is a concrete attempt to tilt that balance back toward defence. The early findings suggest it is working.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-415"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-413">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-414'
	>
	<strong>The two-sided ledger of AI-assisted security</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-418"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-416">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-417'
	>
	For most of computing history, finding and <a href="https://infinum.com/third-party-cyber-risk-management/" id="https://infinum.com/third-party-cyber-risk-management/">exploiting software vulnerabilities</a> required rare expertise. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-421"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-419">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-420'
	>
	The people who could do it reliably numbered in the thousands globally. That constraint mattered – it was a practical limit on how fast attackers could operate and how broadly they could target. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-424"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-422">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-423'
	>
	Over the past year, that constraint has eroded sharply.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-427"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-425">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-426'
	>
	AI models have become increasingly effective at reading and reasoning about code, showing a particular ability to spot vulnerabilities and work out how to exploit them. The cost, effort, and level of expertise required have all dropped dramatically.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-429"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-428'
	>
	<strong>Here is the uncomfortable truth: the same capabilities that make a frontier model useful for vulnerability discovery make it useful for exploitation.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-432"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-430">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-431'
	>
	Claude Mythos Preview, Anthropic&#8217;s unreleased frontier model behind Glasswing, has reached a level of coding capability where it can <strong>surpass all but the most skilled humans</strong> at finding and exploiting software vulnerabilities. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-435"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-433">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-434'
	>
	That is not a marketing claim – it is the assessment Anthropic has published alongside the initiative. The AISI&#8217;s<a href="https://www.aisi.gov.uk/blog/our-evaluation-of-claude-mythos-previews-cyber-capabilities" target="_blank" rel="noreferrer noopener"> evaluation of Claude Mythos Preview&#8217;s cyber capabilities</a> tracks the same capability curve and reaches similar conclusions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-438"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-436">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-437'
	>
	And it is not only expert hands that can wield it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-440"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-439'
	>
	Anthropic&#8217;s own Red Team blog reports that engineers with no formal security training asked Mythos Preview to find remote code execution vulnerabilities overnight, and woke up the following morning to a complete, working exploit.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-443"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-441">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-442'
	>
	An AI that can read a codebase, reason about execution paths, and identify edge cases in authentication logic can do that work for a defender running a bug bounty programme or for an attacker building an exploit chain. <strong>The model does not care which side of the firewall it is on. </strong>And given the rate of AI progress, these capabilities will not remain confined to actors committed to deploying them safely.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-446"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-444">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-445'
	>
	The question for security teams is not whether to engage with this shift. It is – how fast.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-449"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-447">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-448'
	>
	<strong>What Glasswing tells us about where this is heading</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-452"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-450">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-451'
	>
	Anthropic&#8217;s approach with Glasswing is instructive beyond the specific initiative. A few things stand out.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-455"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-453">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-454'
	>
	<strong>The focus on open-source infrastructure is deliberate</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-458"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-456">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-457'
	>
	Open-source software underpins almost every critical system in operation today – cloud platforms, financial infrastructure, healthcare systems, industrial controls. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-461"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-459">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-460'
	>
	Vulnerabilities in widely used libraries do not stay contained. When one surfaces, the blast radius is enormous and the window between disclosure and exploitation has compressed to hours in many cases. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-464"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-462">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-463'
	>
	The <a href="https://infinum.com/blog/axios-npm-supply-chain-attack/" target="_blank" rel="noreferrer noopener">Axios npm supply chain attack in March 2026</a> – where two malicious versions of one of JavaScript&#8217;s most-used libraries were quietly published – is a recent example of exactly how fast that window closes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-467"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-465">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-466'
	>
	<strong>The results are concrete </strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-470"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-468">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-469'
	>
	Mythos Preview has already found <strong>thousands of zero-day vulnerabilities</strong> –  flaws previously unknown even to the software&#8217;s own developers – including some in <strong>every major operating system and web browser</strong>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-473"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-471">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-472'
	>
	Some of the specific findings illustrate just how significant the capability leap is:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-476"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-474">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-475'
	>
	<li><strong>A 27-year-old vulnerability in OpenBSD</strong> – one of the most security-hardened operating systems in the world, widely used to run firewalls and critical infrastructure – that allowed an attacker to remotely crash any machine running the OS simply by connecting to it.</li><li><strong>A 16-year-old vulnerability in FFmpeg</strong>, the video encoding library used by an enormous range of software, in a line of code that automated testing tools had hit five million times without catching the problem.</li><li><strong>A chain of vulnerabilities in the Linux kernel</strong> – the software running most of the world&#8217;s servers – that the model found and linked autonomously to escalate from ordinary user access to full control of the machine.</li><li>A web browser exploit that <strong>chained together four separate vulnerabilities,</strong> writing a complex attack that escaped both the browser&#8217;s renderer sandbox and the operating system sandbox beneath it.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-479"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-477">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-478'
	>
	The gap between Mythos Preview and the previous generation of models is also stark. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-482"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-480">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-481'
	>
	When tested against known vulnerabilities in Mozilla&#8217;s Firefox JavaScript engine, the previous best model – Claude Opus 4.6 – turned those vulnerabilities into working exploits <strong>twice</strong> out of several hundred attempts. <strong>Mythos Preview did it 181 times.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-485"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-483">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-484'
	>
	These are not theoretical weaknesses. They are exploitable flaws that survived decades of human review and millions of automated tests. The model found them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-488"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-486">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-487'
	>
	<strong>The initiative is coordinated by design </strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-491"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-489">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-490'
	>
	Early access, structured disclosure, defined scope – Glasswing is built to funnel findings into responsible remediation rather than onto a paste site.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-493"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<div	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-492'
	>
	<strong>Anthropic&#8217;s position is that the same capabilities that make AI dangerous in the wrong hands make it invaluable for finding and fixing flaws in critical software, and for producing new software with fewer security bugs from the start.&nbsp;</strong></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-496"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-494">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-495'
	>
	That framing is worth taking at face value, because the alternative – waiting for these capabilities to proliferate without a coordinated defensive response – is considerably worse.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-499"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-497">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-498'
	>
	For organisations watching from the outside, the implication is direct: if a frontier model can find vulnerabilities in your dependencies that survived decades of human review and millions of automated tests, you cannot rely on existing scanning and review processes to give you confidence that your attack surface is clean.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-502"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-500">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-501'
	>
	<strong>The attacker&#8217;s advantage – and how to close it</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-505"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-503">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-504'
	>
	Defenders have always operated at a structural disadvantage. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-507"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-506'
	>
	An attacker needs to find one way in. A defender needs to close every path. AI widens that gap if defenders do not move.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-510"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-508">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-509'
	>
	The realistic near-term threat is not yet a fully autonomous AI attacker operating without human direction. But it is human attackers using AI to operate faster, at a greater scale, and with less specialised knowledge than was previously required. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-513"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-511">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-512'
	>
	A moderately skilled attacker with access to a capable model can accelerate reconnaissance, generate targeted phishing content, identify patch-gap windows, and synthesise public vulnerability research into working attack chains. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-518"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-514">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-515'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-516'
	>
	Attacks that previously required specialist knowledge are now within reach of far more people.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-517'
	>
	SEAN MCCARTHY, HEAD OF CYBERSECURITY TESTING, AMR CYBERSECURITY &#8211; PART OF INFINUM</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-521"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-519">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-520'
	>
	We explored a version of this problem in our <a href="https://infinum.com/blog/security-gaps-in-vibe-coded-applications/" target="_blank" rel="noreferrer noopener">analysis of security gaps in vibe-coded applications</a>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-524"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-522">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-523'
	>
	AI-generated code introduces vulnerabilities not because the model is careless but because it optimises for functional correctness, not security depth. An attacker using the same models to probe those applications has a natural advantage over a developer who did not think adversarially when prompting.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-527"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-525">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-526'
	>
	<strong>The answer is not to avoid AI in development. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-530"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-528">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-529'
	>
	It is to apply <a href="https://infinum.com/blog/ssdlc-application-security/" target="_blank" rel="noreferrer noopener">deliberate security discipline at every stage</a> – including to the AI-generated output itself. That means combining automated scanning with <a href="https://infinum.com/cybersecurity/penetration-testing/" target="_blank" rel="noreferrer noopener">human-led testing</a> rather than assuming one replaces the other.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-533"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-531">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-532'
	>
	<strong>What organisations should do before the surge hits</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-536"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-534">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-535'
	>
	Glasswing is likely to accelerate vulnerability disclosures across the open-source ecosystem. Organisations that are unprepared for a sudden increase in security advisories affecting their dependencies will struggle to respond at pace.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-539"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-537">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-538'
	>
	<strong>Martin Walsham, Director of Cybersecurity at AMR Cybersecurity</strong> <strong>– Part of Infinum</strong>, has been tracking this shift closely: &#8220;Frontier AI models are progressing at pace, and the same technologies that defenders can use to increase overall security posture can equally be used by attackers to amplify their capabilities. This heightens the need for organisations to implement strong security baselines, defence in depth, and robust secure code, and to patch at pace to make them less susceptible to attacks.”</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-544"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-540">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-541'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-542'
	>
	<strong>Ahead of an anticipated surge in vulnerability reporting, organisations should be assessing and investing in advanced tooling and enhanced services to continually protect, detect, and respond to cyber threats – because the pace at which attackers operate will only increase.</strong></p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-543'
	>
	MARTIN WALSHAM, DIRECTOR OF CYBERSECURITY, AMR CYBERSECURITY &#8211; PART OF INFINUM. </div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-547"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-545">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-546'
	>
	The precautionary steps below are not dramatic departures from good security hygiene. They are the foundations that make rapid response possible when it is needed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-550"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-548">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-549'
	>
	<strong>Review and test your incident response plan now.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-553"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-551">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-552'
	>
	Not the version that was written two years ago and has not been touched since. Run a tabletop exercise against a realistic scenario – a critical CVE in a dependency you cannot patch immediately, combined with active exploitation attempts.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-556"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-554">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-555'
	>
	<strong>Prepare for increased advisory volume.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-559"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-557">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-558'
	>
	If AI-assisted vulnerability research delivers on its promise, the rate of disclosures in widely used open-source libraries will increase. Security and engineering teams need the capacity to triage and prioritise that volume without dropping everything else. Build that capacity before the surge, not during it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-562"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-560">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-561'
	>
	<strong>Get your asset management list accurate.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-565"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-563">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-564'
	>
	You cannot patch what you do not know you are running. This is the most consistent gap we see in organisations that have otherwise mature security programmes. A dependency buried four levels deep in your supply chain is still your problem when a CVE drops against it. Our <a href="https://infinum.com/blog/software-supply-chain-security/" id="https://infinum.com/blog/software-supply-chain-security/" target="_blank" rel="noreferrer noopener">step-by-step software supply chain security framework</a> covers how to map and manage that exposure systematically.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-568"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-566">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-567'
	>
	<strong>Monitor updates and advisories actively.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-571"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-569">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-570'
	>
	Subscribe to feeds for the libraries and platforms you depend on. Automated dependency scanning tools have improved significantly – if you are not running one, start.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-574"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-572">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-573'
	>
	<strong>Review third-party agreements with critical suppliers.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-577"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-575">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-576'
	>
	If a vulnerability surfaces in a service you depend on and your contract does not specify patching SLAs, you have no lever to apply. Review those agreements and open conversations with suppliers about their response posture before you need to have that conversation under pressure.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-580"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-578">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-579'
	>
	<strong>Test your external perimeter.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-583"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-581">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-582'
	>
	If your last penetration test was more than twelve months ago, you do not have an accurate picture of your exposure. This is especially true for organisations that have made infrastructure changes, onboarded new services, or shipped significant product updates since the last test.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-586"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-584">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-585'
	>
	<strong>Have a plan for enhanced monitoring at short notice.&nbsp;</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-589"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-587">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-588'
	>
	Not all threats give you advance warning. Know what elevated monitoring looks like for your environment and how quickly you can activate it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-592"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-590">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-591'
	>
	<strong>Security baselines matter more, not less</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-595"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-593">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-594'
	>
	There is a temptation to frame AI-powered threats as something categorically new that requires a categorically new response.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-598"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-596">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-597'
	>
	In some respects, that is true – the <strong>speed and scale</strong> at which AI-assisted attacks can operate does change the calculus. But the vulnerabilities being exploited are mostly the same ones that have always existed: missing input validation, broken access control, insecure defaults, and unpatched dependencies. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-601"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-599">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-600'
	>
	Our <a href="https://infinum.com/blog/cybersecurity-trends-2026/" target="_blank" rel="noreferrer noopener">cybersecurity trends outlook for 2026</a> covers how AI-driven attacks, stricter compliance requirements, and supply chain exposure are converging into a single pressure point for security teams.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-604"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-602">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-603'
	>
	The <a href="https://infinum.com/blog/eu-cybersecurity-legislation-nis2-dora/" target="_blank" rel="noreferrer noopener">NIS2 and DORA frameworks</a> that came into force across the EU reflect this same reality. The technical requirements they mandate – multi-factor authentication, incident reporting, supply chain risk management, regular penetration testing – are not responses to AI-powered threats specifically. They are the baseline hygiene that makes an organisation resilient regardless of what the attacker is using. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-605">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-606'
	>
	If your organisation is not meeting that baseline, the sophistication of the threat is almost beside the point.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-610"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-608">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-609'
	>
	<strong>Strong foundations beat reactive firefighting</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-613"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-611">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-612'
	>
	Project Glasswing is a meaningful development in the responsible use of frontier AI for defence. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-616"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-614">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-615'
	>
	The AISI and NCSC assessments confirm what security practitioners have been observing in practice: <strong>capability is advancing faster than most organisations have adjusted for.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-619"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-617">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-618'
	>
	The right response is not to wait and see how the landscape settles. It is to invest in the defences that reduce exposure across the board – sound architecture, secure development practices, regular testing, and the operational readiness to respond when something goes wrong.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-622"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-620">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-621'
	>
	<em>Infinum&#8217;s <a href="https://infinum.com/cybersecurity/penetration-testing/" target="_blank" rel="noreferrer noopener">penetration testing</a> and <a href="https://infinum.com/cybersecurity/" target="_blank" rel="noreferrer noopener">cybersecurity services</a> are built around exactly that kind of proactive posture. If you want to understand your current exposure before the next wave of disclosures hits, talk to our security team.</em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/anthropic-project-glasswing/">Project Glasswing Proves Frontier AI Can Break – and Fix – Software</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19278542https://infinum.com/uploads/2026/04/img-GRC-article2.webp</url>
				</image>
				<title>Why GRC Fails – and What a Framework That Actually Works Looks Like</title>
				<link>https://infinum.com/blog/grc-framework/</link>
				<pubDate>Fri, 17 Apr 2026 11:46:06 +0000</pubDate>
				<dc:creator>Tom Miller</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19278542</guid>
				<description>
					<![CDATA[<p>Most GRC programs fail not because the framework is wrong, but because it's built to satisfy auditors, not protect businesses. Here's what that costs you – and how to do it differently.</p>
<p>The post <a href="https://infinum.com/blog/grc-framework/">Why GRC Fails – and What a Framework That Actually Works Looks Like</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-648"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-625">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-628"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-626">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-627'
	>
	<strong>Most GRC programs fail not because the framework is wrong, but because it&#8217;s built to satisfy auditors, not protect businesses. Here&#8217;s what that costs you – and how to do it differently.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-631"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-629">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-630'
	>
	Most organisations have some version of GRC in place. Policies exist. Compliance boxes get ticked. A risk register lives somewhere in a shared drive, last updated before anyone currently on the team joined. And then a breach happens, or an audit goes badly, and everyone is surprised.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-634"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-632">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-633'
	>
	They shouldn&#8217;t be. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-637"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-635">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-636'
	>
	The most common GRC failure isn&#8217;t ignorance of the framework – it&#8217;s treating it as an administrative exercise rather than a decision-making system. You end up with documentation that describes security rather than delivers it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-640"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-638">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-639'
	>
	That distinction matters more than most security conversations acknowledge.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-643"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-641">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-642'
	>
	<strong>Why GRC exists – and why it usually gets implemented wrong</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-646"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-644">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-645'
	>
	GRC – governance, risk, and compliance – is a system for making security decisions that support a business rather than obstruct it. Not rules imposed from above, but a framework built around what the organisation is actually trying to achieve.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-659"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-658">
	
<div class="block-column" data-id="es-657">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-656"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-655">
	
<div class="block-grid-item" data-id="es-654">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-649"
	 href='https://infinum.com/blog/what-is-grc/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-650'
	>
	<strong>If you want a deeper grounding in GRC fundamentals before going further, start with our GRC explainer – it covers the full framework from first principles.</strong></div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-651"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-652'
	>
	Start here</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-653'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-825"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-660">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-663"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-661">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-662'
	>
	The problem is that most implementations start from the wrong end. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-666"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-664">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-665'
	>
	They start with a compliance requirement, <strong>reverse-engineer the policies needed to satisfy it</strong>, and call that a GRC program. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-669"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-667">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-668'
	>
	The risk register gets populated because ISO 27001 requires one, not because anyone is actively using it. Policies get written because auditors want to see them, not because they reflect how the business actually operates.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-671"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-670'
	>
	This is checkbox compliance. And it&#8217;s not just ineffective – it&#8217;s actively dangerous. It creates the appearance of security maturity without the substance. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-674"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-672">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-673'
	>
	When something goes wrong, the documentation says the right things. The reality doesn&#8217;t match.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-677"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-675">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-676'
	>
	A GRC framework that works starts with a different question: what is this business trying to achieve, and what could prevent it? <strong>Risk is the answer. </strong>Governance and compliance are how you respond to it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-680"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-678">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-679'
	>
	<strong>Start with risk – and be honest about it</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-683"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-681">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-682'
	>
	Risk sits at the centre of GRC. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-688"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-684">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-685'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-686'
	>
	<strong>Most organisations are far better at documenting risk than they are at being honest about it.</strong></p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-687'
	>
	TOM MILLER, HEAD OF ASSURANCE, AMR CYBERSECURITY – PART OF INFINUM</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-691"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-689">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-690'
	>
	The starting point is asset classification – understanding what you&#8217;re actually trying to protect. Critical data, intellectual property, operational systems, customer-facing services. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-694"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-692">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-693'
	>
	Not everything is equal, and treating it as if it is means you&#8217;ll over-invest in protecting things that don&#8217;t matter and under-invest in protecting things that do.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-697"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-695">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-696'
	>
	Once assets are mapped, the threat picture becomes clearer. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-700"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-698">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-699'
	>
	<li><strong>Sensitive customer data attracts financially motivated attackers.</strong></li><li><strong>Source code repositories attract competitors and state actors. </strong></li><li><strong>Physical sites face different exposure entirely.</strong></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-703"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-701">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-702'
	>
	The threats facing each asset differ in nature, method, and likely impact – and that shapes how risk should be assessed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-706"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-704">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-705'
	>
	<span class='screen-reader-text'>Risk assessment comes down to two dimensions: impact and likelihood. </span><span aria-hidden='true'>Risk assessment comes down to two dimensions: <strong>impact and likelihood. </strong></span></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-709"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-707">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-708'
	>
	<span class='screen-reader-text'>How damaging would this event be – financially, operationally, reputationally? And how likely is it to occur given your current controls and environment? </span><span aria-hidden='true'><em>How damaging would this event be – financially, operationally, reputationally? And how likely is it to occur given your current controls and environment? </em></span></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-712"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-710">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-711'
	>
	Plot those two on a matrix, score them consistently, and you get a risk level you can act on.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-715"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-713">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-714'
	>
	The scoring methodology matters less than its consistent application. An organisation that assesses risk differently each quarter produces data that can&#8217;t be trended or compared. The value of a risk register is cumulative – it shows you how risk is changing over time, which controls are working, and where new exposure is emerging.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-717"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-716'
	>
	<strong>Risk reviews should happen at least annually for the full register, and quarterly for anything rated high.</strong> </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-720"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-718">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-719'
	>
	Each risk needs a named owner – a senior person responsible for accepting that the risk level is appropriate and for escalating it if it changes. Without ownership, risks get logged and forgotten.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-723"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-721">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-722'
	>
	<strong>What to do when a control isn&#8217;t working</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-726"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-724">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-725'
	>
	This is where most GRC programs go quiet. A control gets implemented, it gets checked off, and nobody asks whether it actually changed anything.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-728"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-727'
	>
	When a control isn&#8217;t working – when the risk level hasn&#8217;t moved, or when incidents keep recurring in the same area – the answer isn&#8217;t to add more controls. It&#8217;s to go back to the risk assessment and ask whether you&#8217;ve correctly understood the threat.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-731"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-729">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-730'
	>
	Often, the control addresses the symptom rather than the cause. A phishing training module doesn&#8217;t solve a culture that punishes people for reporting mistakes. A firewall rule doesn&#8217;t fix misconfigured cloud permissions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-736"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-732">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-733'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-734'
	>
	Controls should reduce either the likelihood or the impact of a risk. If neither is moving, something is wrong with the control, the assessment, or both. </p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-735'
	>
	TOM MILLER, HEAD OF ASSURANCE, AMR CYBERSECURITY – PART OF INFINUM</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-739"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-737">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-738'
	>
	For technical controls specifically,<a href="https://infinum.com/blog/why-penetration-testing-is-important/"> penetration testing</a> is one of the most direct ways to find out whether a control is actually doing what you think it is.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-742"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-740">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-741'
	>
	<strong>Why security policies fail – and what to do about it</strong>?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-745"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-743">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-744'
	>
	Governance is what makes risk management repeatable. Documented policies, defined responsibilities, clear ownership – the infrastructure that ensures security doesn&#8217;t live in one person&#8217;s head and doesn&#8217;t fall apart when someone leaves.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-748"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-746">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-747'
	>
	But governance has a failure mode that organisations consistently underestimate: policies that nobody follows.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-751"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-749">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-750'
	>
	<li><strong>Lock down laptops too tightly, and people find workarounds.  </strong></li><li><strong>Require complex passwords to be changed every 30 days, and they get written on sticky notes. </strong></li><li><strong>Mandate a slow, bureaucratic approval process for software tools, and teams start using personal accounts for work data.</strong></li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-754"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-752">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-753'
	>
	If staff are bypassing a control, that is not a compliance problem. It is a design problem. The control is wrong. It&#8217;s asking people to choose between doing their job and following the rules, and unsurprisingly, they choose their job.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-756"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-755'
	>
	The irony is that overly strict controls often create more risk than they prevent – because the workarounds are almost always less secure than whatever the policy was trying to enforce.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-759"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-757">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-758'
	>
	The fix isn&#8217;t stricter enforcement. It&#8217;s redesigning the control to be compatible with how work actually gets done. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-762"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-760">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-761'
	>
	<strong>Security that works with people is more effective than security that works against them, even if it looks less rigorous on paper.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-765"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-763">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-764'
	>
	Metrics are how you catch this early.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-768"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-766">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-767'
	>
	Security training completion rates, phishing simulation results, patch compliance rates, incident trends – these tell you whether the governance framework is working in practice, not just on paper. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-771"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-769">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-770'
	>
	Patterns in that data are diagnostic. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-774"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-772">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-773'
	>
	If phishing click rates stay flat after multiple training rounds, the training isn&#8217;t the solution. If patch compliance drops in one team, there&#8217;s a resourcing or tooling problem to fix, not a people problem to escalate.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-777"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-775">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-776'
	>
	Incident reporting culture sits underneath all of it </h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-780"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-778">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-779'
	>
	Teams that punish mistakes get underreporting. Underreporting means the same vulnerabilities recur because nobody connected the dots between incidents. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-782"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-781'
	>
	An environment where people report phishing clicks, near misses, and process failures without fear is not a soft environment – it&#8217;s one that learns faster than its attackers. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-785"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-783">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-784'
	>
	For teams building software, the same principle applies to the development process itself: embedding security from the start is cheaper and more effective than bolting it on later.<a href="https://infinum.com/blog/ssdlc-application-security/"> Here&#8217;s what that shift looks like in practice.</a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-788"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-786">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-787'
	>
	<strong>How to decide whether to comply with a regulation</strong>?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-791"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-789">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-790'
	>
	Compliance is the most visible part of GRC, and the most frequently misunderstood. The default assumption is that compliance requirements are obligations to be met. Some are. Many aren&#8217;t.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-794"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-792">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-793'
	>
	There are three distinct categories worth separating:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-797"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-795">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-796'
	>
	<li><strong>Mandatory compliance</strong> – legal requirements that apply to your organisation based on sector, geography, or the nature of the data you handle. GDPR for organisations processing EU personal data.<a href="https://infinum.com/blog/eu-cybersecurity-legislation-nis2-dora/"> NIS2 and DORA</a> for financial services and critical sectors across the EU. Non-compliance here isn&#8217;t a business decision – it&#8217;s a legal exposure.</li><li><strong>Commercial compliance</strong> – certifications and frameworks that aren&#8217;t legally required but open doors. ISO 27001 is the most common example: many enterprise customers and regulated-industry partners won&#8217;t sign contracts with vendors who can&#8217;t demonstrate it. The compliance decision here is a sales and market access question as much as a security one.</li><li><strong>Voluntary frameworks</strong> – standards like NIST or CIS Controls that provide useful structure without any external mandate. The value is in the methodology, not the certification.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-800"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-798">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-799'
	>
	Treating all three categories the same way produces bad decisions. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-803"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-801">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-802'
	>
	Spending significant resources on a voluntary framework while ignoring a mandatory obligation is a governance failure. So is pursuing an expensive certification that none of your target customers will ever ask for.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-806"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-804">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-805'
	>
	<strong>Outcome-based regulation changes the calculation</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-809"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-807">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-808'
	>
	Increasingly, regulators define what good looks like rather than prescribing exactly how to get there. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-812"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-810">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-811'
	>
	<a href="https://infinum.com/cybersecurity/nis2-compliance-services/" target="_blank" rel="noreferrer noopener">NIS2</a> is a clear example – it specifies required capabilities and outcomes across risk management, incident handling, and supply chain security, but leaves implementation to the organisation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-815"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-813">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-814'
	>
	This is good policy design. It acknowledges that a one-size-fits-all technical prescription can&#8217;t account for the diversity of organisations in scope. But it <strong>shifts the burden onto organisations</strong> to genuinely interpret what compliance means for their context, rather than following a checklist.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-818"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-816">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-817'
	>
	That interpretation requires security judgment, not just legal review. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-820"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-819'
	>
	A small professional services firm and a hospital group might both fall under NIS2, but the controls that constitute appropriate risk management for each look very different. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-823"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-821">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-822'
	>
	Getting that translation right is the work – and it can&#8217;t be delegated entirely to a compliance team.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-836"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-835">
	
<div class="block-column" data-id="es-834">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-833"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-832">
	
<div class="block-grid-item" data-id="es-831">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-826"
	 href='https://infinum.com/blog/cybersecurity-trends-2026/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-827'
	>
	<strong><strong><strong><strong>For a current view of which regulatory shifts are having the most practical impact on security teams right now,</strong><a href="https://infinum.com/blog/cybersecurity-trends-2026/"><strong> our 2026 cybersecurity trends piece</strong></a><strong> covers the landscape.</strong></strong></strong></strong></div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-828"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-829'
	>
	Learn more here</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-830'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-868"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-837">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-840"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-838">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-839'
	>
	<strong>Vendor risk: the risk you let in without realising it</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-843"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-841">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-842'
	>
	Your own security posture is only part of the picture. Every supplier onboarded, every tool deployed, every third party with any form of access to your systems extends your attack surface. In most organisations, that surface is considerably larger than anyone has formally mapped.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-845"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-844'
	>
	Vendor risk management isn&#8217;t about being suspicious of suppliers. It&#8217;s about not assuming trust where it hasn&#8217;t been established. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-848"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-846">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-847'
	>
	The questions worth asking before any significant vendor relationship:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-851"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-849">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-850'
	>
	<li>Do they hold relevant certifications (ISO 27001, Cyber Essentials, SOC 2)?</li><li>Has their product been independently penetration tested, and will they share the findings?</li><li>How do they manage vulnerabilities in their own software and infrastructure?</li><li>What access will they have to your systems – and is that access scoped correctly?</li><li>What happens to your data if the relationship ends?</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-854"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-852">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-853'
	>
	These aren&#8217;t bureaucratic hurdles. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-857"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-855">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-856'
	>
	They&#8217;re the minimum basis for making an informed decision about the risk a vendor introduces. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-860"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-858">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-859'
	>
	An organisation that can&#8217;t answer these questions about its critical suppliers has a <strong>material gap in its risk picture,</strong> regardless of how well-managed its internal controls are.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-863"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-861">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-862'
	>
	Supply chain compromise is one of the highest-impact attack vectors in the current threat landscape, precisely because it bypasses the controls organisations invest in protecting their own perimeter.<a href="https://infinum.com/blog/software-supply-chain-security/"> </a></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-866"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-864">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-865'
	>
	 </p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-879"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-878">
	
<div class="block-column" data-id="es-877">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-876"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-875">
	
<div class="block-grid-item" data-id="es-874">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-869"
	 href='https://infinum.com/blog/software-supply-chain-security/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-870'
	>
	The software supply chain security problem is worth understanding in detail if your organisation builds or depends on software from third parties.</div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-871"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-872'
	>
	Learn more</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-873'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-905"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-880">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-883"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-881">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-882'
	>
	<strong>The loop that most organisations miss</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-886"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-884">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-885'
	>
	The reason GRC works – when it works – is that governance, risk, and compliance aren&#8217;t separate programmes running in parallel. They&#8217;re a loop.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-888"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-887'
	>
	Risk assessment drives what governance policies need to exist. Governance structures ensure risks are owned and monitored. Compliance requirements feed back into risk, because falling foul of a regulation is itself a risk with an impact and a likelihood that needs to be assessed and managed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-891"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-889">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-890'
	>
	Break any link in that loop and the system degrades. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-894"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-892">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-893'
	>
	Risk managed without governance produces decisions that live in spreadsheets and get forgotten. Governance without risk produces policies disconnected from the actual threats. Compliance without either produces documentation that satisfies auditors and protects no one.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-897"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-895">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-896'
	>
	The organisations that do this well aren&#8217;t the ones with the most sophisticated tools or the thickest policy libraries. They&#8217;re the ones where security decisions are made deliberately, with clear ownership, against a shared understanding of what the business is trying to protect.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-900"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-898">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-899'
	>
	That&#8217;s a cultural outcome as much as a process one. And it&#8217;s harder to fake than any compliance certificate.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-903"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-901">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-902'
	>
	<em>Security that works with your business rather than against it starts with the right foundations. Infinum&#8217;s security practice helps organisations build GRC frameworks grounded in real risk, not just audit readiness.</em><a href="https://infinum.com/cybersecurity/" id="https://infinum.com/cybersecurity/"><em> Explore our cybersecurity services</em></a><em> to see where we can help.</em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/grc-framework/">Why GRC Fails – and What a Framework That Actually Works Looks Like</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19278431https://infinum.com/uploads/2026/04/img-GRC-article1.webp</url>
				</image>
				<title>What Is GRC? Governance, Risk, and Compliance Explained</title>
				<link>https://infinum.com/blog/what-is-grc/</link>
				<pubDate>Fri, 17 Apr 2026 11:46:02 +0000</pubDate>
				<dc:creator>Tom Miller</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19278431</guid>
				<description>
					<![CDATA[<p>GRC connects governance, risk, and compliance into a single decision-making system. Here's what each pillar means, how they interact, and how businesses apply them in practice.</p>
<p>The post <a href="https://infinum.com/blog/what-is-grc/">What Is GRC? Governance, Risk, and Compliance Explained</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-926"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-906">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-909"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-907">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-908'
	>
	<strong>GRC connects governance, risk, and compliance into a single decision-making system. Here&#8217;s what each pillar means, how they interact, and how businesses apply them in practice.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-912"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-910">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-911'
	>
	Most organizations already manage<strong> <a href="https://infinum.com/governance-risk-compliance-services/" id="https://infinum.com/governance-risk-compliance-services/">governance, risk, and compliance</a></strong> in some form – they just do it in separate silos, with different teams, different tools, and no shared language. GRC formalizes that into a single, connected system.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-915"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-913">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-914'
	>
	When governance, risk, and compliance operate independently, decisions get made without context. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-918"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-916">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-917'
	>
	An IT team patches vulnerabilities without knowing which ones actually threaten business-critical systems. A compliance team checks boxes without understanding the underlying risk. Leadership approves budgets without visibility into what they&#8217;re actually protecting.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-921"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-919">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-920'
	>
	GRC fixes that – not by adding process overhead, but by aligning security decisions with business goals. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-924"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-922">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-923'
	>
	And in an environment where the regulatory landscape keeps expanding, the number of threat vectors keeps growing, and senior leadership is increasingly held personally accountable for security failures, that alignment is no longer optional.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-937"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-936">
	
<div class="block-column" data-id="es-935">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-934"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-933">
	
<div class="block-grid-item" data-id="es-932">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-927"
	 href='https://infinum.com/blog/grc-framework/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-928'
	>
	<strong>Already familiar with GRC but want a more practical perspective on how it should work in real businesses</strong>? Check out our blog on the GRC framework for modern organizations. </div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-929"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-930'
	>
	Learn more here</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-931'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-1124"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-938">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-941"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-939">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-940'
	>
	<strong>What does GRC stand for?</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-944"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-942">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-943'
	>
	GRC stands for Governance, Risk, and Compliance. Each term names a distinct discipline, but the value of GRC comes from how they interact.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-947"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-945">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-946'
	>
	<strong>Governance</strong> defines how an organization makes decisions – its policies, roles, responsibilities, and the processes that keep security practices consistent as the business grows or changes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-950"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-948">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-949'
	>
	<strong>Risk</strong> is the analytical core. Risk management identifies what matters most to the business, assesses what could go wrong, and determines how much uncertainty the organization is willing to accept.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-953"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-951">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-952'
	>
	<strong>Compliance</strong> ensures the organization meets its legal, regulatory, contractual, and framework-based obligations – whether that&#8217;s GDPR,<a href="https://infinum.com/blog/eu-cybersecurity-legislation-nis2-dora/" target="_blank" rel="noreferrer noopener"> NIS2 and DORA</a>, <a href="https://infinum.com/pci-dss-compliance-guide/" target="_blank" rel="noreferrer noopener">PCI DSS</a>, ISO/IEC 27001, or requirements imposed by a customer.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-956"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-954">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-955'
	>
	The three are not parallel tracks – they form a loop. Governance defines how things should work, risk explains why controls are needed, compliance confirms that external expectations are met. Strip any one of them out and the system breaks down.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-959"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-957">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-958'
	>
	<strong>Why GRC matters for business</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-962"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-960">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-961'
	>
	The case for GRC goes well beyond avoiding fines, though the fines alone are significant. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-965"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-963">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-964'
	>
	<li>Under <a href="https://infinum.com/cybersecurity/nis2-compliance-services/" target="_blank" rel="noreferrer noopener">NIS2</a>, essential entities face penalties of up to €10 million or 2% of global turnover. </li><li>Under GDPR, major violations carry fines of up to €20 million or 4% of annual worldwide revenue. </li><li>Failure to comply with the Payment Card Industry Data Security Standard (PCI DSS) can result in suspension of card processing rights for non-compliant organisations. </li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-968"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-966">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-967'
	>
	These aren&#8217;t edge cases – they&#8217;re the baseline exposure for businesses operating in regulated environments.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-971"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-969">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-970'
	>
	But the more durable argument for GRC isn&#8217;t the downside. It&#8217;s the operational benefit.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-976"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-972">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-973'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-974'
	>
	<strong>Organizations with mature GRC programs make better decisions faster. Risk appetite is defined, so teams don&#8217;t have to relitigate every security investment. Compliance obligations are mapped, so the answer to &#8220;do we need to do this?&#8221; is documented rather than guessed. Governance structures are in place, so accountability doesn&#8217;t evaporate when the person who knew something leaves.</strong></p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-975'
	>
	TOM MILLER, HEAD OF ASSURANCE, AMR CYBERSECURITY – PART OF INFINUM</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-979"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-977">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-978'
	>
	There&#8217;s also a commercial dimension. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-982"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-980">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-981'
	>
	Enterprise customers and regulated-sector partners regularly require evidence of security maturity before signing contracts. SOC 2 attestation, ISO/IEC 27001 certification, and documented compliance management systems are increasingly prerequisites rather than differentiators. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-985"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-983">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-984'
	>
	A strong GRC posture opens doors; the absence of one closes them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-988"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-986">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-987'
	>
	<strong>How does risk management work in GRC?</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-991"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-989">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-990'
	>
	Risk management is where most GRC programs begin, and for good reason. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-994"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-992">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-993'
	>
	Without a clear picture of what you&#8217;re protecting and what threatens it, governance produces arbitrary rules and compliance becomes theater.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-997"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-995">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-996'
	>
	<strong>Step one: identify and classify your assets</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1000"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-998">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-999'
	>
	You cannot manage risk to assets you haven&#8217;t mapped. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1003"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1001">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1002'
	>
	Those assets may include customer data, intellectual property, operational systems, physical infrastructure, or vendor relationships. Classification matters because not all assets warrant the same level of protection – and trying to protect everything equally usually means protecting nothing well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1006"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1004">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1005'
	>
	<strong>Step two: understand the threat landscape</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1009"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1007">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1008'
	>
	Different assets face different threats. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1012"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1010">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1011'
	>
	Personal data is targeted for financial gain. Critical infrastructure faces operational disruption. Source code may attract industrial espionage. Understanding the nature of threats – not just their existence – shapes how you assess and respond to them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1015"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1013">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1014'
	>
	<strong>Step three: assess impact and likelihood</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1018"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1016">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1017'
	>
	This is where the risk matrix comes in. Risk is typically evaluated across two dimensions:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1021"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1019">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1020'
	>
	<li><strong>Impact</strong> – how damaging an incident would be, in terms of financial loss, reputational harm, regulatory penalties, or operational disruption</li><li><strong>Likelihood</strong> – how probable it is that the event occurs, given existing controls and the threat environment</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1024"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1022">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1023'
	>
	These are plotted on a matrix, commonly a 5×5 grid, to produce a risk score. The exact numbers are less important than the consistency of the methodology. Organizations that assess risks differently each time they run the exercise produce data that can&#8217;t be compared or trended. Continuous monitoring through defined key risk indicators (KRIs) keeps the picture current between formal review cycles.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1027"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1025">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1026'
	>
	<strong>Step four: decide how to treat the risk</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1030"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1028">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1029'
	>
	Once a risk level is established, the business chooses how to respond. The standard options are:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1033"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1031">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1032'
	>
	<li><strong>Reduce</strong> the risk through controls – security training, technical safeguards, process changes</li><li><strong>Accept</strong> the risk if it falls within the organization&#8217;s risk appetite</li><li><strong>Avoid</strong> the risk by changing or discontinuing the activity that creates it</li><li><strong>Transfer</strong> the risk – through insurance, contracts, or third-party arrangements</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1036"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1034">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1035'
	>
	Controls should be matched to risks specifically. Generic controls applied uniformly are expensive and often ineffective against the actual threats an organization faces. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1039"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1037">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1038'
	>
	For technical risks in particular,<a href="https://infinum.com/cybersecurity/penetration-testing/" target="_blank" rel="noreferrer noopener"> penetration testing</a> is one of the most direct ways to validate whether your controls actually hold up.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1042"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1040">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1041'
	>
	<strong>Risk assessment &amp; management is ongoing, not periodic</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1045"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1043">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1044'
	>
	Threats change. Businesses evolve. Acquisitions, new product lines, cloud migrations, and regulatory changes all shift the risk assessment. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1048"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1046">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1047'
	>
	Most organizations review their full risk register at least annually. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1051"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1049">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1050'
	>
	High-risk areas warrant more frequent reassessment. Assigning clear risk owners – people accountable for monitoring and managing specific risks – is what prevents risks from being noted once and then quietly forgotten.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1054"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1052">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1053'
	>
	<strong>What is governance in a GRC framework?</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1057"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1055">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1056'
	>
	Governance is the operational skeleton of GRC. It translates risk decisions into repeatable practice.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1060"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1058">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1059'
	>
	That includes</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1063"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1061">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1062'
	>
	<li><strong>documented policies</strong> covering data handling, access control, incident response plans, acceptable use, and other security-critical areas</li><li><strong>defined roles</strong> – from senior leadership accountability at board level down to team-level ownership – so that security doesn&#8217;t depend on any single individual</li><li><strong>processes </strong>for reviewing and updating those policies as the business changes</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1066"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1064">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1065'
	>
	One design failure that consistently undermines governance programs: rules that are too strict for people to follow. Overly restrictive policies don&#8217;t eliminate risk – they push it underground. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1069"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1067">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1068'
	>
	Employees find workarounds. Shadow IT proliferates. Data ends up in personal accounts because the approved tools are too slow or too inconvenient.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1071"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1070'
	>
	<strong>Effective governance balances protection with usability. Policies should make it easier to work securely, not harder to work at all.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1074"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1072">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1073'
	>
	Governance frameworks also need scheduled reviews. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1077"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1075">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1076'
	>
	A policy written before your organization moved to cloud infrastructure, onboarded a major enterprise customer, or doubled headcount is likely obsolete in places. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1080"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1078">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1079'
	>
	Incident data, employee feedback, and internal audit results should all feed into governance updates – not sit in a report that nobody reads.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1083"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1081">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1082'
	>
	<strong>What compliance frameworks do businesses need?</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1086"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1084">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1085'
	>
	The answer depends on the industry, the markets served, and the nature of customer relationships. But the typical compliance picture for a modern business covers several layers:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1089"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1087">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1088'
	>
	<li><strong>Legal and regulatory requirements</strong> – data protection laws, cybersecurity regulations, sector-specific legislation (NIS2 and DORA in the EU, for example)</li><li><strong>Industry frameworks</strong> – ISO/IEC 27001, Payment Card Industry Data Security Standard (<a href="https://infinum.com/cybersecurity/pci-dss-compliance-services/" target="_blank" rel="noreferrer noopener">PCI DSS</a>), SOC 2, NIST, CIS Controls</li><li><strong>Regional data protection regulations</strong> – the General Data Protection Regulation (GDPR) for organizations handling EU personal data; the California Consumer Privacy Act (CCPA) for those serving US consumers; the Health Insurance Portability and Accountability Act (HIPAA) for healthcare; the Sarbanes-Oxley Act (SOX) for US-listed companies</li><li><strong>Anti-corruption and financial crime frameworks</strong> – the Foreign Corrupt Practices Act (FCPA), the UK Bribery Act, and EU Money Laundering Directives for relevant sectors</li><li><strong>Contractual obligations</strong> – security requirements imposed by enterprise customers or partners, often as conditions of doing business</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1092"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1090">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1091'
	>
	It&#8217;s important to note that these often overlap. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1095"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1093">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1094'
	>
	A financial services company serving EU customers may simultaneously need to comply with DORA, NIS2, GDPR, and the security requirements of its largest institutional clients. GRC provides the structure to manage these demands coherently rather than spinning up separate workstreams for each.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1098"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1096">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1097'
	>
	<strong>What is outcome-based regulation?</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1099">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1100'
	>
	A significant portion of modern compliance frameworks – including NIS2 and many data protection regimes – define outcomes rather than prescribing specific security controls. They tell you what you need to achieve, not exactly how to achieve it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1102">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1103'
	>
	This creates flexibility. It also creates interpretation work. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1105">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1106'
	>
	&#8220;Implement appropriate technical and organizational measures&#8221; means different things for a 20-person SaaS company and a multinational bank. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1108">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1109'
	>
	Understanding your specific risk profile, business context, and the regulator&#8217;s expectations for your sector is what makes outcome-based regulatory compliance meaningful rather than aspirational.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1111">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1112'
	>
	<strong>Compliance is itself a risk decision</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1114">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1115'
	>
	Not every framework that exists is mandatory for your organization. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1117">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1118'
	>
	Some are legally required. Others are commercially beneficial – certain enterprise customers won&#8217;t sign contracts with vendors who can&#8217;t demonstrate ISO/IEC 27001 certification, for example. Others are optional but signal maturity to the market.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1120">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1121'
	>
	Deciding which standards to pursue should follow the same logic as any risk assessment follow-up decision: what are the obligations, what is the business value, and what does it cost?</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1135"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-1134">
	
<div class="block-column" data-id="es-1133">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1132"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-1131">
	
<div class="block-grid-item" data-id="es-1130">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-1125"
	 href='https://infinum.com/blog/cybersecurity-trends-2026/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-1126'
	>
	<strong>For an up-to-date view of which regulatory obligations are currently driving the most change, our 2026 cybersecurity trends piece is a useful companion read.</strong></div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-1127"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-1128'
	>
	Learn more here</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-1129'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-1158"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1136">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1137">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1138'
	>
	<strong>Culture, metrics, and the feedback loop</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1142"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1140">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1141'
	>
	GRC doesn&#8217;t run on documents alone. It runs on people.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1143'
	>
	Security training participation rates, phishing simulation results, system patching cadence, and incident trends are all metrics that reveal how the governance framework is performing in practice – not just on paper. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1145">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1146'
	>
	Organizations that track these consistently identify weaknesses before they become incidents. Regular training sessions and awareness programs matter here not as regulatory compliance checkboxes, but as data sources: if phishing click rates don&#8217;t move after repeated training rounds, the training isn&#8217;t working.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1148">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1149'
	>
	The other half of this is incident reporting culture. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1153"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1151">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1152'
	>
	Employees need to feel safe raising concerns, reporting mistakes, and escalating near misses. Blame discourages reporting. Underreporting makes risk data unreliable and leaves the same vulnerabilities recurring across incidents that could have been connected.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1156"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1154">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1155'
	>
	Every incident that gets reported and analyzed is a direct feed into the risk register, the governance framework, and the next training cycle &#8211; that feedback loop is what makes GRC a living system rather than a compliance filing exercise.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1169"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-1168">
	
<div class="block-column" data-id="es-1167">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1166"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-1165">
	
<div class="block-grid-item" data-id="es-1164">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-1159"
	 href='https://infinum.com/blog/ssdlc-application-security/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-1160'
	>
	If your organization builds software, embedding security into the development lifecycle is where that loop starts – here&#8217;s how to make that shift.</div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-1161"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-1162'
	>
	Explore SSDLC</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-1163'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-1194"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1170">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1171">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1172'
	>
	<strong>GRC tools: what actually matters</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1174">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1175'
	>
	The market for GRC platforms – compliance management systems, risk registers, policy libraries, audit tracking tools – is large and varied, ranging from enterprise-grade systems with automated controls mapping and real-time dashboards to simpler internal documentation and spreadsheet-based approaches.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1177'
	>
	Sophisticated tooling can be valuable – but only if it&#8217;s properly configured, actively maintained, and matched to organizational maturity. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1179">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1180'
	>
	A platform that requires significant customization and ongoing administration may create more overhead than it removes for a smaller organization.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1186"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1182">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1183'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-1184'
	>
	What matters is not the sophistication of the tool but the quality of the thinking behind it. A GRC spreadsheet used rigorously beats an enterprise platform treated as a checkbox.</p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1185'
	>
	TOM MILLER, HEAD OF ASSURANCE, AMR CYBERSECURITY &#8211; PART OF INFINUM</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1189"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1187">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1188'
	>
	<a href="https://infinum.com/enterprise-cyber-risk-management/" id="19275077">Vendor risk management</a> deserves specific attention. Every supplier introduced into your environment extends your attack surface, and that includes cloud providers, managed service providers, software vendors, and any third party with access to your systems or data. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1190">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1191'
	>
	Trust should be verified through due diligence, not assumed. When evaluating vendors, prioritize demonstrated experience, relevant credentials, and a clear approach to their own GRC.</p></div>	</div>


</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1205"
	 data-animation-target='inner-items'>
		
			<div class="block-columns" data-id="es-1204">
	
<div class="block-column" data-id="es-1203">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1202"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="grid block-grid__grid" data-id="es-1201">
	
<div class="block-grid-item" data-id="es-1200">
	
<a	class="card-simple js-card-simple block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-1195"
	 href='https://infinum.com/blog/software-supply-chain-security/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<div	class='typography typography--size-24-text js-typography card-simple__heading'
	data-id='es-1196'
	>
	<strong>For a practical framework on how to assess and manage that exposure, our guide to software supply chain security</strong> <strong>covers it step by step.</strong></div>		</div>

		<button	class="btn btn--color-infinum btn--size-medium btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-1197"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-1198'
	>
	Learn more here</div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-1199'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>
</div>
</div>	</div>
</div>
</div>	</div>

<div
	class="wrapper"
	data-id="es-1265"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1206">
	</div>

<div class="block-blog-content-main">
	


<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1209"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1207">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1208'
	>
	<strong>How to build a GRC framework: where to start</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1212"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1210">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1211'
	>
	The most common mistake when building a GRC program is starting with the tools or the compliance checklist rather than the risk picture. The sequence matters.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1213">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-1214'
	>
	<strong>Start with an honest assessment of where you are.</strong> </h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1218"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1216">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1217'
	>
	Map your assets, identify your regulatory obligations, and evaluate whether your current governance structures and compliance programs are actually functioning or just documented. Gaps between what the policies say and what teams do are the most important findings at this stage.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1221"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1219">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-1220'
	>
	<strong>Define your risk appetite.</strong> </h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1224"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1222">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1223'
	>
	Senior leadership needs to agree – explicitly, on paper – on how much risk the organization is willing to accept in different areas. Without that anchor, every risk treatment decision becomes a negotiation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1227"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1225">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-1226'
	>
	<strong>Prioritize by impact.</strong> </h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1230"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1228">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1229'
	>
	You cannot fix everything at once. Address the highest-risk areas first, assign owners, and set measurable targets. A chief compliance officer or equivalent role provides the continuity needed to drive this process – someone whose job it is to track progress across the organization, not just within a single team.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1233"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1231">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-1232'
	>
	<strong>Build compliance management into operations, not alongside them.</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1236"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1234">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1235'
	>
	Compliance programs that exist in parallel to how work actually gets done produce documentation and little else. The goal is to integrate compliance requirements into everyday workflows so that adherence is the path of least resistance, not an additional burden.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1239"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1237">
	<h3	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-1238'
	>
	<strong>Review regularly.</strong> </h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1240">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1241'
	>
	A GRC program that isn&#8217;t updated is a liability. Set a cadence for risk register reviews, policy updates, and internal audit cycles. The specific intervals matter less than committing to them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1245"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1243">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1244'
	>
	<strong>Why GRC builds business trust</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1248"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1246">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1247'
	>
	The organizations that handle security incidents badly are rarely those with the weakest technical controls. They&#8217;re often the ones that didn&#8217;t know what they were protecting, couldn&#8217;t communicate clearly with stakeholders, or had no documented process for responding.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1249">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1250'
	>
	GRC addresses all of that. It forces honest conversations about risk that many organizations avoid until something goes wrong. It creates accountability at the leadership level. And it produces the documentation and evidence that regulators, customers, and partners increasingly expect as a baseline condition of doing business.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1252">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1253'
	>
	No organization eliminates risk entirely. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1255">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1256'
	>
	What GRC provides is something more practical: the ability to understand it, manage it deliberately, and learn from it when things don&#8217;t go according to plan.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1260"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1258">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1259'
	>
	<em>Security decisions made without a governance and risk foundation tend to be reactive, inconsistent, and hard to justify when things go wrong. </em></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1261">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1262'
	>
	<em>Infinum&#8217;s security practice helps organizations build GRC frameworks that work in the real world – connected to business goals, not just compliance checklists.</em><a href="https://infinum.com/cybersecurity/" id="https://infinum.com/cybersecurity/"><em> Explore our cybersecurity services</em></a><em> to see where we can help.</em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/what-is-grc/">What Is GRC? Governance, Risk, and Compliance Explained</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19278544https://infinum.com/uploads/2026/04/img-hero-selfhosting-llm.webp</url>
				</image>
				<title>Self-Hosting AI Models: A Practical Guide to Building Your Own Stack</title>
				<link>https://infinum.com/blog/self-hosting-ai-models-a-practical-guide/</link>
				<pubDate>Thu, 16 Apr 2026 16:16:50 +0000</pubDate>
				<dc:creator>Vjekoslav Drakšić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19278544</guid>
				<description>
					<![CDATA[<p>Infrastructure decisions, model selection tradeoffs, and performance optimization techniques we encountered while building a self-hosted multi-model inference stack. </p>
<p>The post <a href="https://infinum.com/blog/self-hosting-ai-models-a-practical-guide/">Self-Hosting AI Models: A Practical Guide to Building Your Own Stack</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1467"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1266">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1269"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1267">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1268'
	>
	Many organizations now want full ownership of their <a href="https://infinum.com/artificial-intelligence/" id="https://infinum.com/artificial-intelligence/">AI infrastructure</a>. The motivation for self-hosting ranges from data ownership requirements and contractual obligations to maintaining the highest level of system security.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1270">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1271'
	>
	This post covers the infrastructure decisions, model selection tradeoffs, and performance optimization techniques we encountered while building a self-hosted multi-model inference stack. <a href="https://infinum.com/blog/ai-generated-code-security-risks/" id="https://infinum.com/blog/ai-generated-code-security-risks/">Security architecture</a> and model licensing are out of scope here as both deserve their own deep dives. Still, everything about building the infrastructure and making it perform is fair game.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1275"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1273">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1274'
	>
	Here&#8217;s what our stack looked like:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1278"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1276">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1277'
	>
	<li>An open-source inference engine (<a href="https://github.com/vllm-project/production-stack">vLLM production stack</a>)</li><li>A multi open-weight model setup</li><li>Accelerated computing instances on AWS</li><li>A scalable, highly available EKS cluster</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1281"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1279">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1280'
	>
	vLLM as an inference engine</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1284"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1282">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1283'
	>
	There are several open-source inference engines to choose from, including <a href="https://github.com/InternLM/lmdeploy">LMDeploy</a>, <a href="https://github.com/sgl-project/sglang">SGLang</a>, and <a href="https://github.com/NVIDIA/TensorRT-LLM">TensorRT-LLM</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1287"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1285">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1286'
	>
	We chose vLLM for its performance, <a href="https://docs.vllm.ai/en/latest/models/supported_models/">broad model support</a>, <a href="https://docs.vllm.ai/en/latest/">extensive documentation</a>, and built-in multi-model type routing. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1290"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1288">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1289'
	>
	Their production stack ships with an infrastructure diagram you can extend for your own setup, but the core components are:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1294"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1291">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1292'
	>
	<strong>Request router</strong></p><p	class='typography typography--size-18-text-roman js-typography bullet__paragraph'
	data-id='es-1293'
	>
	An OpenAI-compatible API layer. It uses prefix-aware routing to direct repeat context to the same worker, reducing time to first token. In a multi-model setup, the router handles requests by endpoint, model name, and worker assignment.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1295">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1296'
	>
	<strong>Workers</strong></p><p	class='typography typography--size-18-text-roman js-typography bullet__paragraph'
	data-id='es-1297'
	>
	vLLM instances running on GPU nodes. The stack handles tensor parallelism across multiple GPUs for large models out of the box.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1302"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1299">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1300'
	>
	<strong>KV cache storage</strong></p><p	class='typography typography--size-18-text-roman js-typography bullet__paragraph'
	data-id='es-1301'
	>
	In a multi-worker setup, previously computed state is retrieved from <a href="https://docs.lmcache.ai/">LMCache</a>, which delivers significant performance gains, especially for models like <a href="https://blog.lmcache.ai/en/2025/08/05/lmcache-supports-gpt-oss-20b-120b-on-day-1/">GPT OSS</a>.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1306"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1303">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1304'
	>
	<strong>Observability stack</strong></p><p	class='typography typography--size-18-text-roman js-typography bullet__paragraph'
	data-id='es-1305'
	>
	Prometheus and Grafana for monitoring.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1309"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1307">
	<h3	class='typography typography--size-30-text js-typography block-typography__typography'
	data-id='es-1308'
	>
	Simplified end-to-end flow</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1312"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1310">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1311'
	>
	The request router analyzes the incoming prompt&#8217;s prefix and directs it to a worker that already holds that context in memory. The worker processes the request with optimized block-based memory management, pulling previously computed states from a per-node or cluster-wide cache, and generates the response.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1315"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1313">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1314'
	>
	Choosing the right hosting environment</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1318"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1316">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1317'
	>
	The AI hosting landscape is competitive. The vLLM production stack has <a href="https://github.com/vllm-project/production-stack/tree/main/deployment_on_cloud">cloud deployment support</a> for AWS, Azure, and GCP, and project velocity matters a lot at this stage.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1321"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1319">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1320'
	>
	This is why we chose AWS EKS. The cost savings from alternative providers did not justify the increased setup complexity.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1324"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1322">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1323'
	>
	Specialty cloud hosting providers are cheaper, but they often offer unmanaged environments. That means you handle all the heavy lifting yourself, like networking, orchestration, GPU scheduling, the lot.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1327"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1325">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1326'
	>
	On-premise considerations</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1330"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1328">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1329'
	>
	Buying hardware immediately is an operational risk. This is true even if you have predictable workloads.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1333"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1331">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1332'
	>
	<strong>We recommend a phased approach:</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1337"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1334">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<h4	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1335'
	>
	<strong>Phase 1: Model PoC</strong></h4><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1336'
	>
	Optional if you already know the model you want. Use managed services like AWS Bedrock to find the sweet spot between model size and reasoning capability. The open-weight model catalogue is expanding fast and the setup is minimal.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1339"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<hr
	class="block-divider"
	data-id="es-1338"
	aria-hidden="true" />	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1343"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1340">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<h4	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1341'
	>
	<strong>Phase 2: Cloud PoC</strong></h4><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1342'
	>
	Use cloud-managed Kubernetes to prototype your multi-model infrastructure. Test different GPU offerings, benchmark your setup, and figure out your TPM and RPM requirements. Test your open-source model choices without locking into expensive hardware early.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1345"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<hr
	class="block-divider"
	data-id="es-1344"
	aria-hidden="true" />	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1349"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--black block-bullet__bullet" data-id="es-1346">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<h4	class='typography typography--size-24-text js-typography bullet__heading'
	data-id='es-1347'
	>
	<strong>Phase 3: On-premise refinement</strong></h4><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-1348'
	>
	Once you understand your patterns and limits, modify your existing Kubernetes cluster for an on-premise deployment. This is significantly easier than starting here from scratch.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1352"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1350">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1351'
	>
	Choosing the right model</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1355"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1353">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1354'
	>
	To simplify the equation: the two factors that drive infrastructure cost are <strong>model size</strong> (parameter count) and <strong>model context</strong> (the active memory window containing your conversation and retrieved data).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1358"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1356">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1357'
	>
	The LLM is your main challenge. Embedding and reranking models require comparatively little GPU power.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1361"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1359">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1360'
	>
	Here are three scenarios to illustrate the range. Note that these are rough on-demand estimates, and be sure to check current pricing and consider reserved or spot instances where applicable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1364"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1362">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1363'
	>
	Small: chatbot with basic interactions</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1367"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1365">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1366'
	>
	Customer support, simple Q&amp;A. No complex reasoning or large context required.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1370"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1368">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1369'
	>
	<li><strong>Size:</strong> 7B or 8B parameters</li><li><strong>Context:</strong> 2k–20k tokens</li><li><strong>OSS models:</strong> Llama 3 (8B), Mistral (7B), Qwen (7B)</li><li><strong>Proprietary use case equivalents:</strong> GPT-4o-mini, Claude Haiku, Gemini Flash-Lite</li><li><strong>Infrastructure:</strong> A single G6e family instance</li><li><strong>Monthly cost:</strong> ~$400–$600</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1372"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<hr
	class="block-divider"
	data-id="es-1371"
	aria-hidden="true" />	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1375"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1373">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1374'
	>
	Medium: reasoning over a knowledge base</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1378"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1376">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1377'
	>
	Internal knowledge bases where the model reads retrieved company documents, follows strict instructions, and needs to minimize hallucinations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1381"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1379">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1380'
	>
	<li><strong>Size:</strong> 70B parameters</li><li><strong>Context:</strong> 20k–50k tokens</li><li><strong>OSS models:</strong> Llama 3 (70B), Mixtral (8x7B), Qwen (72B), GPT-OSS-20B</li><li><strong>Proprietary use case equivalents:</strong> Claude Sonnet, Gemini Flash</li><li><strong>Infrastructure:</strong> Multi-GPU setup</li><li><strong>Monthly cost:</strong> ~$3k–$8k</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1383"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<hr
	class="block-divider"
	data-id="es-1382"
	aria-hidden="true" />	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1386"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1384">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1385'
	>
	Large: high accuracy, high reasoning, high context</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1389"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1387">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1388'
	>
	Complex code refactoring, massive document analysis, predictions, and advanced agents. Maximum accuracy and minimal hallucinations are non-negotiable.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1392"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1390">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1391'
	>
	<li><strong>Size:</strong> 100B+ parameters</li><li><strong>Context:</strong> 50k+ tokens</li><li><strong>OSS models:</strong> GPT-OSS-120B, DeepSeek-R1, Mistral Large 3</li><li><strong>Proprietary use case equivalents:</strong> GPT-5, Claude Opus, Gemini Pro</li><li><strong>Infrastructure:</strong> p5e.48xlarge instances (8×H200)</li><li><strong>Monthly cost:</strong> ~$30k+</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1395"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1393">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1394'
	>
	<strong>These are rough single-environment estimates.</strong> Multi-environment, highly available enterprise setups multiply these figures quickly.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1398"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1396">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1397'
	>
	Benchmarking your setup</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1401"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1399">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1400'
	>
	Although there are fast general benchmarking tools available, like <a href="https://github.com/AlexsJones/llmfit">LLMfit</a>, you should measure model performance in your own environment. This also reveals hardware traps that generic benchmarks won&#8217;t surface.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1404"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1402">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1403'
	>
	For example, adding more L40S GPUs may not increase performance. These GPUs communicate over the PCIe bus instead of NVLink, and the communication overhead can cancel out the compute gains.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1407"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1405">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1406'
	>
	vLLM has a native benchmarking option via the <a href="https://docs.vllm.ai/en/latest/cli/bench/serve/">bench serve</a> command. The key metrics to watch:</p></div>	</div>

<div
	class="wrapper"
	data-id="es-1408"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table"><table><thead><tr><th>Metric</th><th>Meaning</th></tr></thead><tbody><tr><td><strong>Median TTFT</strong> (Time to First Token)</td><td>How long from prompt submission to the first generated token. The user&#8217;s perceived responsiveness.</td></tr><tr><td><strong>Median TPOT</strong> (Time Per Output Token)</td><td>How long each subsequent token takes to generate.</td></tr><tr><td><strong>Median ITL</strong> (Inter-Token Latency)</td><td>The gap between consecutive tokens. Smoothness of streaming output.</td></tr><tr><td><strong>Output token throughput</strong></td><td>Tokens generated per second across all concurrent users.</td></tr><tr><td><strong>Total token throughput</strong></td><td>Combined rate for both prompt processing and generation.</td></tr><tr><td><strong>Request throughput</strong></td><td>Complete requests resolved per second.</td></tr><tr><td><strong>Max request concurrency</strong></td><td>Peak number of simultaneous requests handled during the test.</td></tr></tbody></table></figure>
		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1411"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1409">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1410'
	>
	Optimization techniques</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1414"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1412">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1413'
	>
	There is extensive documentation on optimization techniques. Here&#8217;s a summary of those that made the biggest difference for us.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1417"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1415">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1416'
	>
	<a href="https://docs.vllm.ai/en/latest/features/quantization/">Quantization</a></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1420"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1418">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1419'
	>
	Reduces weight precision (e.g., from 16-bit to 8-bit or 4-bit) to shrink the model&#8217;s memory footprint. This has a direct impact on what model you can fit on your available hardware.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1423"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1421">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1422'
	>
	<a href="https://docs.vllm.ai/en/latest/features/automatic_prefix_caching/#introduction">Automatic prefix caching</a></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1426"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1424">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1425'
	>
	Worker/Node level memory management. Caches the KV state of existing queries. If you&#8217;re querying the same long document multiple times, the document is processed once and subsequent queries pull from cache. The result is higher throughput and lower latency.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1429"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1427">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1428'
	>
	Distributed caching via <a href="https://lmcache.ai/">LMCache</a></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1432"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1430">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1431'
	>
	Automatic prefix caching is limited to a single worker&#8217;s GPU VRAM — extremely fast, but expensive. LMCache enables cluster-wide offloading to cheaper storage (CPU memory, disk, or Redis) at the cost of some latency. Use both in a tiered memory hierarchy for the best balance.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1435"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1433">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1434'
	>
	<a href="https://docs.vllm.ai/en/stable/serving/parallelism_scaling/">Tensor parallelism</a></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1438"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1436">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1437'
	>
	Workload distribution. Splits tensors across multiple GPUs. Effectively a requirement for larger models. Performance depends heavily on fast interconnects like NVLink.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1441"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1439">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1440'
	>
	<a href="https://docs.vllm.ai/en/latest/features/speculative_decoding/">Speculative decoding</a></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1444"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1442">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1443'
	>
	There are multiple methods. One approach pairs a large model with a tiny, fast model. The fast model guesses the next tokens, and the large model verifies them in a single pass. This multiplies token generation speed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1447"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1445">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1446'
	>
	<a href="https://docs.vllm.ai/en/latest/features/disagg_prefill/">Disaggregated prefilling</a></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1450"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1448">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1449'
	>
	Separates the prefill and decode stages onto different GPUs or nodes. Since the two tasks have different computational profiles (compute-bound vs. memory-bandwidth-bound), you can scale each independently — either to improve responsiveness or to prevent long prompts from stalling active generation.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1453"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1451">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1452'
	>
	What&#8217;s ahead for self-hosting</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1456"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1454">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1455'
	>
	There will always be demand for on-premise self-hosted AI in systems that require maximum control over their data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1459"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1457">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1458'
	>
	The barrier to entry is dropping. Inference engines are maturing, optimization techniques are compounding, and models are getting better with fewer parameters and lower VRAM requirements. The recent Gemma 4 release is a good example: judging by the benchmarks, it delivers strong performance for a modest hardware investment. Stay tuned for a deep dive on that one.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1462"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1460">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1461'
	>
	In conclusion, enterprise-grade self-hosting remains<strong> expensive, but the trajectory is clear: organizations will be able to do significantly more with <a href="https://ai.google.dev/gemma/docs/core">significantly less hardware</a>.</strong> </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1465"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1463">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1464'
	>
	The phased approach we outlined here is designed to let you start proving value now, without committing to infrastructure you don&#8217;t yet understand.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/self-hosting-ai-models-a-practical-guide/">Self-Hosting AI Models: A Practical Guide to Building Your Own Stack</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19277485https://infinum.com/uploads/2026/03/data-to-decisions-hero.webp</url>
				</image>
				<title>From Data to Decisions: How AI-Driven Knowledge Hubs Are Decoding Enterprise Complexity</title>
				<link>https://infinum.com/blog/ai-knowledge-hubs/</link>
				<pubDate>Wed, 08 Apr 2026 09:56:17 +0000</pubDate>
				<dc:creator>Joseph Eric Rosenthal</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19277485</guid>
				<description>
					<![CDATA[<p>Discover how we've helped clients across industries turn raw data into actionable insights with AI-powered knowledge hubs.</p>
<p>The post <a href="https://infinum.com/blog/ai-knowledge-hubs/">From Data to Decisions: How AI-Driven Knowledge Hubs Are Decoding Enterprise Complexity</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1541"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1468">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1471"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1469">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1470'
	>
	An AI-driven Knowledge Hub is an intelligent system that acts as an organization&#8217;s &#8216;internal GPT&#8217;, turning raw,<strong> scattered data into actionable insights through a chat interface. We&#8217;ve delivered them across industries to solve real business problems for our clients. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1474"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1472">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1473'
	>
	The modern enterprise is built on vast amounts of data, yet turning that data into actionable insights remains one of the most persistent and costly <a href="https://infinum.com/blog/ai-strategy/" id="https://infinum.com/blog/ai-strategy/">challenges organizations face</a>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1477"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1475">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1476'
	>
	At Infinum, we&#8217;ve worked with clients across industries to bridge this gap by developing AI-powered Knowledge Hubs: centralized, intelligent repositories that aggregate and analyze your organization&#8217;s data and surface new insights through a seamless chat interface. Think of them as an <a href="https://infinum.com/blog/model-context-protocols-mcp-ai-enabled-businesses/" id="https://infinum.com/blog/model-context-protocols-mcp-ai-enabled-businesses/">internal GPT</a> — one that knows your business, speaks your language, and has access to everything your teams need to make faster, more confident decisions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1480"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1478">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1479'
	>
	From streamlining complex workflows for insurance firms to centralizing intelligence for global tech companies and premier fitness networks, these knowledge hubs are the connective tissue between big data and better decision-making. Here are a few examples of the work we’ve done to harness the power of data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1483"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1481">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1482'
	>
	Helping insurance professionals cut through the noise of data</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1486"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1484">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1485'
	>
	Risk is at the heart of every decision insurance professionals make. Underwriters navigate enormous volumes of data, claims history, actuarial tables, regulatory changes, weather events, market trends, competitor pricing, and their ability to accurately assess and price that risk directly impacts the business. The problem is that this data is rarely in one place, and pulling it together manually is slow, error-prone, and expensive.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1489"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1487">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1488'
	>
	We built an <strong>insurance intelligence solution</strong> that combines <a href="https://infinum.com/artificial-intelligence/data-engineering/" id="https://infinum.com/artificial-intelligence/data-engineering/">data engineering</a>, risk modeling, and competitor and market data to support underwriting and risk assessment decisions. The system gathers claims data, actuarial tables, regulatory filings, and publicly available sources, and makes all of it accessible through a conversational chatbot. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1491"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1490'
	>
	An underwriter can ask: &#8220;Based on recent flooding events in Germany and current claims history in the region, should I adjust the premium for a commercial property policy renewal in Frankfurt, and if so, by how much?&#8221; and get a data-backed recommendation in seconds.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1494"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1492">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1493'
	>
	The star feature is source citation. Every recommendation comes with a reference to the underlying data used to generate it. This significantly reduces the <a href="https://infinum.com/blog/ai-chatbot-development-pain-points/" id="https://infinum.com/blog/ai-chatbot-development-pain-points/">risk of AI hallucination</a>, which is especially critical in heavily regulated sectors like insurance, where decisions are subject to strict auditing and compliance requirements.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1497"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1495">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1496'
	>
	Streamlining the flow of information for a global tech leader</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1500"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1498">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1499'
	>
	Decision-makers at global tech companies are bombarded with news from every direction, but most of it isn&#8217;t relevant to their business. The real challenge is isolating the specific tech, environmental, and geopolitical shifts that actually impact their operations. For our client, the manual effort required to monitor these risks was leading to delayed reactions and missed opportunities. So we built <strong>an</strong> <strong>internal knowledge hub</strong> that turns that flood of global content into focused, actionable intelligence, using<a href="https://infinum.com/blog/scaling-ai-with-databricks/" id="https://infinum.com/blog/scaling-ai-with-databricks/"> advanced data engineering and custom API integrations</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1503"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1501">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1502'
	>
	Rather than handing leadership a pile of raw articles, the system distills complex global events into concise daily and weekly briefs, filtered by pre-defined criteria unique to the client&#8217;s industry. Every brief that lands is directly relevant to the company&#8217;s long-term strategic goals and risk management.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1506"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1504">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1505'
	>
	A distinct advantage of this hub is its multi-dimensional filtering logic. By applying pre-defined criteria unique to the client’s industry, the system eliminates &#8216;noise&#8217; and ensures that every brief delivered is directly relevant to the company&#8217;s long-term strategic goals and risk management. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1509"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1507">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1508'
	>
	<strong>Business intelligence platform for a premium fitness brand</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1512"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1510">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1511'
	>
	Despite having large volumes of operational and financial data, teams across fitness clubs struggled with hard-to-use systems, missing metrics, and fragmented reporting. This made it difficult to get a clear picture of performance, align teams, and make timely, data-driven decisions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1515"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1513">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1514'
	>
	We designed and built <strong>a centralized BI platform</strong> that integrates data from across the organization into a single, intuitive interface. By combining robust data modeling with user-centered design, the platform turns complex data into accessible, actionable insights for everyone – from frontline staff to executives.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1518"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1516">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1517'
	>
	<li><strong>We enabled real-time visibility across the business. </strong>With data refreshing multiple times per day, stakeholders can monitor revenue, membership trends, class utilization, and operational metrics in near real time, allowing for faster, more informed decisions.</li><li><strong><strong>The interface is designed for interactive data exploration</strong>. </strong>Users can move from high-level overviews to detailed drill-downs, compare performance over time, and quickly identify patterns through clear visualizations and consistent data cues.</li><li><strong>AI-generated summaries make complex data easy to understand. </strong>A layer of Microsoft AI translates complex data into plain-language summaries, surfacing key trends and insights automatically and making analytics accessible to non-technical users.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1521"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple__content-align--left"
	data-id="es-1519"
	>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<p	class='typography typography--size-36-text js-typography card-simple__heading'
	data-id='es-1520'
	>
	Want a behind-the-scenes look at how we built the platform and what it looks like in action? Read the <a href="https://infinum.com/work/midtown-business-intelligence-platform/" id="https://infinum.com/work/midtown-business-intelligence-platform/" target="_blank" rel="noreferrer noopener">Midtown BI platform case study</a>.</p>		</div>

			</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1524"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1522">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1523'
	>
	Turning &#8216;hidden&#8217; email data into a tool for cost reduction</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1527"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1525">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1526'
	>
	Procurement teams are often buried under a lot of unstructured data, RFQs, and vendor price lists trapped in email threads and PDF attachments. Without a way to aggregate this data, it is impossible to compare vendor performance, track price volatility, or identify cost-saving opportunities in real-time. Manual data entry is slow, prone to error, and prevents strategic decision-making.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1530"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1528">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1529'
	>
	We built a sophisticated <strong>procurement automation solution</strong> that bridges the gap between raw communication and executive-ready analysis. Using Azure Document Intelligence, the system reads incoming vendor emails and complex attachments, automatically extracting and structuring critical data points. An Automated Extraction Layer then identifies and categorizes that data by vendor, product, and price, storing it in a high-performance structured database. This replaces manual tracking with a real-time repository of market intelligence.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1533"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1531">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1532'
	>
	From there, the platform performs deep-dive analyses, including vendor valuation and historical price benchmarking, and surfaces them through custom dashboards for real-time decision-making. Procurement teams walk into negotiations backed by data instead of gut feel, turning what was once hidden in an inbox into a genuine competitive advantage.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1536"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1534">
	<h2	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1535'
	>
	<strong>The transition from </strong>&#8216;<strong>data-rich&#8217; to &#8216;insight-driven&#8217; is no longer a luxur</strong>y</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1539"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1537">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1538'
	>
	As demonstrated across the insurance, tech, consulting, and fitness sectors, the challenge was never a lack of data. The organizations we worked with were sitting on everything they needed. They just couldn&#8217;t find it, validate it, or act on it fast enough. An AI-powered Knowledge Hub closes that gap. The right answer stops being buried in a database and becomes one question away. At Infinum, we don’t just build interfaces. We build the cognitive infrastructure that allows your team to stop searching and start leading. If that sounds like something your organization needs, <a href="https://infinum.com/artificial-intelligence/" id="https://infinum.com/artificial-intelligence/" target="_blank" rel="noreferrer noopener">check out what we can do</a>.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/ai-knowledge-hubs/">From Data to Decisions: How AI-Driven Knowledge Hubs Are Decoding Enterprise Complexity</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19277675https://infinum.com/uploads/2026/04/pen-vs-red.webp</url>
				</image>
				<title>Pen Testing, Red Teaming, and Why No Scanner Can Replace Either</title>
				<link>https://infinum.com/blog/pen-testing-red-teaming/</link>
				<pubDate>Wed, 01 Apr 2026 14:02:28 +0000</pubDate>
				<dc:creator>Sean McCarthy</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19277675</guid>
				<description>
					<![CDATA[<p>Pen testing and red teaming are often used interchangeably. They're not. Here's what each actually does, when you need which, and why automated scanners can't replace either.</p>
<p>The post <a href="https://infinum.com/blog/pen-testing-red-teaming/">Pen Testing, Red Teaming, and Why No Scanner Can Replace Either</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[

<div
	class="wrapper"
	data-id="es-1667"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1542">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1545"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1543">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1544'
	>
	<strong>Pen testing and red teaming are often used interchangeably. Both probe your defences. Both find what&#8217;s broken. But they ask fundamentally different questions, and the one you choose shapes how wide you assess your business security.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1548"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1546">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1547'
	>
	<a href="https://infinum.com/cybersecurity/penetration-testing/" id="https://infinum.com/cybersecurity/penetration-testing/" target="_blank" rel="noreferrer noopener">Penetration testing</a> and <a href="https://infinum.com/cybersecurity/red-teaming/" target="_blank" rel="noreferrer noopener">red teaming</a> both start from the same premise: hire someone to break in before the bad guys do. But they&#8217;re different tools for different problems, and conflating them is one of the more common mistakes organisations make.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1551"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1549">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1550'
	>
	Two approaches, similar goal</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1554"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1552">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1553'
	>
	Penetration testing is focused. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1557"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1555">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1556'
	>
	You define the scope – a specific application, a network segment, a set of systems – and testers use the <a href="https://infinum.com/blog/penetration-testing-steps/" target="_blank" rel="noreferrer noopener">penetration testing methodology step by step</a> in an attempt to find and exploit vulnerabilities within it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1560"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1558">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1559'
	>
	Most engagements use a gray box approach: testers are given enough context to work efficiently. Credentials, access, scope. Enough to find what matters within a fixed timeframe.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1562"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1561'
	>
	<strong>Red teaming is the opposite of narrow. It&#8217;s intelligence-led and scenario-driven, built to simulate a sophisticated adversary targeting your organisation specifically. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1565"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1563">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1564'
	>
	The approach changes depending on who you are – <a href="https://infinum.com/red-team-services/" id="https://infinum.com/red-team-services/">a red team</a> targeting a bank crafts different phishing emails, chooses different attack vectors, and pursues different objectives than one targeting a logistics company. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1568"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1566">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1567'
	>
	The whole exercise is shaped by what real threat actors are actually doing to organisations like yours.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1571"
	 data-animation-target='inner-items'>
		
			<div class="block-group" data-id=es-1570>
	
<div
	class="wrapper"
	data-id="es-1569"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table is-style-first-column-strong"><table class="has-fixed-layout"><thead><tr><th>Pen testing</th><th><strong>Red teaming</strong></th></tr></thead><tbody><tr><td>Narrow, system-focused scope</td><td><strong>Whole-organisation scope</strong></td></tr><tr><td>Often gray box by default</td><td><strong>Intelligence-led, scenario-based</strong></td></tr><tr><td>Time-boxed engagement</td><td><strong>Simulates a real, tailored adversary</strong></td></tr><tr><td>Finds specific technical vulnerabilities</td><td><strong>Tests people, process, technology</strong></td></tr></tbody></table></figure>
		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1574"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1572">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1573'
	>
	Penetration Testing vs Red Teaming: Key Differences</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1577"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1575">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1576'
	>
	The simplest way to tell them apart: pen testing answers &#8220;is this system secure?&#8221;, red teaming answers &#8220;could a determined attacker get into our organisation?&#8221;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1580"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1578">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1579'
	>
	Scope is the biggest practical difference. Pen testing is bounded — a specific application, network segment, or set of APIs. The tester works within those limits, finds what&#8217;s exploitable, and reports it. Red teaming has no such boundary. The adversary simulation can move across applications, people, and physical premises, using whatever combination of vectors a real attacker would.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1583"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1581">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1582'
	>
	The objectives differ, too. Pen testing produces a list of technical vulnerabilities with severity ratings and remediation steps. Red teaming produces something more like a case study: here is how an attacker targeting your organisation could move from initial access to their end goal, and here is what your people, processes, and technology did, or didn&#8217;t do to stop them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1586"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1584">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1585'
	>
	Cost and time reflect this. A pen test might run for a week or two. A red team engagement is typically measured in weeks to months, and requires significantly more planning on both sides.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1589"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1587">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1588'
	>
	When Do You Need Pen Testing vs Red Teaming?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1592"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1590">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1591'
	>
	Pen testing is right for checking specific systems — after a new build, before a release, or as part of a compliance cycle. TIBER-EU and<a href="https://infinum.com/blog/eu-cybersecurity-legislation-nis2-dora/" id="https://infinum.com/blog/eu-cybersecurity-legislation-nis2-dora/"> DORA</a> both require it. If you&#8217;re running one annually and after major changes, you&#8217;re doing the basics right.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1595"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1593">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1594'
	>
	Red teaming is for organisations that have already done the basics. You need mature security processes in place first — incident detection, response playbooks, trained staff — otherwise a red team engagement mostly finds that your foundations are weak, which a pen test would have told you for a fraction of the cost. When that foundation is there, red teaming stress-tests the whole picture: not just whether systems are patched, but whether your people, processes, and assumptions hold up under a realistic attack.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1598"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1596">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1597'
	>
	The other factor is the threat model. If you handle sensitive data, operate critical infrastructure, or are the kind of target sophisticated threat actors actively pursue, red teaming answers a question pen testing can&#8217;t: not &#8220;is this system secure?&#8221; but &#8220;could a determined adversary get into our organisation?&#8221;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1601"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1599">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1600'
	>
	If you&#8217;re not sure which fits, start with a pen test. And if you want to understand what a red team engagement actually involves, <a href="https://infinum.com/red-team-services/" id="https://infinum.com/red-team-services/">explore our red team services</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1604"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1602">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1603'
	>
	Technical depth isn&#8217;t enough</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1607"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1605">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1606'
	>
	The best pen testers and red teamers share two things: deep technical expertise and genuine creativity. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1610"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1608">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1609'
	>
	The technical side is obvious – you need to understand how systems behave under pressure, and how to adapt when a vector doesn&#8217;t work as expected. But creativity is what separates good from exceptional.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1613"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1611">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1612'
	>
	Testing isn&#8217;t a checklist. When a system reacts unexpectedly, the question isn&#8217;t &#8220;what does the tool say next?&#8221; – it&#8217;s &#8220;what does this tell me, and where does it lead?&#8221; That kind of thinking can&#8217;t be scripted. It has to be developed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1617"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1614">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1615'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-1616'
	>
	<strong>You need to think like an attacker – then explain the risk in language a board member can act on.</strong></p>
		<div class="blockquote__caption-wrap">
					</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1620"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1618">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1619'
	>
	The second half of that matters as much as the first. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1623"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1621">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1622'
	>
	A brilliant technical finding is worthless if it can&#8217;t be translated into plain language. The job isn&#8217;t just to find vulnerabilities – it&#8217;s to help the organisation understand what they mean and what to do about them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1626"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1624">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1625'
	>
	Why no scanner replaces this</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1629"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1627">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1628'
	>
	<a href="https://infinum.com/blog/security-gaps-in-vibe-coded-applications/" target="_blank">Our research into AI-generated code security</a> found that automated tools are good at cataloging CVEs, misconfigured headers, and outdated libraries. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1632"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1630">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1631'
	>
	They&#8217;re fast, they&#8217;re consistent, and they&#8217;re useful. But they operate on fixed logic. They flag what they&#8217;re programmed to flag, and they stop there.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1635"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1633">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1634'
	>
	A skilled tester doesn&#8217;t stop there. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1638"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1636">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1637'
	>
	They notice how a system reacts, chain together findings that no single tool would connect, and pursue lines of attack that require judgment – not just pattern matching. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1640"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1639'
	>
	<strong>Automated scanners also can&#8217;t walk through your front door pretending to be IT support, or craft a phishing email convincing enough to fool a trained employee.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1643"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1641">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1642'
	>
	Nine times out of ten, <a href="https://infinum.com/blog/how-do-phishing-simulations-contribute-to-enterprise-security/">real attackers get in through people, not ports</a>. A scanner has nothing to say about that. Manual testing does.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1646"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1644">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1645'
	>
	This is why organisations that rely on automated tools as their primary security layer end up with a false sense of coverage. The scanner ran clean – but that&#8217;s only true for the things the scanner knows how to look for. The cost of finding out too late is well-documented in our breakdown of <a href="https://infinum.com/blog/cyberattack-cost/">the real cost of a cyberattack</a>, which shows what&#8217;s actually at stake.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1649"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1647">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1648'
	>
	Attackers aren&#8217;t limited by that constraint. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1652"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1650">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1651'
	>
	A vendor with a quiet network connection into your environment, a help desk employee who clicks the wrong attachment – these don&#8217;t show up on a dashboard. They show up when it&#8217;s too late.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1659"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<a	class="card-simple js-card-simple card-simple--is-ad block-card__card-simple card-simple--has-link js-card-simple-link card-simple__content-align--left"
	data-id="es-1653"
	 href='https://infinum.com/cybersecurity/'>

	
	
	<div class="card-simple__content">
		<div class="card-simple__heading-wrap">
			<p	class='typography typography--size-36-text js-typography card-simple__heading'
	data-id='es-1654'
	>
	<strong>Want to discover security vulnerabilities before attackers do? </strong></p>		</div>

		<p	class='typography typography--size-16-text-roman js-typography card-simple__paragraph'
	data-id='es-1655'
	 id='es-1653-paragraph'>
	Explore the full list of our cybersecurity services. </p><button	class="btn btn--color-infinum btn--size-small btn--width-default btn__icon-position--right card-simple__btn js-block-card-btn js-card-simple-link"
	data-id="es-1656"
	 tabindex='-1'>
		<div class="btn__inner">
					<div	class='typography typography--size-none js-typography btn__label'
	data-id='es-1657'
	>
	<strong><strong>Learn more</strong></strong></div>		
		<i
	class="icon btn__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='arrow-right-16' data-id='es-1658'>
	<svg fill='none' height='16' viewBox='0 0 17 16' width='17' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'><g stroke='currentColor' stroke-width='2'><path d='m.5 7.99999 14 .00001'/><path d='m9.23352 2.7251 5.97848 5.97852'/><path d='m9.23352 13.2744 5.97848-5.9785'/></g></svg></i>	</div>
	</button>	</div>
</a>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1662"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1660">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1661'
	>
	So, the question isn&#8217;t whether to test. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1665"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1663">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1664'
	>
	It&#8217;s whether you&#8217;re testing the right things, in the right way, with people who can tell the difference. Automated tools have their place – but they&#8217;re a floor, not a ceiling.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/pen-testing-red-teaming/">Pen Testing, Red Teaming, and Why No Scanner Can Replace Either</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19277691https://infinum.com/uploads/2026/04/axios-npm-attack.webp</url>
				</image>
				<title>The Axios npm Attack: What It Means for Every JavaScript Project</title>
				<link>https://infinum.com/blog/axios-npm-supply-chain-attack/</link>
				<pubDate>Wed, 01 Apr 2026 13:00:03 +0000</pubDate>
				<dc:creator>Hrvoje Filaković</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19277691</guid>
				<description>
					<![CDATA[<p>axios is the JavaScript library most apps use to talk to the internet. On March 31, two malicious versions were quietly published to npm — and anyone who ran npm install during a three-hour window may have a remote access trojan on their machine. Full technical breakdown inside.</p>
<p>The post <a href="https://infinum.com/blog/axios-npm-supply-chain-attack/">The Axios npm Attack: What It Means for Every JavaScript Project</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-1864"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1668">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1671"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1669">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1670'
	>
	On March 31, attackers compromised axios — a JavaScript library downloaded roughly 100 million times a week. Here&#8217;s what happened, who&#8217;s affected, and what to do now.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1674"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1672">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1673'
	>
	If you&#8217;ve never heard of axios, here&#8217;s the short version: it&#8217;s the library that most JavaScript applications use to talk to the internet. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1677"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1675">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1676'
	>
	Fetching data from an API, submitting a form, making a request to a backend service – axios handles it. It&#8217;s in frontend apps, backend services, CI pipelines, and internal tools. Chances are it&#8217;s somewhere in your stack right now, possibly several places.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1680"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1678">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1679'
	>
	<span class='screen-reader-text'>On March 31, 2026, axios—with roughly 100 million weekly downloads—became the vector for one of the most significant npm supply chain attacks in recent memory.</span><span aria-hidden='true'><strong>On March 31, 2026, axios—with roughly 100 million weekly downloads—became the vector for one of the most significant npm supply chain attacks in recent memory.</strong></span></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1682"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1681'
	>
	Two malicious versions of axios were published to npm: axios@1.14.1 and axios@0.30.4. Both contained a hidden dependency designed to install a cross-platform remote access trojan on any developer machine that ran npm install. The window was under three hours — but given axios&#8217;s scale, that was enough. If your team ships JavaScript and installed either version during that period, treat the affected machine as compromised.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1685"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1683">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1684'
	>
	<strong>You don’t need to have installed axios directly to be at risk. </strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1688"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1686">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1687'
	>
	Any package in your dependency tree that lists axios with a floating version range (<code>^1.x</code>) and was rebuilt during the exposure window may have pulled in the malicious version automatically. This also includes AI coding assistants and automated tooling — anything that ran <code>npm install</code> on your behalf yesterday should be treated the same as a manual install.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1691"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1689">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1690'
	>
	We&#8217;ve written before about <a href="https://infinum.com/blog/software-supply-chain-security/">software supply chain security</a> and the systemic risks that come with modern dependency management. This attack is exactly the scenario we described – not a theoretical edge case, but a live incident affecting one of the most widely used libraries in the JavaScript ecosystem. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1694"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1692">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1693'
	>
	<a href="https://cloud.google.com/blog/topics/threat-intelligence/north-korea-threat-actor-targets-axios-npm-package" id="https://cloud.google.com/blog/topics/threat-intelligence/north-korea-threat-actor-targets-axios-npm-package">Google&#8217;s Threat Intelligence Group</a> has attributed the attack to UNC1069, a North Korean group previously active in cryptocurrency theft. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1697"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1695">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1696'
	>
	Here&#8217;s what happened, how it worked, and what you should check right now.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1700"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1698">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1699'
	>
	<strong>What happened</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1703"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1701">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1702'
	>
	The attacker didn&#8217;t touch a single line of axios source code. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1706"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1704">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1705'
	>
	Instead, they compromised a long-lived npm access token belonging to jasonsaayman, the project&#8217;s lead maintainer. With that token, they published two new releases – one for the 1.x branch and one for the legacy 0.x branch – 39 minutes apart, covering both release lines simultaneously.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1709"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1707">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1708'
	>
	Both releases modified exactly one file: package.json. The only substantive change was adding plain-crypto-js@4.2.1 as a runtime dependency. That package was pre-staged 18 hours earlier, under a separate attacker-controlled account, with a clean version first to build registry history before the malicious update was pushed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1711"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1710'
	>
	Why this matters: When you run npm install, you&#8217;re not just downloading the package you asked for — you&#8217;re downloading everything it depends on, including any setup scripts those dependencies declare. The attacker&#8217;s package declared one. Most developers never see this happening. It runs silently, by design. By the time npm install finished, the script had already executed, phoned home, and delivered its payload.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1714"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1712">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1713'
	>
	plain-crypto-js contains a full copy of the legitimate crypto-js library – every source file identical, bit-for-bit. The only difference is a postinstall hook: &#8220;node setup.js&#8221;. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1717"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1715">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1716'
	>
	When npm resolves the dependency tree and runs that hook, the dropper fires. It contacts the attacker&#8217;s command-and-control server, delivers a platform-specific payload for macOS, Windows, or Linux, then deletes itself and replaces package.json with a clean stub reporting version 4.2.0.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1720"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1718">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1719'
	>
	By the time npm install finishes, there&#8217;s no error, no warning, no obvious trace. The directory node_modules/plain-crypto-js/ exists, but npm list shows version 4.2.0 – not the malicious 4.2.1 that actually ran. Standard npm audit finds nothing.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1723"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1721">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1722'
	>
	<strong>Why this specific attack is worth studying</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1726"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1724">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1725'
	>
	Most supply chain incidents involve obvious red flags – a zero-history package, a suspicious name, a sudden maintainer change. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1729"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1727">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1728'
	>
	This one was deliberately engineered to avoid all of them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1734"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="blockquote block-blockquote__blockquote" data-id="es-1730">
	
	<div class="blockquote__content">
		<i
	class="icon blockquote__icon icon--size-16 icon--scale-100"
	 aria-hidden='true' data-name='blockquote-24' data-id='es-1731'>
	<svg fill='none' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path clip-rule='evenodd' d='m12 24c6.6274 0 12-5.3726 12-12 0-2.79685-.9568-5.37021-2.561-7.41062-.581.22951-1.0832.60583-1.5069 1.12898-.5132.60844-.7698 1.41969-.7698 2.43375v.07605h2.5789v5.59004h-5.6197v-5.01962c0-1.11547.154-2.06616.4619-2.85205.3336-.81125.757-1.48307 1.2702-2.01545.528-.52161 1.1175-.92155 1.7687-1.1998-2.0728-1.70651-4.7279-2.73128-7.6223-2.73128-6.62742 0-12 5.37258-12 12 0 6.6274 5.37258 12 12 12zm-3.53811-18.05347c-.30793.78589-.46189 1.73658-.46189 2.85205v5.01962h5.6197v-5.59004h-2.5789v-.07605c0-1.01406.2566-1.82531.7698-2.43375.5389-.63379 1.1804-1.05209 1.9245-1.2549v-2.28164c-.7441.07605-1.4626.25351-2.1555.53238-.6928.27887-1.3086.68449-1.84752 1.21688-.51321.53238-.9366 1.2042-1.27019 2.01545z' fill='currentColor' fill-rule='evenodd'/></svg></i><p	class='typography typography--size-36-text js-typography blockquote__quote'
	data-id='es-1732'
	>
	<strong>Put plainly: most security tools work by recognising known bad things – a flagged domain, a suspicious file, a package with no history. This attack had none of those signals. It arrived under a trusted name, from a legitimate account, with clean source code and a registry history. The tools that were supposed to catch it passed it through.</strong></p>
		<div class="blockquote__caption-wrap">
			<div	class='typography typography--size-12-text-roman js-typography blockquote__caption'
	data-id='es-1733'
	>
	HRVOJE FILAKOVIC, CYBERSECURITY ENGINEER</div>		</div>
	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1737"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1735">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1736'
	>
	That&#8217;s what makes it worth paying attention to, even if axios isn&#8217;t in your stack – the technique will be reused.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1740"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1738">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1739'
	>
	The attacker published a clean decoy package 18 hours before activating the payload – long enough to avoid &#8220;brand new account&#8221; alerts from registry scanners. The malicious axios releases were signed by the legitimate maintainer&#8217;s account. No corresponding commit or tag appeared on GitHub (that gap is the forensic signal, in hindsight), but most CI systems don&#8217;t verify OIDC provenance on pull.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1742"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1741'
	>
	The plain-crypto-js package was designed to survive a human code review. The library files were identical to the legitimate crypto-js. A developer diffing the package against its stated source would find nothing. The malicious payload lived in package.json and setup.js – a postinstall script that looks, at a glance, like a standard build step.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1745"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1743">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1744'
	>
	This is the attack pattern that <a href="https://infinum.com/blog/eu-cybersecurity-legislation-nis2-dora/">NIS2</a> and <a href="https://infinum.com/blog/cyber-resilience-act/">CRA</a> regulations are increasingly focused on: not a breach of your perimeter, but a compromise of the supply chain your code depends on. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1748"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1746">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1747'
	>
	Your code didn&#8217;t have a vulnerability. Your tooling did.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1751"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1749">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1750'
	>
	<strong>The OIDC misconfiguration that made it possible</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1754"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1752">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1753'
	>
	Axios had OIDC Trusted Publishing configured for its release workflow. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1757"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1755">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1756'
	>
	In theory, this should have made a token-based publish impossible – OIDC ties releases to specific GitHub Actions runs, and the ephemeral token can&#8217;t be stolen.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1760"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1758">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1759'
	>
	In practice, the GitHub Actions workflow passed both the OIDC credentials and a classic NPM_TOKEN environment variable. When both are present, npm defaults to the token. The long-lived token – which can be exfiltrated – was effectively the only authentication method that mattered.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1763"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1761">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1762'
	>
	This is a common misconfiguration. Many projects enable OIDC Trusted Publishing and consider the job done, without removing or rotating the classic token that overrides it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1766"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1764">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1765'
	>
	<strong>Check if you&#8217;re affected – right now</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1769"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1767">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1768'
	>
	<strong>Step 1 – Check your lockfile for the malicious versions</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1771"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">grep</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">E</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">&quot;axios&quot;</span><span class="token" style="color: #032f62;">&#039;</span><span class="token"> </span><span class="token" style="color: #005cc5;">package</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">lock</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">json</span><span class="token"> </span><span class="token" style="color: #d73a49;">|</span><span class="token"> </span><span class="token" style="color: #005cc5;">grep</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">E</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1\.14\.1|0\.30\.4</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #005cc5;">npm</span><span class="token"> </span><span class="token" style="color: #005cc5;">list</span><span class="token"> </span><span class="token" style="color: #005cc5;">axios</span><span class="token"> </span><span class="token" style="color: #005cc5;">2</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">dev</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">null</span><span class="token"> </span><span class="token" style="color: #d73a49;">|</span><span class="token"> </span><span class="token" style="color: #005cc5;">grep</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">E</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1\.14\.1|0\.30\.4</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1774"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1772">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1773'
	>
	<strong>Step 2 – Check for the malicious dependency in node_modules</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1777"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1775">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1776'
	>
	The presence of this directory – regardless of what version package.json now reports – means the dropper executed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1779"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">ls</span><span class="token"> </span><span class="token" style="color: #005cc5;">node_modules</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">plain</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">crypto</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">js</span><span class="token"> </span><span class="token" style="color: #005cc5;">2</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">dev</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">null</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #005cc5;">echo</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">DROPPER RAN</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1782"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1780">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1781'
	>
	<strong>Step 3 – Check for persistent artifacts</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1784"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> macOS</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">ls</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">la</span><span class="token"> </span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Library</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">Caches</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">com</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">apple</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">act</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">mond</span><span class="token"> </span><span class="token" style="color: #005cc5;">2</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">dev</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">null</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #005cc5;">echo</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">COMPROMISED</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> Linux</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">ls</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">la</span><span class="token"> </span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">tmp</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">ld</span><span class="token" style="color: #d73a49;">.</span><span class="token" style="color: #005cc5;">py</span><span class="token"> </span><span class="token" style="color: #005cc5;">2</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">dev</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #005cc5;">null</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #005cc5;">echo</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">COMPROMISED</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> Windows (cmd.exe)</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">dir</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">%PROGRAMDATA%\wt.exe</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #005cc5;">2</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token" style="color: #005cc5;">nul</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #005cc5;">echo</span><span class="token"> </span><span class="token" style="color: #005cc5;">COMPROMISED</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1787"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1785">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1786'
	>
	<strong>If you find any of these</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1790"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1788">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1789'
	>
	The response depends on where the install ran. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1793"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1791">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1792'
	>
	For <strong>ephemeral CI runners</strong> (e.g. GitHub-hosted), the runner is destroyed after each job — rotate any secrets that were injected during the affected run and move on. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1796"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1794">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1795'
	>
	For <strong>developer machines and self-hosted runners</strong>, treat the system as fully compromised: isolate it from the network immediately and re-image it or restore from a verified clean backup taken before March 30. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1798"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1797'
	>
	<strong>Do not attempt to clean in place — the RAT deploys persistence mechanisms that survive a reboot, so credential rotation on a live system is not sufficient.</strong> </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1801"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1799">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1800'
	>
	Once you have a clean machine, rotate everything that was accessible from it: npm tokens, SSH keys, cloud credentials (AWS, GCP, Azure), CI/CD secrets, and any values in <code>.env</code> files present at install time.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1804"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1802">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1803'
	>
	<strong>To downgrade cleanly</strong></h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1806"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">npm</span><span class="token"> </span><span class="token" style="color: #005cc5;">install</span><span class="token"> </span><span class="token" style="color: #005cc5;">axios</span><span class="token" style="color: #d73a49;">@</span><span class="token" style="color: #005cc5;">1</span><span class="token" style="color: #005cc5;">.</span><span class="token" style="color: #005cc5;">14</span><span class="token" style="color: #005cc5;">.</span><span class="token" style="color: #005cc5;">0</span><span class="token">  </span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> for 1.x users</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #005cc5;">npm</span><span class="token"> </span><span class="token" style="color: #005cc5;">install</span><span class="token"> </span><span class="token" style="color: #005cc5;">axios</span><span class="token" style="color: #d73a49;">@</span><span class="token" style="color: #005cc5;">0</span><span class="token" style="color: #005cc5;">.</span><span class="token" style="color: #005cc5;">30</span><span class="token" style="color: #005cc5;">.</span><span class="token" style="color: #005cc5;">3</span><span class="token">  </span><span class="token" style="color: #6a737d;">#</span><span class="token" style="color: #6a737d;"> for 0.x users</span><span class="token" style="color: #6a737d;">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1809"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1807">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1808'
	>
	<strong>What to change in your CI/CD configuration</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1812"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1810">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1811'
	>
	Beyond the immediate incident, this attack exposes a few controls worth auditing across your pipelines.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1815"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1813">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1814'
	>
	<li><strong>Remove or rotate long-lived npm tokens. </strong>If your publish workflow uses a classic NPM_TOKEN alongside OIDC, the token wins. Either remove it from the workflow entirely, or rotate it and restrict it to the minimum necessary scope.</li><li><strong>Add &#8211;ignore-scripts to CI installs. </strong>This prevents postinstall hooks from running during automated builds:</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1817"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #005cc5;">npm</span><span class="token"> </span><span class="token" style="color: #005cc5;">ci</span><span class="token"> </span><span class="token" style="color: #d73a49;">--</span><span class="token" style="color: #005cc5;">ignore</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">scripts</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1820"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1818">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1819'
	>
	<li><strong>Pin versions explicitly. </strong>Avoid floating ranges like ^1.14.0. Both malicious releases were tagged latest, so any unpinned install resolved to them.</li><li><strong>Add provenance verification to your review process. </strong>For major releases of critical packages, check npm registry metadata for OIDC provenance. Legitimate axios 1.x releases show GitHub Actions as the publisher with a trustedPublisher field. The malicious release showed the maintainer&#8217;s username directly – no OIDC binding, no corresponding GitHub tag.</li><li><strong>Block the C2 domain at the network level</strong>. If you have a firewall or DNS filtering in place, block the C2 domain <code>sfrclak[.]com</code> and IP address <code>142[.]11[.]206[.]73</code> on port 8000. Flag this to your network or DevOps team rather than handling it at the host level — a firewall rule covers all machines rather than requiring per-device changes.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1823"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1821">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1822'
	>
	<strong>The broader pattern</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1826"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1824">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1825'
	>
	This isn&#8217;t an isolated incident. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1829"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1827">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1828'
	>
	The axios attack follows the same playbook as the CrowdStrike npm compromise, the IoliteLabs VSCode extension backdoor, and the <a href="https://infinum.com/blog/openclaw-moltbot-clawdbot-viral-ai-sidekick/">fake ClawdBot VS Code extension</a> we documented earlier this year — all incidents where a trusted-looking package or installer was used to deliver a credential stealer to unsuspecting developers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1831"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-highlighted-text">
	<p	class='typography typography--size-36-text js-typography block-highlighted-text__typography'
	data-id='es-1830'
	>
	The package manager ecosystem runs on implicit trust: if a package is in npm under a recognizable name and a legitimate maintainer&#8217;s account, most tooling and most developers treat it as safe.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1834"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1832">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1833'
	>
	That model is under sustained attack. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1837"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1835">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1836'
	>
	The attacker here invested 18 hours of prep time, built platform-specific payloads for three operating systems, and designed the dropper to self-destruct. This is not someone experimenting – it&#8217;s operational tradecraft applied to the JavaScript supply chain.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1840"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1838">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1839'
	>
	As we covered in our <a href="https://infinum.com/blog/software-supply-chain-security/">supply chain security framework</a>, the highest-risk entry points are often not your own code but the tools and processes you depend on to build and deploy it. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1843"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1841">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1842'
	>
	The question isn&#8217;t whether your perimeter is secure, it&#8217;s whether your CI pipeline would have caught this before it ran.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1846"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1844">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1845'
	>
	<strong>For teams with third-party risk exposure</strong></h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1849"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1847">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1848'
	>
	If you&#8217;re managing a product that runs JavaScript in CI and you have compliance obligations – PCI DSS, NIS2, ISO 27001 – this incident is worth documenting even if you weren&#8217;t affected. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1852"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1850">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1851'
	>
	Our <a href="https://infinum.com/third-party-cyber-risk-management/">third-party cyber risk management</a> work often starts with incidents like this one: not after a breach, but as a trigger to audit what dependency hygiene actually looks like in practice across an engineering org.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1855"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1853">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1854'
	>
	The controls that would have caught this – OIDC provenance checks, version pinning, &#8211;ignore-scripts in CI, outbound network monitoring – aren&#8217;t difficult to implement. They just tend not to exist until something goes wrong.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1858"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1856">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1857'
	>
	If you want to review your current posture, <a href="https://infinum.com/contact/">get in touch</a>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1861"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1859">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1860'
	>
	<strong>Indicators of compromise</strong></h2></div>	</div>

<div
	class="wrapper"
	data-id="es-1862"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			
<figure class="wp-block-table is-style-stripes"><table><tbody><tr><td><strong>Malicious packages</strong></td><td></td></tr><tr><td>Malicious package</td><td>axios@1.14.1 (shasum: 2553649f)</td></tr><tr><td>Malicious package</td><td>axios@0.30.4 (shasum: d6f3f62f)</td></tr><tr><td>Malicious dependency</td><td>plain-crypto-js@4.2.1</td></tr><tr><td>Attacker npm account</td><td>jasonsaayman (email changed to ifstap[at]proton[.]me)</td></tr><tr><td>Staging npm account</td><td>nrwise (email: nrwise[at]proton[.]me)</td></tr><tr><td><strong>Network indicators</strong></td><td></td></tr><tr><td>C2 domain</td><td>sfrclak[.]com</td></tr><tr><td>C2 IP</td><td>142[.]11[.]206[.]73</td></tr><tr><td>C2 URL</td><td>hxxp://sfrclak[.]com:8000/6202033</td></tr><tr><td>C2 port</td><td>8000</td></tr><tr><td>macOS POST body</td><td>packages.npm[.]org/product0</td></tr><tr><td>Windows POST body</td><td>packages.npm[.]org/product1</td></tr><tr><td>Linux POST body</td><td>packages.npm[.]org/product2</td></tr><tr><td><strong>Filesystem artifacts</strong></td><td></td></tr><tr><td>macOS artifact</td><td>/Library/Caches/com.apple.act.mond</td></tr><tr><td>Windows (persistent)</td><td>%PROGRAMDATA%\wt.exe</td></tr><tr><td>Windows temp (self-deletes)</td><td>%TEMP%\6202033.vbs | %TEMP%\6202033.ps1</td></tr><tr><td>Linux artifact</td><td>/tmp/ld.py</td></tr><tr><td><strong>Advisory references</strong></td><td></td></tr><tr><td>GitHub advisory</td><td>GHSA-fw8c-xr5c-95f9</td></tr><tr><td>Malware advisory</td><td>MAL-2026-2306</td></tr><tr><td>Malware family (GTIG)</td><td>WAVESHAPER.V2</td></tr><tr><td><strong>Safe versions</strong></td><td></td></tr><tr><td>Safe 1.x version</td><td>axios@1.14.0 (shasum: 7c29f4cf)</td></tr><tr><td>Safe 0.x version</td><td>axios@0.30.3</td></tr></tbody></table><figcaption class="wp-element-caption"><em>Infinum&#8217;s cybersecurity team provides penetration testing, third-party risk management, and secure development advisory for enterprise and regulated-industry clients. Learn more at </em><a href="https://infinum.com/cybersecurity/"><em>infinum.com/cybersecurity</em></a><em>.</em></figcaption></figure>
		</div>
	</div>


</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/axios-npm-supply-chain-attack/">The Axios npm Attack: What It Means for Every JavaScript Project</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
					<item>
				<image>
					<url>19276916https://infinum.com/uploads/2026/03/android-protection-hero-2.webp</url>
				</image>
				<title>Understanding &#038; Defeating Android Protections</title>
				<link>https://infinum.com/blog/understanding-defeating-android-protections/</link>
				<pubDate>Thu, 19 Mar 2026 11:13:28 +0000</pubDate>
				<dc:creator>Hrvoje Filaković</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19276916</guid>
				<description>
					<![CDATA[<p>Discover how hackers bypass Android root detection, anti-hooking, and anti-debug protections with real code examples and penetration testing techniques to strengthen your mobile security knowledge.</p>
<p>The post <a href="https://infinum.com/blog/understanding-defeating-android-protections/">Understanding &amp; Defeating Android Protections</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-2309"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-1865">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1868"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1866">
	<p	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1867'
	>
	Many modern Android applications are highly advanced and operate in sensitive domains like banking, money transfers, and other critical services people rely on daily. A rooted environment gives attackers elevated access to the device, which they can abuse in order to bypass the app’s restrictions, extract sensitive data, and interfere with the app’s behavior.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1871"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1869">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1870'
	>
	To counter these threats, many apps implement protections against common tools and techniques used in reverse engineering. These include anti-root, anti-hook, and anti-debug mechanisms, which are designed to make an attacker’s job significantly more difficult—often requiring considerable effort and creativity to bypass.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1874"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-1872">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-1873'
	>
	<li>Anti-Root – Detects whether the device has been rooted.</li><li>Anti-Hook – Detects function hooking attempts using tools like Frida.</li><li>Anti-Debug – Detects whether the application is being debugged.</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1877"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1875">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1876'
	>
	A practical look at protection mechanisms</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1880"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1878">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1879'
	>
	This article provides other security researchers with a practical look at how some of these protection mechanisms are implemented and how they can be bypassed during <a href="https://infinum.com/blog/penetration-testing-steps/" id="https://infinum.com/blog/penetration-testing-steps/">penetration testing</a> or security research.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1883"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1881">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1882'
	>
	Additionally, by understanding how these protections work, developers can <a href="https://infinum.com/blog/ssdlc-application-security/" id="https://infinum.com/blog/ssdlc-application-security/">build stronger, more resilient security mechanisms</a> into their apps and even extend these ideas to develop more advanced and effective techniques.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1886"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1884">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1885'
	>
	Furthermore, during this research, an application called TamperLab was created. It includes various protection mechanisms to detect whether a device is rooted, whether any hooking is in place, or whether the application is being debugged. The project is fully open-source, and contributions are welcome.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1889"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1887">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1888'
	>
	It can be found on the following GitHub page for you to check out:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1891"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-html github-light" data-language="html" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">https://github.com/infinum/cs-tamperlab
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1894"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1892"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1893">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2026/03/Screenshot-2026-03-17-at-11.23.01-1400x910.webp				media='(max-width: 699px)'
				type=image/webp								height="910"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2026/03/Screenshot-2026-03-17-at-11.23.01.webp"
					class="image__img block-media__image-img"
					alt="TamperLab Android app showing root detection, hook detection, and debug detection status indicators with green and red checkmarks"
										height="968"
															width="1490"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1897"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1895">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-1896'
	>
	Anti-Root Protections</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1900"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1898">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1899'
	>
	In this section, we will look at some commonly used root detection techniques and their implementations, and immediately follow each one with an example of how it can be bypassed during testing or reverse engineering.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1903"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1901">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1902'
	>
	The “One Function” Folly</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1906"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1904">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1905'
	>
	The most common way of implementing protection measures such as anti-root, anti-hook, and anti-debug is by placing all checks inside a single function. This is a common mistake, as it gives attackers the opportunity to <a href="https://infinum.com/blog/ai-generated-code-security-risks/" id="https://infinum.com/blog/ai-generated-code-security-risks/">bypass all protections</a> within seconds.For example, in the following scenario, the <a href="https://github.com/scottyab/rootbeer">RootBeer</a> library is used to quickly demonstrate why placing all checks in a single function can be problematic. As shown in the code snippet below, the isRooted() function is called.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1908"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">boolean</span><span class="token"> </span><span class="token" style="color: #24292e;">isRooted</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">rootBeer</span><span class="token">.</span><span class="token" style="color: #6f42c1;">isRooted</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">showRootStatusDialog</span><span class="token">(</span><span class="token">isRooted</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1911"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1909">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1910'
	>
	Such a function includes various methods to detect if the device is rooted.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1913"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">boolean</span><span class="token"> </span><span class="token" style="color: #6f42c1;">isRooted</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #6f42c1;">detectRootManagementApps</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">||</span><span class="token"> 
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">detectPotentiallyDangerousApps</span><span class="token">(</span><span class="token">)</span><span class="token">  </span><span class="token" style="color: #d73a49;">||</span><span class="token"> 
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">checkForBinary</span><span class="token">(</span><span class="token">BINARY_SU</span><span class="token">)</span><span class="token">         </span><span class="token" style="color: #d73a49;">||</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">checkForDangerousProps</span><span class="token">(</span><span class="token">)</span><span class="token">          </span><span class="token" style="color: #d73a49;">||</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">checkForRWPaths</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1916"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1914">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1915'
	>
	Although the function includes many ways to detect if the device is rooted, it is not sufficient because the isRooted() function itself can be hooked, allowing an attacker to bypass all detections with a single hook.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1919"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1917">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1918'
	>
	Using the following simple Frida script, we can do exactly that. We obtain a reference to the RootBeer class and hook the isRooted() function, immediately returning false.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1921"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-javascript github-light" data-language="javascript" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Java</span><span class="token">.</span><span class="token" style="color: #6f42c1;">perform</span><span class="token">(</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">=&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token" style="color: #005cc5;">rootbeer</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">Java</span><span class="token">.</span><span class="token" style="color: #6f42c1;">use</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.scottyab.rootbeer.RootBeer</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #24292e;">rootbeer</span><span class="token">.</span><span class="token" style="color: #24292e;">isRooted</span><span class="token">.</span><span class="token" style="color: #6f42c1;">implementation</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">function</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">[+] isRooted() hooked -&gt; returning false</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">false</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1924"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1922">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1923'
	>
	Using the following command, the targeted application can be started with the hook applied.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1926"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">frida </span><span class="token" style="color: #d73a49;">-</span><span class="token">U </span><span class="token" style="color: #d73a49;">-</span><span class="token">l </span><span class="token" style="color: #24292e;">evade_root</span><span class="token">.</span><span class="token" style="color: #24292e;">js</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token">f </span><span class="token" style="color: #24292e;">com</span><span class="token">.</span><span class="token" style="color: #24292e;">hacking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1929"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1927">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1928'
	>
	As shown in the following image, the previously created script successfully bypasses all the checks because they are contained within a single function.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1932"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1930"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1931">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_2.webp"
					class="image__img block-media__image-img"
					alt="Frida terminal output showing isRooted() hook successfully returning false, bypassing all RootBeer root checks with a single Frida script"
										height="311"
															width="745"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1935"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1933">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1934'
	>
	Testing this inside TamperLab shows that we successfully bypass the protection measure, and a green checkmark is displayed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1938"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1936"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1937">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_3.webp"
					class="image__img block-media__image-img"
					alt="TamperLab app displaying green checkmark after successful bypass of root detection using Frida isRooted() hook"
										height="310"
															width="478"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1941"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1939">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1940'
	>
	SU Binary Check (Shell)</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1944"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1942">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1943'
	>
	All rooted Android devices contain the su binary, and any application requiring root access must use su to elevate privileges and perform privileged actions on the device.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1947"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1945">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1946'
	>
	When present on a device, applications can detect the existence of the binary and conclude that the device is rooted. A quick way to check for it is by programmatically executing the which su system command.In my application, I created a simple HelperClass that contains various functionalities and detection methods. One of its purposes is to execute system commands.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1949"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">String</span><span class="token"> </span><span class="token" style="color: #24292e;">output</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">HelperClass</span><span class="token">.</span><span class="token" style="color: #6f42c1;">executeCommand</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">which su</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1952"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1950">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1951'
	>
	The executeCommand() function essentially passes the given command as an argument to the exec() function, which executes it on the device.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1954"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Process</span><span class="token"> </span><span class="token" style="color: #24292e;">process</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">Runtime</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getRuntime</span><span class="token">(</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #6f42c1;">exec</span><span class="token">(</span><span class="token">command</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">BufferedReader</span><span class="token"> </span><span class="token" style="color: #24292e;">reader</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">new</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BufferedReader</span><span class="token">(</span><span class="token" style="color: #d73a49;">new</span><span class="token"> </span><span class="token" style="color: #6f42c1;">InputStreamReader</span><span class="token">(</span><span class="token" style="color: #24292e;">process</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getInputStream</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">String</span><span class="token"> </span><span class="token" style="color: #24292e;">output</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">reader</span><span class="token">.</span><span class="token" style="color: #6f42c1;">readLine</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">reader</span><span class="token">.</span><span class="token" style="color: #6f42c1;">close</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">return</span><span class="token"> output</span><span class="token">;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1957"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1955">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1956'
	>
	If the su binary exists, the command will return its full system path, otherwise, an error code will be returned.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1960"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1958">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1959'
	>
	Using Frida, we can bypass this technique by hooking the exec() function itself. If we detect a command such as which su, we can replace it at runtime with another non-existent command.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1962"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Java</span><span class="token">.</span><span class="token" style="color: #6f42c1;">perform</span><span class="token">(</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">const</span><span class="token"> Runtime </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">Java</span><span class="token">.</span><span class="token" style="color: #6f42c1;">use</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">java.lang.Runtime</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #24292e;">Runtime</span><span class="token">.</span><span class="token" style="color: #24292e;">exec</span><span class="token">.</span><span class="token" style="color: #6f42c1;">overload</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">java.lang.String</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">.</span><span class="token" style="color: #24292e;">implementation</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">command</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #24292e;">command</span><span class="token">.</span><span class="token" style="color: #6f42c1;">trim</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">===</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">which su</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">[i] called exec(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> command </span><span class="token" style="color: #d73a49;">+</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">)</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[+] returning a fake binary.</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            command </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">which DoesNotExist</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #6f42c1;">exec</span><span class="token">(</span><span class="token">command</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #6f42c1;">exec</span><span class="token">(</span><span class="token">command</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1965"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1963">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1964'
	>
	As demonstrated, by using this technique, we can target specific exec() parameters after reverse engineering the application and bypass the detection mechanisms in place.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1968"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1966"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1967">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_4.webp"
					class="image__img block-media__image-img"
					alt="Frida script output intercepting Runtime.exec() call for &quot;which su&quot; command and substituting a non-existent binary path to bypass SU binary shell check"
										height="315"
															width="742"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1971"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1969">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-1970'
	>
	SU Binary Check (Native C/C++)</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1974"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1972">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1973'
	>
	Another way developers may check for the su binary or for rooted devices in general is by writing native C/C++ code using JNI. In case you are unfamiliar, JNI (Java Native Interface) is a framework that allows Java code running on the Android platform to interact with native applications and libraries written in C or C++.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1977"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1975">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1976'
	>
	For example, we can check for the su binary by iterating through common system paths where it might exist, and then using the std::ifstream function to check if the file can be opened.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1979"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">extern </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">C</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #24292e;">JNIEXPORT</span><span class="token"> jboolean </span><span class="token" style="color: #24292e;">JNICALL</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #6f42c1;">Java_com_hacking_tamperlab_NativeChecks_CheckSuBinaryNative</span><span class="token">(</span><span class="token">JNIEnv </span><span class="token" style="color: #d73a49;">*</span><span class="token">env</span><span class="token">,</span><span class="token"> jclass clazz</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token" style="color: #d73a49;">char</span><span class="token" style="color: #d73a49;">*</span><span class="token"> paths</span><span class="token">[</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/data/local/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/data/local/bin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/data/local/xbin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/sbin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/su/bin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/system/bin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/system/bin/.ext/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/system/bin/failsafe/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/system/sd/xbin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/system/usr/we-need-root/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/system/xbin/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/cache/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/data/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/dev/</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">//</span><span class="token" style="color: #6a737d;"> Scan directories for &quot;su&quot; binary, if found return true.</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">for</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token" style="color: #d73a49;">char</span><span class="token" style="color: #d73a49;">*</span><span class="token"> path</span><span class="token" style="color: #d73a49;">:</span><span class="token"> paths</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        std</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">string fullPath </span><span class="token" style="color: #d73a49;">=</span><span class="token"> std</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #6f42c1;">string</span><span class="token">(</span><span class="token">path</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">su</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        std</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #d73a49;">:</span><span class="token">ifstream </span><span class="token" style="color: #6f42c1;">file</span><span class="token">(</span><span class="token">fullPath</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #24292e;">file</span><span class="token">.</span><span class="token" style="color: #6f42c1;">good</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">file</span><span class="token">.</span><span class="token" style="color: #6f42c1;">close</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">return</span><span class="token"> JNI_TRUE</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> JNI_FALSE</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1982"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1980">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1981'
	>
	A small Java class is then created to serve as a bridge between the Java code and the native C/C++ code in the application. It uses JNI (Java Native Interface) to perform the native task.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1984"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">class</span><span class="token"> </span><span class="token" style="color: #6f42c1;">NativeChecks</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">System</span><span class="token">.</span><span class="token" style="color: #6f42c1;">loadLibrary</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">tamper-lib</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token" style="color: #d73a49;">native</span><span class="token"> </span><span class="token" style="color: #d73a49;">boolean</span><span class="token"> </span><span class="token" style="color: #6f42c1;">CheckSuBinaryNative</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1987"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1985">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1986'
	>
	Under normal circumstances, you wouldn’t have access to the source code. However, a common way to reverse engineer the application is by decompiling it using <a href="https://github.com/skylot/jadx">JADX</a>, which can be done with the following command.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1989"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">$ jadx </span><span class="token" style="color: #d73a49;">-</span><span class="token">d </span><span class="token" style="color: #6f42c1;">$</span><span class="token">(</span><span class="token">pwd</span><span class="token">)</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #24292e;">TamperLab_Decompiled</span><span class="token"> </span><span class="token" style="color: #6f42c1;">$</span><span class="token">(</span><span class="token">pwd</span><span class="token">)</span><span class="token" style="color: #d73a49;">/</span><span class="token" style="color: #24292e;">TamperLab</span><span class="token">.</span><span class="token" style="color: #24292e;">apk</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1992"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1990">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1991'
	>
	Once decompiled, your application may contain various libraries. You can easily filter through them by searching for files with the .so extension, which indicates native libraries.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1994"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-html github-light" data-language="html" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">$ find TamperLab_Decompiled -type f -name &quot;*.so&quot;                        
</span></span><span class="line"><span class="token">TamperLab_Decompiled/resources/lib/arm64-v8a/libtamper-lib.so
</span></span><span class="line"><span class="token">TamperLab_Decompiled/resources/lib/arm64-v8a/libtoolChecker.so
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-1997"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-1995">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-1996'
	>
	To reverse engineer the library, tools such as <a href="https://github.com/NationalSecurityAgency/ghidra">Ghidra</a> or <a href="https://hex-rays.com/ida-pro">IDA Pro</a> can be used. In this case, Ghidra was used.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2000"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-1998"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-1999">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_5.webp"
					class="image__img block-media__image-img"
					alt="Ghidra decompiled view of libtamper-lib.so native library showing ifstream file check logic, JNI_TRUE return (1) if su binary found, and JNI_FALSE return (0) if not found"
										height="675"
															width="877"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2003"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2001">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2002'
	>
	The decompiled code shows that ifstream is first used (1) to check whether the file exists. Based on this check, the function returns \x01 (JNI_TRUE) (2) if the su binary is found, otherwise, it returns \x00 (JNI_FALSE) (3).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2006"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2004">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2005'
	>
	Since this is a JNI function and is exposed using extern &#8220;C&#8221;, it appears in the symbol table with the exact name observed in Ghidra.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2008"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Java_com_hacking_tamperlab_NativeChecks_CheckSuBinaryNative</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2011"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2009">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2010'
	>
	Bypassing such checks is relatively straightforward. To hook a native function using Frida, we use Interceptor.attach() and specify the target function using Module.findExportByName().</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2013"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Interceptor</span><span class="token">.</span><span class="token" style="color: #6f42c1;">attach</span><span class="token">(</span><span class="token" style="color: #24292e;">Module</span><span class="token">.</span><span class="token" style="color: #6f42c1;">findExportByName</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">libtamper-lib.so</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Java_com_hacking_tamperlab_NativeChecks_CheckSuBinaryNative</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    onEnter</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token"> </span><span class="token">(</span><span class="token">args</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">[i] CheckSuBinaryNative() called</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    onLeave</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token"> </span><span class="token">(</span><span class="token">retval</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[+] Overriding return with JNI_FALSE</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2016"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2014">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2015'
	>
	Since we are intercepting a function from the native library, we need to attach to the process while it is already running by using the -n parameter with the following command.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2018"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">frida </span><span class="token" style="color: #d73a49;">-</span><span class="token">U </span><span class="token" style="color: #d73a49;">-</span><span class="token">l </span><span class="token" style="color: #24292e;">evade_root</span><span class="token">.</span><span class="token" style="color: #24292e;">js</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token">n tamperlab
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2021"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2019">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2020'
	>
	As shown in the script&#8217;s output, we successfully bypass the check even though it resides within JNI code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2024"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2022"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2023">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_6.webp"
					class="image__img block-media__image-img"
					alt="Frida Interceptor.attach output showing successful override of CheckSuBinaryNative() return value to JNI_FALSE, bypassing native C/C++ SU binary detection"
										height="320"
															width="745"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2027"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2025">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2026'
	>
	Another clever approach is to hook the open() function instead of the entire native function implemented in the application.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2030"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2028">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2029'
	>
	Since std::ifstream() ultimately invokes the open() system call, we can hook open() to intercept any attempt to access a binary whose path contains &#8220;su&#8221;. We can then substitute that path with a fake one to bypass the check.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2032"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Interceptor</span><span class="token">.</span><span class="token" style="color: #6f42c1;">attach</span><span class="token">(</span><span class="token" style="color: #24292e;">Module</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getExportByName</span><span class="token">(</span><span class="token" style="color: #005cc5;">null</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">open</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    onEnter</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token"> </span><span class="token">(</span><span class="token">args</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">const</span><span class="token"> path </span><span class="token" style="color: #d73a49;">=</span><span class="token"> args</span><span class="token">[</span><span class="token" style="color: #005cc5;">0</span><span class="token">]</span><span class="token">.</span><span class="token" style="color: #6f42c1;">readUtf8String</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #24292e;">path</span><span class="token">.</span><span class="token" style="color: #6f42c1;">includes</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">su</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">[i] called open(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> path </span><span class="token" style="color: #d73a49;">+</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">+</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">);</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[i] App searching for the &#039;su&#039; binary</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[+] Overriding with random path value.</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">const</span><span class="token"> newPath </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">Memory</span><span class="token">.</span><span class="token" style="color: #6f42c1;">allocUtf8String</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/dev/null</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            args</span><span class="token">[</span><span class="token" style="color: #005cc5;">0</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> newPath</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2035"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2033">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2034'
	>
	As shown in the image, this technique effectively bypasses native checks early by using the -f flag to hook before execution, unlike the -n flag, which attaches the hook while the process is already running.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2038"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2036"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2037">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_7.webp"
					class="image__img block-media__image-img"
					alt="Frida script hooking the open() system call to redirect any path containing &quot;su&quot; to /dev/null, bypassing native root detection before process execution using the -f flag"
										height="475"
															width="868"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2041"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2039">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-2040'
	>
	Spoofing /proc/mounts</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2044"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2042">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2043'
	>
	Nowadays, many Android devices are commonly rooted using <a href="https://github.com/topjohnwu/Magisk">Magisk</a>, which comes with a variety of built-in features.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2047"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2045">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2046'
	>
	The /proc/mounts file contains a list of all currently mounted filesystems on the device. Additionally, when a device is rooted using Magisk, it modifies the boot image and mounts partitions dynamically by default, so you may find traces of Magisk there as well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2050"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2048"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2049">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_8.webp"
					class="image__img block-media__image-img"
					alt="Contents of /proc/mounts on a Magisk-rooted Android device showing magisk-related mount entries that reveal root status to detection mechanisms"
										height="171"
															width="1028"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2053"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2051">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2052'
	>
	An implementation to detect this might look like the following, where an application reads the contents of /proc/mounts in search of Magisk.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2055"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-html github-light" data-language="html" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">public static boolean isMagiskInMounts() {
</span></span><span class="line"><span class="token">  try {
</span></span><span class="line"><span class="token">    BufferedReader reader = new BufferedReader(new FileReader(&quot;/proc/mounts&quot;));
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    String line;
</span></span><span class="line"><span class="token">    while ((line = reader.readLine()) != null) {
</span></span><span class="line"><span class="token">      if (line.contains(&quot;magisk&quot;)        ||
</span></span><span class="line"><span class="token">          line.contains(&quot;/sbin/.magisk&quot;) ||
</span></span><span class="line"><span class="token">          line.contains(&quot;/dev/&quot;) &amp;&amp; line.contains(&quot;magisk&quot;)) {
</span></span><span class="line"><span class="token">        return true;
</span></span><span class="line"><span class="token">      }
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">    reader.close();
</span></span><span class="line"><span class="token">  } catch (IOException e) {
</span></span><span class="line"><span class="token">    e.printStackTrace();
</span></span><span class="line"><span class="token">  }
</span></span><span class="line"><span class="token">  return false;
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2058"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2056">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2057'
	>
	To bypass this, we can create a script like the following, where we define a list of mounts that don’t contain Magisk traces or any other suspicious entries, for that matter.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2061"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2059">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2060'
	>
	The first interceptor hooks the open() system call to capture the file descriptor used when accessing /proc/mounts.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2064"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2062">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2063'
	>
	The second interceptor hooks read(), checks if the file descriptor corresponds to /proc/mounts, ensures the content hasn’t already been spoofed (to prevent repeated modifications and potential crashes), and finally replaces the buffer with our fake mount data defined at the top.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2066"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">const</span><span class="token"> fake_mounts </span><span class="token" style="color: #d73a49;">=</span><span class="token"> `
</span></span><span class="line"><span class="token" style="color: #d73a49;">/</span><span class="token">dev</span><span class="token" style="color: #d73a49;">/</span><span class="token">block</span><span class="token" style="color: #d73a49;">/</span><span class="token">dm</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">8</span><span class="token"> </span><span class="token" style="color: #d73a49;">/</span><span class="token"> ext4 ro</span><span class="token">,</span><span class="token">seclabel</span><span class="token">,</span><span class="token">relatime </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">tmpfs </span><span class="token" style="color: #d73a49;">/</span><span class="token">dev tmpfs rw</span><span class="token">,</span><span class="token">seclabel</span><span class="token">,</span><span class="token">nosuid</span><span class="token">,</span><span class="token">relatime</span><span class="token">,</span><span class="token">size</span><span class="token" style="color: #d73a49;">=</span><span class="token">3896612k</span><span class="token">,</span><span class="token">nr_inodes</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">974153</span><span class="token">,</span><span class="token">mode</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">755</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">devpts </span><span class="token" style="color: #d73a49;">/</span><span class="token">dev</span><span class="token" style="color: #d73a49;">/</span><span class="token">pts devpts rw</span><span class="token">,</span><span class="token">seclabel</span><span class="token">,</span><span class="token">relatime</span><span class="token">,</span><span class="token">mode</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">600</span><span class="token">,</span><span class="token">ptmxmode</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">000</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">proc </span><span class="token" style="color: #d73a49;">/</span><span class="token">proc proc rw</span><span class="token">,</span><span class="token">relatime</span><span class="token">,</span><span class="token">gid</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">3009</span><span class="token">,</span><span class="token">hidepid</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">2</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">sysfs </span><span class="token" style="color: #d73a49;">/</span><span class="token">sys sysfs rw</span><span class="token">,</span><span class="token">seclabel</span><span class="token">,</span><span class="token">relatime </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">selinuxfs </span><span class="token" style="color: #d73a49;">/</span><span class="token">sys</span><span class="token" style="color: #d73a49;">/</span><span class="token">fs</span><span class="token" style="color: #d73a49;">/</span><span class="token">selinux selinuxfs rw</span><span class="token">,</span><span class="token">relatime </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">tmpfs </span><span class="token" style="color: #d73a49;">/</span><span class="token">mnt tmpfs rw</span><span class="token">,</span><span class="token">seclabel</span><span class="token">,</span><span class="token">nosuid</span><span class="token">,</span><span class="token">nodev</span><span class="token">,</span><span class="token">noexec</span><span class="token">,</span><span class="token">relatime</span><span class="token">,</span><span class="token">size</span><span class="token" style="color: #d73a49;">=</span><span class="token">3896612k</span><span class="token">,</span><span class="token">nr_inodes</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">974153</span><span class="token">,</span><span class="token">mode</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">755</span><span class="token">,</span><span class="token">gid</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">1000</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">tmpfs </span><span class="token" style="color: #d73a49;">/</span><span class="token">mnt</span><span class="token" style="color: #d73a49;">/</span><span class="token">installer tmpfs rw</span><span class="token">,</span><span class="token">seclabel</span><span class="token">,</span><span class="token">nosuid</span><span class="token">,</span><span class="token">nodev</span><span class="token">,</span><span class="token">noexec</span><span class="token">,</span><span class="token">relatime</span><span class="token">,</span><span class="token">size</span><span class="token" style="color: #d73a49;">=</span><span class="token">3896612k</span><span class="token">,</span><span class="token">nr_inodes</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">974153</span><span class="token">,</span><span class="token">mode</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">755</span><span class="token">,</span><span class="token">gid</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #005cc5;">1000</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">
</span></span><span class="line"><span class="token">`</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">const</span><span class="token"> fakeMountBuffer </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">Memory</span><span class="token">.</span><span class="token" style="color: #6f42c1;">allocUtf8String</span><span class="token">(</span><span class="token">fake_mounts</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">let fakeMountFds </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">new</span><span class="token"> </span><span class="token" style="color: #6f42c1;">Set</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">let hasSpoofed </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">false</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">Interceptor</span><span class="token">.</span><span class="token" style="color: #6f42c1;">attach</span><span class="token">(</span><span class="token" style="color: #24292e;">Module</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getExportByName</span><span class="token">(</span><span class="token" style="color: #005cc5;">null</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">open</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    onEnter</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">args</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">path</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">Memory</span><span class="token">.</span><span class="token" style="color: #6f42c1;">readUtf8String</span><span class="token">(</span><span class="token">args</span><span class="token">[</span><span class="token" style="color: #005cc5;">0</span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    onLeave</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">retval</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">path</span><span class="token"> </span><span class="token" style="color: #d73a49;">===</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/proc/mounts</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">[i] /proc/mounts opened -&gt; file descriptor:</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">fakeMountFds</span><span class="token">.</span><span class="token" style="color: #6f42c1;">add</span><span class="token">(</span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">Interceptor</span><span class="token">.</span><span class="token" style="color: #6f42c1;">attach</span><span class="token">(</span><span class="token" style="color: #24292e;">Module</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getExportByName</span><span class="token">(</span><span class="token" style="color: #005cc5;">null</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #032f62;">read</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    onEnter</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">args</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">fd</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> args</span><span class="token">[</span><span class="token" style="color: #005cc5;">0</span><span class="token">]</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">buf</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> args</span><span class="token">[</span><span class="token" style="color: #005cc5;">1</span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">count</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> args</span><span class="token">[</span><span class="token" style="color: #005cc5;">2</span><span class="token">]</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    onLeave</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">retval</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #24292e;">fakeMountFds</span><span class="token">.</span><span class="token" style="color: #6f42c1;">has</span><span class="token">(</span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">fd</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d73a49;">!</span><span class="token">hasSpoofed</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">const</span><span class="token"> length </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">fake_mounts</span><span class="token">.</span><span class="token" style="color: #24292e;">length</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token">length </span><span class="token" style="color: #d73a49;">&lt;=</span><span class="token"> </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">count</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                    hasSpoofed </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                    </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[+] Spoofing read() from /proc/mounts with fake one.</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                    </span><span class="token" style="color: #24292e;">Memory</span><span class="token">.</span><span class="token" style="color: #6f42c1;">copy</span><span class="token">(</span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">buf</span><span class="token">,</span><span class="token"> fakeMountBuffer</span><span class="token">,</span><span class="token"> length</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                    </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token">length</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                    </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[-] Buffer too small to spoof.</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #d73a49;">else</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[+] /proc/mounts already spoofed, continuing...</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2069"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2067">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2068'
	>
	By running the hook, we successfully spoof the contents of /proc/mounts with our fake data, effectively bypassing the detection check.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2072"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2070"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2071">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_9.webp"
					class="image__img block-media__image-img"
					alt="Frida script output confirming successful spoofing of /proc/mounts read() call with clean fake mount data, bypassing Magisk detection"
										height="446"
															width="982"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2075"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2073">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2074'
	>
	It’s important to note that these techniques can be implemented and bypassed in various ways. Consequently, multiple solutions and countermeasures exist to address them.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2078"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2076">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-2077'
	>
	Anti-Hooking Protections</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2081"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2079">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2080'
	>
	Hooking is a powerful technique used during mobile penetration tests because it allows intercepting, modifying, and monitoring an application’s behavior at runtime. It provides direct access to function calls, arguments, return values, and the internal logic of methods.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2084"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2082">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2083'
	>
	To perform such attacks, <a href="https://github.com/frida/frida">Frida</a> is a widely used tool that enables pentesters and attackers to bypass security controls or extract potentially sensitive data.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2087"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2085">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-2086'
	>
	Frida Port Detection</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2090"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2088">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2089'
	>
	A common way to detect Frida is by checking for open frida-server ports, since Frida communicates using WebSockets. Simple checks often look for ports like 27042 or 27043, which are the default ports used by Frida.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2093"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2091">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2092'
	>
	Such checks can be easily bypassed by simply starting the Frida server on a different port using the following command.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2095"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">.</span><span class="token" style="color: #d73a49;">/</span><span class="token">frida</span><span class="token" style="color: #d73a49;">-</span><span class="token">server</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">16.5</span><span class="token">.</span><span class="token" style="color: #b31d28;font-style: italic;">9</span><span class="token" style="color: #d73a49;">-</span><span class="token">android</span><span class="token" style="color: #d73a49;">-</span><span class="token">arm64 </span><span class="token" style="color: #d73a49;">-</span><span class="token">l </span><span class="token" style="color: #005cc5;">0.0</span><span class="token">.</span><span class="token">0</span><span class="token">.</span><span class="token">0</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #005cc5;">1337</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2098"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2096">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2097'
	>
	A more advanced detection method involves scanning all ports by sending specific HTTP requests and checking for a 101 Switching Protocols response, which indicates the presence of a Frida server.An example of such native code would involve sending a WebSocket upgrade request to every open port on the device. If the response contains 101 Switching Protocols, it confirms that a Frida server has been successfully detected.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2100"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">for</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d73a49;">int</span><span class="token"> </span><span class="token" style="color: #24292e;">i</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">;</span><span class="token"> i </span><span class="token" style="color: #d73a49;">&lt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">65535</span><span class="token">;</span><span class="token"> i</span><span class="token" style="color: #d73a49;">++</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #6f42c1;">connect</span><span class="token">(</span><span class="token">sock</span><span class="token">,</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d73a49;">const</span><span class="token"> struct sockaddr</span><span class="token" style="color: #d73a49;">*</span><span class="token">)</span><span class="token" style="color: #d73a49;">&amp;</span><span class="token">addr</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">sizeof</span><span class="token">(</span><span class="token">addr</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">==</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">snprintf</span><span class="token">(</span><span class="token">req</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">sizeof</span><span class="token">(</span><span class="token">req</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">GET /ws HTTP/1.1</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Host: %s:%d</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Upgrade: websocket</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Connection: Upgrade</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Sec-WebSocket-Key: CpxD2C5REVLHvsUC9YAoqg==</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Sec-WebSocket-Version: 13</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">User-Agent: Frida</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">                 </span><span class="token" style="color: #6f42c1;">inet_ntoa</span><span class="token">(</span><span class="token" style="color: #24292e;">addr</span><span class="token">.</span><span class="token" style="color: #24292e;">sin_addr</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">ntohs</span><span class="token">(</span><span class="token" style="color: #24292e;">addr</span><span class="token">.</span><span class="token" style="color: #24292e;">sin_port</span><span class="token">)</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">write</span><span class="token">(</span><span class="token">sock</span><span class="token">,</span><span class="token"> req</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">strlen</span><span class="token">(</span><span class="token">req</span><span class="token">)</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        ssize_t bytes_read </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #6f42c1;">read</span><span class="token">(</span><span class="token">sock</span><span class="token">,</span><span class="token"> res</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #6f42c1;">sizeof</span><span class="token">(</span><span class="token">res</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">-</span><span class="token"> </span><span class="token" style="color: #005cc5;">1</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token">bytes_read </span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                res</span><span class="token">[</span><span class="token">bytes_read</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&#039;</span><span class="token" style="color: #005cc5;">\0</span><span class="token" style="color: #032f62;">&#039;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #6f42c1;">strstr</span><span class="token">(</span><span class="token">res</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">101 Switching Protocols</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                    </span><span class="token" style="color: #6f42c1;">close</span><span class="token">(</span><span class="token">sock</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">return</span><span class="token"> JNI_TRUE</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2103"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2101">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2102'
	>
	This check can be bypassed by hooking the read() calls and inspecting the buffer content after the call completes. If the buffer contains 101 Switching Protocols, indicating a Frida server query, we can modify the response to something benign such as HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n to evade detection.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2105"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Interceptor</span><span class="token">.</span><span class="token" style="color: #6f42c1;">attach</span><span class="token">(</span><span class="token" style="color: #24292e;">Module</span><span class="token">.</span><span class="token" style="color: #6f42c1;">findExportByName</span><span class="token">(</span><span class="token" style="color: #005cc5;">null</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">read</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">    onEnter</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">args</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">buffer</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> args</span><span class="token">[</span><span class="token" style="color: #005cc5;">1</span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">size</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> args</span><span class="token">[</span><span class="token" style="color: #005cc5;">2</span><span class="token">]</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">curr_retval</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line"><span class="token">    onLeave</span><span class="token" style="color: #d73a49;">:</span><span class="token"> </span><span class="token" style="color: #6f42c1;">function</span><span class="token">(</span><span class="token">retval</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">curr_retval</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">toInt32</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">curr_retval</span><span class="token"> </span><span class="token" style="color: #d73a49;">&gt;</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #24292e;">response</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">buffer</span><span class="token">.</span><span class="token" style="color: #6f42c1;">readCString</span><span class="token">(</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #24292e;">response</span><span class="token">.</span><span class="token" style="color: #6f42c1;">includes</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">101 Switching Protocols</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">[i] Application detected Frida server via WebSocket</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">console</span><span class="token">.</span><span class="token" style="color: #6f42c1;">log</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\t</span><span class="token" style="color: #032f62;">[+] Modifying the WebSocket response</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">var</span><span class="token"> </span><span class="token" style="color: #24292e;">modifiedResponse</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">HTTP/1.1 200 OK</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">Content-Length: 0</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #005cc5;">\r</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #005cc5;">this</span><span class="token">.</span><span class="token" style="color: #24292e;">buffer</span><span class="token">.</span><span class="token" style="color: #6f42c1;">writeUtf8String</span><span class="token">(</span><span class="token">modifiedResponse</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">retval</span><span class="token">.</span><span class="token" style="color: #6f42c1;">replace</span><span class="token">(</span><span class="token" style="color: #24292e;">modifiedResponse</span><span class="token">.</span><span class="token" style="color: #24292e;">length</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">}</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2108"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2106">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2107'
	>
	As demonstrated, once the hook is executed, the check is successfully bypassed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2111"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2109"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2110">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_10.webp"
					class="image__img block-media__image-img"
					alt="Frida read() hook modifying WebSocket 101 Switching Protocols response to HTTP 200 OK, successfully bypassing Frida port detection across all 65535 ports"
										height="313"
															width="755"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2114"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2112">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-2113'
	>
	Frida Threads Detection</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2117"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2115">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2116'
	>
	In Linux-based environments (including Android), each process has a task directory located at /proc/self/task, containing a subdirectory for each thread within the process. Each of these subdirectories includes a comm file that holds the name of the corresponding thread.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2120"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2118">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2119'
	>
	When Frida is injected into a process, it typically creates several threads for its internal operations. These threads often have distinctive names such as frida, gum-js-loop, gmain, gdbus or some other which can be used to detect Frida&#8217;s presence.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2123"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2121">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2122'
	>
	To better understand this, we can run the following command on the device to retrieve the names of all threads for a specified process.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">PPID</span><span class="token" style="color: #d73a49;">=</span><span class="token" style="color: #6f42c1;">$</span><span class="token">(</span><span class="token">pidof </span><span class="token" style="color: #24292e;">com</span><span class="token">.</span><span class="token" style="color: #24292e;">hacking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">)</span><span class="token">;</span><span class="token"> </span><span class="token" style="color: #d73a49;">for</span><span class="token"> i in </span><span class="token" style="color: #d73a49;">/</span><span class="token">proc</span><span class="token" style="color: #d73a49;">/</span><span class="token">$PPID</span><span class="token" style="color: #d73a49;">/</span><span class="token">task</span><span class="token" style="color: #6a737d;">/*</span><span class="token" style="color: #6a737d;">; do cat &quot;$i/comm&quot; 2&gt;/dev/null; done
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2126">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2127'
	>
	As shown in the following snippet, this is the output of the thread list when no Frida hooks are active.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">cking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">Signal</span><span class="token"> </span><span class="token" style="color: #24292e;">Catcher</span><span class="token">
</span></span><span class="line"><span class="token">perfetto_hprof_
</span></span><span class="line"><span class="token">ADB</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #24292e;">JDWP</span><span class="token"> </span><span class="token" style="color: #24292e;">Connec</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">Jit</span><span class="token"> thread pool
</span></span><span class="line"><span class="token">mali</span><span class="token" style="color: #d73a49;">-</span><span class="token">utility</span><span class="token" style="color: #d73a49;">-</span><span class="token">wo
</span></span><span class="line"><span class="token">mali</span><span class="token" style="color: #d73a49;">-</span><span class="token">cmar</span><span class="token" style="color: #d73a49;">-</span><span class="token">backe
</span></span><span class="line"><span class="token">ged</span><span class="token" style="color: #d73a49;">-</span><span class="token">swd
</span></span><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2131">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2132'
	>
	When a Frida hook is applied to the process, threads named gmain and gdbus appear both associated with Frida’s runtime. This allows us to detect Frida based on the presence of these thread names.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2135"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">cking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">
</span></span><span class="line"><span class="token">perfetto_hprof_
</span></span><span class="line"><span class="token">ADB</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #24292e;">JDWP</span><span class="token"> </span><span class="token" style="color: #24292e;">Connec</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">Jit</span><span class="token"> thread pool
</span></span><span class="line"><span class="token">mali</span><span class="token" style="color: #d73a49;">-</span><span class="token">cmar</span><span class="token" style="color: #d73a49;">-</span><span class="token">backe
</span></span><span class="line"><span class="token" style="color: #24292e;">RenderThread</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">cking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">
</span></span><span class="line"><span class="token">gmain
</span></span><span class="line"><span class="token">gdbus
</span></span><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2136">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2137'
	>
	To detect this, we can use C++ code like the following, which loops through each comm file in the /proc/self/task directory to retrieve thread names and checks them against a list of common thread names used by Frida.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-php github-light" data-language="php" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">SNIP</span><span class="token" style="color: #d73a49;">...</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">DIR</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #005cc5;">dir</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">opendir</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/proc/self/task</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">[</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">SNIP</span><span class="token" style="color: #d73a49;">...</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">struct</span><span class="token"> </span><span class="token" style="color: #005cc5;">dirent</span><span class="token"> </span><span class="token" style="color: #d73a49;">*</span><span class="token" style="color: #005cc5;">entry</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">char</span><span class="token"> </span><span class="token" style="color: #005cc5;">path</span><span class="token">[</span><span class="token" style="color: #005cc5;">PATH_MAX</span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">char</span><span class="token"> </span><span class="token" style="color: #005cc5;">comm</span><span class="token">[</span><span class="token" style="color: #005cc5;">256</span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">while</span><span class="token"> </span><span class="token">(</span><span class="token">(</span><span class="token" style="color: #005cc5;">entry</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">readdir</span><span class="token">(</span><span class="token" style="color: #005cc5;">dir</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">!=</span><span class="token"> </span><span class="token" style="color: #005cc5;">NULL</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">[</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">SNIP</span><span class="token" style="color: #d73a49;">...</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #6f42c1;">snprintf</span><span class="token">(</span><span class="token" style="color: #005cc5;">path</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">sizeof</span><span class="token">(</span><span class="token" style="color: #005cc5;">path</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">/proc/self/task/%s/comm</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">entry</span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token" style="color: #24292e;">d_name</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">[</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">SNIP</span><span class="token" style="color: #d73a49;">...</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">fgets</span><span class="token">(</span><span class="token" style="color: #005cc5;">comm</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">sizeof</span><span class="token">(</span><span class="token" style="color: #005cc5;">comm</span><span class="token">)</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">fp</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">!=</span><span class="token"> </span><span class="token" style="color: #005cc5;">NULL</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #005cc5;">comm</span><span class="token">[</span><span class="token" style="color: #005cc5;">strcspn</span><span class="token">(</span><span class="token" style="color: #005cc5;">comm</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">\n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">0</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #005cc5;">strstr</span><span class="token">(</span><span class="token" style="color: #005cc5;">comm</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">frida</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #d73a49;">||</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #005cc5;">strstr</span><span class="token">(</span><span class="token" style="color: #005cc5;">comm</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">gum</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">   </span><span class="token" style="color: #d73a49;">||</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #005cc5;">strstr</span><span class="token">(</span><span class="token" style="color: #005cc5;">comm</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">gmain</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #005cc5;">fclose</span><span class="token">(</span><span class="token" style="color: #005cc5;">fp</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #005cc5;">closedir</span><span class="token">(</span><span class="token" style="color: #005cc5;">dir</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">JNI_TRUE</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">fclose</span><span class="token">(</span><span class="token" style="color: #005cc5;">fp</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #005cc5;">closedir</span><span class="token">(</span><span class="token" style="color: #005cc5;">dir</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #005cc5;">JNI_FALSE</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">[</span><span class="token" style="color: #d73a49;">...</span><span class="token" style="color: #005cc5;">SNIP</span><span class="token" style="color: #d73a49;">...</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2141">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2142'
	>
	One intriguing approach to evade detection is to patch the entire frida-server binary by replacing all occurrences of strings like gmain. By searching for gmain in Ghidra, we can observe the following results.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2144"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2145">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_11.webp"
					class="image__img block-media__image-img"
					alt="Ghidra search results showing multiple occurrences of the &quot;gmain&quot; string inside the frida-server binary, used for Frida thread name detection"
										height="522"
															width="917"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2147">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2148'
	>
	By selecting one of the instances, we can examine the disassembled code to pinpoint its exact location.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2150"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2151">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_12.webp"
					class="image__img block-media__image-img"
					alt="Ghidra disassembly view showing exact memory location of the gmain string in the frida-server binary for targeted patching"
										height="305"
															width="848"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2153">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2154'
	>
	We can now use Ghidra’s built-in hex editor to modify these strings, replacing gmain with another string, such as hackr.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2156"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2157">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_13.webp"
					class="image__img block-media__image-img"
					alt="Ghidra hex editor view showing gmain string being replaced with hackr to rename Frida&#039;s internal thread and evade thread-name-based detection"
										height="247"
															width="933"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2159">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2160'
	>
	After injecting the Frida hook, we can see that we have successfully bypassed the detection, as it no longer identifies Frida’s threads.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2162"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2163">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_14.webp"
					class="image__img block-media__image-img"
					alt="Frida injection output after frida-server binary patch showing Frida threads no longer detected, with renamed thread appearing as hackr instead of gmain"
										height="310"
															width="478"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2165">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2166'
	>
	If we loop through the thread names again for the application we are attacking, we can see that it now successfully contains the hackr thread name.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">cking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">ReferenceQueueD</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">FinalizerDaemon</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">FinalizerWatchd</span><span class="token">
</span></span><span class="line"><span class="token">binder</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #005cc5;">7261_1</span><span class="token">
</span></span><span class="line"><span class="token">binder</span><span class="token" style="color: #d73a49;">:</span><span class="token" style="color: #005cc5;">7261_2</span><span class="token">
</span></span><span class="line"><span class="token">hackr
</span></span><span class="line"><span class="token">gdbus
</span></span><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2170">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2171'
	>
	Of course, there are other detectable strings, but this simple example demonstrates one way to bypass detection by directly patching the frida-server binary yourself. This way you could build an entirely different frida-server to avoid detections or modify the original source code as well.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2173">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-2174'
	>
	Anti-Debug Protections</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2176">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2177'
	>
	Anti-debug protections are another way to protect your Android application from reverse engineering. These mechanisms aim to detect or prevent debugging attempts, stopping attackers from stepping through the app’s code instruction by instruction to understand its internal logic.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2181"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2179">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2180'
	>
	Like most security measures, anti-debug mechanisms can also be bypassed using Frida hooks. However, I want to show you how you can defeat these protections using a debugger itself.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2184"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2182">
	<h3	class='typography typography--size-36-text js-typography block-typography__typography'
	data-id='es-2183'
	>
	Defeating Anti-Debug using Debugger</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2187"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2185">
	<h4	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-2186'
	>
	isDebuggerConnected()</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2190"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2188">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2189'
	>
	This is a simple, ready-made function that checks if a debugger is connected to the application. It returns true if a debugger is detected, otherwise, it returns false.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2193"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2191">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2192'
	>
	Implementing such a function is straightforward, and you can call it as follows:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2195"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #24292e;">Debug</span><span class="token">.</span><span class="token" style="color: #6f42c1;">isDebuggerConnected</span><span class="token">(</span><span class="token">)</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2198"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2196">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2197'
	>
	To use the debugger and bypass this check, we can utilize JADX’s integrated debugger. Before launching it, ensure the application is already running.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2201"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2199">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2200'
	>
	Another way to start an application is by using the following ADB command, which will launch the app but pause and wait for the debugger to attach.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2203"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">adb shell am set</span><span class="token" style="color: #d73a49;">-</span><span class="token">debug</span><span class="token" style="color: #d73a49;">-</span><span class="token">app </span><span class="token" style="color: #d73a49;">-</span><span class="token">w </span><span class="token" style="color: #24292e;">com</span><span class="token">.</span><span class="token" style="color: #24292e;">hacking</span><span class="token">.</span><span class="token" style="color: #24292e;">tamperlab</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2206"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2204">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2205'
	>
	As shown, when you launch the application, it will display a message indicating that it is waiting for a debugger.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2209"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2207"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2208">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_15.webp"
					class="image__img block-media__image-img"
					alt="Android device screen showing &quot;Waiting For Debugger&quot; dialog after launching TamperLab with ADB debug flag, pausing app execution until debugger attaches"
										height="214"
															width="355"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2212"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2210">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2211'
	>
	In my case, it doesn’t work, but I can open the application without it waiting for the debugger. However, your application might require this behavior, so it’s important to test both methods.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2213">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2214'
	>
	Additionally, whenever you’re done or close the application, make sure to run the following command to remove the app from waiting for a debugger.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2217"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">adb shell am clear</span><span class="token" style="color: #d73a49;">-</span><span class="token">debug</span><span class="token" style="color: #d73a49;">-</span><span class="token">app
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2220"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2218">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2219'
	>
	Once ready, you can open JADX and load the APK file of the target application. You can also pull the APK from your device using ADB.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2221">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2222'
	>
	Once loaded into JADX, select the green bug icon, which opens a dialog prompting you to choose the application to debug along with its process ID.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2226"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2224"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2225">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_16.webp"
					class="image__img block-media__image-img"
					alt="JADX integrated debugger showing process selection dialog for com.hacking.tamperlab to attach debugger to the running TamperLab application"
										height="255"
															width="864"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2229"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2227">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2228'
	>
	After the debugger attaches, the application’s execution is automatically paused inside the MainActivity. You can then press the green play button to continue running the application.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2232"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2230"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2231">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_17.webp"
					class="image__img block-media__image-img"
					alt="JADX debugger paused at MainActivity entry point after attaching, with green play button ready to resume application execution"
										height="377"
															width="968"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2235"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2233">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2234'
	>
	Once you find the correct position to set a breakpoint, you can do so by pressing the F2 key. For this example, I set the breakpoint exactly where the isDebuggerConnected() function is called.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2236"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2237">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_18.webp"
					class="image__img block-media__image-img"
					alt="JADX debugger showing breakpoint set on invoke-static opcode calling isDebuggerConnected(), with v0 register visible in the debug variables panel"
										height="239"
															width="957"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2241"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2239">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2240'
	>
	The following instruction essentially calls the isDebuggerConnected() function using the invoke-static opcode.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2243"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">invoke</span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #d73a49;">static</span><span class="token"> </span><span class="token">{</span><span class="token">}</span><span class="token">,</span><span class="token"> Landroid</span><span class="token" style="color: #d73a49;">/</span><span class="token">os</span><span class="token" style="color: #d73a49;">/</span><span class="token">Debug</span><span class="token">;</span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token" style="color: #6f42c1;">isDebuggerConnected</span><span class="token">(</span><span class="token">)</span><span class="token">Z # method</span><span class="token">@</span><span class="token" style="color: #d73a49;">0008</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2246"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2244">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2245'
	>
	Then, the move-result instruction moves the return value of the function (either true or false) into the v0 register.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2248"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-html github-light" data-language="html" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">move-result v0
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2251"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2249">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2250'
	>
	By stepping over these two instructions, we can observe that the v0 register contains the value 1, indicating that a debugger has been detected.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2254"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2252"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2253">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_19.webp"
					class="image__img block-media__image-img"
					alt="JADX debugger showing v0 register containing value 1 (true) after move-result instruction, confirming debugger was detected by isDebuggerConnected()"
										height="324"
															width="1129"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2257"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2255">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2256'
	>
	To bypass this check, we can simply set the value to 0 using the debugger, as shown below:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2260"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2258"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2259">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_20.webp"
					class="image__img block-media__image-img"
					alt="JADX debugger view showing v0 register value manually overridden to 0 (false) to bypass isDebuggerConnected() check during live debugging session"
										height="302"
															width="1139"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2263"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2261">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2262'
	>
	Continuing the application’s execution, we successfully bypass the check by manipulating the variables during debugging.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2266"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2264"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2265">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_21.webp"
					class="image__img block-media__image-img"
					alt="TamperLab app showing green checkmark after successfully bypassing isDebuggerConnected() anti-debug protection by manipulating register value in JADX debugger"
										height="261"
															width="344"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2269"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2267">
	<h4	class='typography typography--size-24-text js-typography block-typography__typography'
	data-id='es-2268'
	>
	Detection via USB &amp; ADB</h4></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2272"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2270">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2271'
	>
	Another interesting way to detect debugging is by checking if the device is connected via USB with ADB enabled. While this isn’t a direct debugger detection method, it remains a useful check nonetheless.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2275"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2273">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2274'
	>
	A simple implementation might look like the following, where the app dynamically listens for the USB_STATE broadcast and parses the connected and adb boolean extras from the received intent.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2277"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-java github-light" data-language="java" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #24292e;">IntentFilter</span><span class="token"> </span><span class="token" style="color: #24292e;">filter</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">new</span><span class="token"> </span><span class="token" style="color: #6f42c1;">IntentFilter</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">android.hardware.usb.action.USB_STATE</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">BroadcastReceiver</span><span class="token"> </span><span class="token" style="color: #24292e;">usbReceiver</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">new</span><span class="token"> </span><span class="token" style="color: #6f42c1;">BroadcastReceiver</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">@</span><span class="token" style="color: #d73a49;">Override</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">public</span><span class="token"> </span><span class="token" style="color: #d73a49;">void</span><span class="token"> </span><span class="token" style="color: #6f42c1;">onReceive</span><span class="token">(</span><span class="token" style="color: #24292e;">Context</span><span class="token"> </span><span class="token" style="color: #e36209;">ctx</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #24292e;">Intent</span><span class="token"> </span><span class="token" style="color: #e36209;">intent</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">boolean</span><span class="token"> </span><span class="token" style="color: #24292e;">connected</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">intent</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getBooleanExtra</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">connected</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">false</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">boolean</span><span class="token"> </span><span class="token" style="color: #24292e;">adbEnabled</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">intent</span><span class="token">.</span><span class="token" style="color: #6f42c1;">getBooleanExtra</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">adb</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #005cc5;">false</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">callback</span><span class="token">.</span><span class="token" style="color: #6f42c1;">accept</span><span class="token">(</span><span class="token">connected </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> adbEnabled</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #24292e;">ctx</span><span class="token">.</span><span class="token" style="color: #6f42c1;">unregisterReceiver</span><span class="token">(</span><span class="token" style="color: #005cc5;">this</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">context</span><span class="token">.</span><span class="token" style="color: #6f42c1;">registerReceiver</span><span class="token">(</span><span class="token">usbReceiver</span><span class="token">,</span><span class="token"> filter</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #24292e;">Intent</span><span class="token"> </span><span class="token" style="color: #24292e;">sticky</span><span class="token"> </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #24292e;">context</span><span class="token">.</span><span class="token" style="color: #6f42c1;">registerReceiver</span><span class="token">(</span><span class="token" style="color: #005cc5;">null</span><span class="token">,</span><span class="token"> filter</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">if</span><span class="token"> </span><span class="token">(</span><span class="token">sticky </span><span class="token" style="color: #d73a49;">!=</span><span class="token"> </span><span class="token" style="color: #005cc5;">null</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #24292e;">usbReceiver</span><span class="token">.</span><span class="token" style="color: #6f42c1;">onReceive</span><span class="token">(</span><span class="token">context</span><span class="token">,</span><span class="token"> sticky</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line"><span class="token">[</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token" style="color: #24292e;">SNIP</span><span class="token">.</span><span class="token">.</span><span class="token">.</span><span class="token">]</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2280"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2278">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2279'
	>
	We can also bypass this check by using the debugger to place breakpoints at the appropriate locations.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2283"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2281">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2282'
	>
	In this case, I set a breakpoint on the if-eqz instructions, which checks whether the values in registers v0 and v2 are equal to zero. These registers correspond to the connected and adbEnabled flags.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2286"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2284">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2285'
	>
	When the breakpoint is hit, we observe that both values are set to 1 (true), indicating that USB is connected and ADB is enabled.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2289"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-2287"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-2288">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2026/03/image_22.webp"
					class="image__img block-media__image-img"
					alt="JADX debugger breakpoint showing if-eqz instructions with v0 (connected=1) and v2 (adbEnabled=1) registers, detecting USB connection with ADB enabled"
										height="501"
															width="1088"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2292"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2290">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2291'
	>
	We can now simply set these two values to 0 (false), causing the check to fail and allowing the app to continue execution.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2295"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2293">
	<h2	class='typography typography--size-52-default js-typography block-typography__typography'
	data-id='es-2294'
	>
	Conclusion</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2298"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2296">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2297'
	>
	We have explored several common anti-root, anti-hook, and anti-debug techniques and demonstrated how each can ultimately be bypassed. However, it is important to recognize that these protections still play a critical role in Android security.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2301"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2299">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2300'
	>
	No protection is entirely foolproof. Given enough time and the right tools, a determined attacker can often find a way around most defenses. However, the goal of these mechanisms isn’t to create an unbreakable application, but rather to increase the complexity of attacks. This raises the time, effort, and skill required for an attacker to compromise the application, which can deter casual attackers and slow down more advanced ones.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2304"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2302">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2303'
	>
	In short, while these security checks can be bypassed, they remain a valuable part of a defense-in-depth strategy. Labs like TamperLab that we have created, provide a practical environment where you can practice implementing these detection mechanisms and learn how to bypass them. It’s about making it hard enough that breaking the security is no longer worth the effort.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-2307"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-typography" data-id="es-2305">
	<p	class='typography typography--size-16-text-roman js-typography block-typography__typography'
	data-id='es-2306'
	>
	At Infinum, we help you stay ahead with tailored cybersecurity services, including <a href="https://infinum.com/cybersecurity/penetration-testing/" id="https://infinum.com/cybersecurity/penetration-testing/">penetration testing</a> and <a href="https://infinum.com/cybersecurity/red-teaming/" id="https://infinum.com/cybersecurity/red-teaming/">security assessments</a>. Whether launching new products or protecting existing ones, we identify weaknesses before attackers do so you can focus on what matters. Learn more about how we keep your digital world secure on our <a href="https://infinum.com/cybersecurity/">cybersecurity page</a>.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/understanding-defeating-android-protections/">Understanding &amp; Defeating Android Protections</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>