@base <https://codewall.ai/blog/how-we-hacked-bains-competitive-intelligence-platform> .
@prefix schema: <https://schema.org/> .
@prefix owl: <https://www.w3.org/2002/07/owl#> .

<#article> a schema:Article ;
  schema:headline "How We Hacked Bain's Competitive Intelligence Platform"@en ;
  schema:name "How We Hacked Bain's Competitive Intelligence Platform"@en ;
  schema:datePublished "2026-04-13" ;
  schema:inLanguage "en" ;
  schema:url <https://codewall.ai/blog/how-we-hacked-bains-competitive-intelligence-platform> ;
  schema:publisher <#codewall-blog> ;
  schema:author <#paul-price> ;
  schema:about
    <#bain>,
    <#pyxis>,
    <#autonomous-offensive-agent>,
    <#surface-mapping>,
    <#hardcoded-js-credential>,
    <#authenticated-foothold>,
    <#raw-sql-injection>,
    <#cross-database-service-account>,
    <#graphql-account-provisioning>,
    <#okta-directory-modification>,
    <#jwt-token-log-exposure>,
    <#bulk-extraction-path>,
    <#production-database-clone>,
    <#system-prompt-exposure>,
    <#responsible-disclosure> ;
  schema:articleSection
    "Mapping the Surface"@en,
    "Pulling the Thread"@en,
    "What Was on the Other Side"@en,
    "Beyond the Data"@en,
    "Three for Three"@en,
    "Responsible Disclosure Timeline"@en ;
  schema:abstract """The article claims an autonomous offensive agent obtained production access to Bain's Pyxis platform through hardcoded credentials in a public JavaScript bundle and then expanded that foothold into broad database and identity-layer access."""@en ;
  schema:articleBody """CodeWall presents Bain as the third member of an MBB series after McKinsey and BCG. The article says the agent mapped Bain's public surface, downloaded a JavaScript bundle from the Pyxis competitive-intelligence platform, extracted a hardcoded username and password, authenticated successfully, and then found an SQL injection path plus an over-privileged service account spanning eleven databases. It further claims exposure of 159 billion rows of consumer transaction data, thousands of AI conversations, GraphQL account creation with Okta modification, long-lived JWT tokens in activity logs, arbitrary export endpoints, single-call database cloning, and readable proprietary system prompts. The narrative is framed as evidence that continuous AI-driven offensive testing finds real attack chains traditional point-in-time pentests miss."""@en ;
  schema:hasPart
    <#part-map>,
    <#part-thread>,
    <#part-data>,
    <#part-escalation>,
    <#part-series>,
    <#part-disclosure> ;
  schema:mentions
    <#defined-terms>,
    <#research-sequence-howto>,
    <#faq-1>, <#faq-2>, <#faq-3>, <#faq-4>, <#faq-5>,
    <#faq-6>, <#faq-7>, <#faq-8>, <#faq-9>, <#faq-10>,
    <#codewall>,
    <#okta>,
    <#llama-3-1-405b> .

<#codewall-blog> a schema:Blog ;
  schema:name "CodeWall Research & News"@en ;
  schema:url <https://codewall.ai/blog> ;
  schema:publisher <#codewall> .

<#codewall> a schema:Organization ;
  schema:name "CodeWall"@en ;
  schema:url <https://codewall.ai/> .

<#paul-price> a schema:Person ;
  schema:name "Paul Price"@en ;
  schema:jobTitle "Founder & CEO"@en ;
  schema:affiliation <#codewall> ;
  schema:sameAs <https://www.linkedin.com/in/paulprice/> .

<#bain> a schema:Organization ;
  schema:name "Bain & Company"@en ;
  schema:url <https://www.bain.com/> .

<#pyxis> a schema:SoftwareApplication, schema:Product ;
  schema:name "Pyxis"@en ;
  schema:alternateName "Bain's Competitive Intelligence Platform"@en ;
  schema:brand <#bain> ;
  schema:url <https://www.pyxisbybain.com/> ;
  schema:applicationCategory "Competitive intelligence and analytics platform"@en ;
  schema:description """The article presents Pyxis as Bain's client-facing competitive-intelligence platform and the initial production entry point for the reported attack path."""@en .

<#okta> a schema:SoftwareApplication, schema:Product ;
  schema:name "Okta"@en ;
  schema:url <https://www.okta.com/> ;
  schema:applicationCategory "Identity and access management"@en .

<#llama-3-1-405b> a schema:SoftwareApplication ;
  schema:name "Llama 3.1 405B"@en ;
  schema:applicationCategory "Large language model"@en .

<#autonomous-offensive-agent> a schema:DefinedTerm ;
  schema:name "Autonomous offensive agent"@en ;
  schema:description """The article describes an agent that maps infrastructure, prioritizes targets, chains findings, and produces a full attack narrative with minimal manual guidance."""@en .

<#surface-mapping> a schema:DefinedTerm ;
  schema:name "Surface mapping"@en ;
  schema:description """The reconnaissance phase where the agent enumerated Bain's public subdomains, portals, and APIs to find exposed attack paths quickly."""@en .

<#hardcoded-js-credential> a schema:DefinedTerm ;
  schema:name "Hardcoded JavaScript credential exposure"@en ;
  schema:description """The article's initial flaw: a username and password embedded in a JavaScript bundle downloadable from the public Pyxis website."""@en .

<#authenticated-foothold> a schema:DefinedTerm ;
  schema:name "Authenticated foothold"@en ;
  schema:description """The article says the extracted service-account credential produced a fully authenticated session on the production Pyxis platform."""@en .

<#raw-sql-injection> a schema:DefinedTerm ;
  schema:name "Raw SQL injection through API error reflection"@en ;
  schema:description """The article claims a Pyxis API endpoint accepted raw SQL payloads and reflected query results through error messages, exposing the production database layer."""@en .

<#cross-database-service-account> a schema:DefinedTerm ;
  schema:name "Cross-database over-privileged service account"@en ;
  schema:description """The article says the service account behind the injection path held hundreds of roles and permissions with read-write access across eleven databases."""@en .

<#graphql-account-provisioning> a schema:DefinedTerm ;
  schema:name "GraphQL account provisioning path"@en ;
  schema:description """The article's most critical persistence path: a GraphQL endpoint that allowed arbitrary account creation after the initial foothold."""@en .

<#okta-directory-modification> a schema:DefinedTerm ;
  schema:name "Okta directory modification"@en ;
  schema:description """The article says the same GraphQL path allowed direct modification of Bain's Okta directory, enabling persistent access beyond simple credential rotation."""@en .

<#jwt-token-log-exposure> a schema:DefinedTerm ;
  schema:name "JWT token log exposure"@en ;
  schema:description """The article says activity logs stored 36,869 complete JWT tokens with employee emails and one-year expiry, enabling impersonation without MFA."""@en .

<#bulk-extraction-path> a schema:DefinedTerm ;
  schema:name "Bulk extraction path"@en ;
  schema:description """The article says multiple export endpoints accepted arbitrary SQL and attacker-controlled destinations, enabling cross-cloud bulk extraction from production data stores."""@en .

<#production-database-clone> a schema:DefinedTerm ;
  schema:name "Production database clone path"@en ;
  schema:description """The article states an attacker could trigger a full production database clone through a single API call after obtaining the foothold."""@en .

<#system-prompt-exposure> a schema:DefinedTerm ;
  schema:name "System prompt exposure"@en ;
  schema:description """The article says Pyxis conversation metadata exposed an 18,621-character proprietary AI system prompt containing methodology, schema definitions, and analytical frameworks."""@en .

<#responsible-disclosure> a schema:DefinedTerm ;
  schema:name "Responsible disclosure"@en ;
  schema:description """The article says testing was verification-only, evidence was shared with Bain's security team, fixes were confirmed, and publication happened only after remediation."""@en .

<#defined-terms> a schema:DefinedTermSet ;
  schema:name "Defined terms for How We Hacked Bain's Competitive Intelligence Platform"@en ;
  schema:hasPart
    <#autonomous-offensive-agent>,
    <#surface-mapping>,
    <#hardcoded-js-credential>,
    <#authenticated-foothold>,
    <#raw-sql-injection>,
    <#cross-database-service-account>,
    <#graphql-account-provisioning>,
    <#okta-directory-modification>,
    <#jwt-token-log-exposure>,
    <#bulk-extraction-path>,
    <#production-database-clone>,
    <#system-prompt-exposure>,
    <#responsible-disclosure> ;
  schema:isPartOf <#article> .

<#part-map> a schema:WebPageElement ;
  schema:name "Mapping the Surface"@en ;
  schema:position 1 ;
  schema:about <#surface-mapping>, <#hardcoded-js-credential>, <#authenticated-foothold> ;
  schema:text """The article says the agent mapped Bain's public infrastructure, downloaded a JavaScript bundle from Pyxis, extracted embedded credentials, and authenticated within eighteen minutes."""@en .

<#part-thread> a schema:WebPageElement ;
  schema:name "Pulling the Thread"@en ;
  schema:position 2 ;
  schema:about <#raw-sql-injection>, <#cross-database-service-account> ;
  schema:text """The article claims the agent then found an API path that reflected raw SQL results and that the supporting service account had broad read-write access across eleven databases."""@en .

<#part-data> a schema:WebPageElement ;
  schema:name "What Was on the Other Side"@en ;
  schema:position 3 ;
  schema:about <#pyxis>, <#cross-database-service-account> ;
  schema:text """The article says the reachable data included 159 billion rows of sanitized transaction data, mapped client schemas, thousands of AI conversations, and a large omnichannel dataset."""@en .

<#part-escalation> a schema:WebPageElement ;
  schema:name "Beyond the Data"@en ;
  schema:position 4 ;
  schema:about
    <#graphql-account-provisioning>,
    <#okta-directory-modification>,
    <#jwt-token-log-exposure>,
    <#bulk-extraction-path>,
    <#production-database-clone>,
    <#system-prompt-exposure> ;
  schema:text """The article extends impact to persistence and escalation: account creation, Okta changes, JWT impersonation, export abuse, single-call cloning, and proprietary prompt exposure."""@en .

<#part-series> a schema:WebPageElement ;
  schema:name "Three for Three"@en ;
  schema:position 5 ;
  schema:about <#autonomous-offensive-agent>, <#codewall> ;
  schema:text """The article frames Bain as the third MBB case and uses the result to argue that autonomous offensive testing finds weaknesses traditional periodic pentests miss."""@en .

<#part-disclosure> a schema:WebPageElement ;
  schema:name "Responsible Disclosure Timeline"@en ;
  schema:position 6 ;
  schema:about <#responsible-disclosure> ;
  schema:text """The article says reconnaissance began on March 12, 2026, disclosure was sent on March 17, evidence sharing continued through March 19, remediation completed March 19, and publication followed on April 13."""@en .

<#research-sequence-howto> a schema:HowTo ;
  schema:name "How the article describes the research sequence"@en ;
  schema:about <#autonomous-offensive-agent>, <#responsible-disclosure> ;
  schema:isPartOf <#article> ;
  schema:step <#step-1>, <#step-2>, <#step-3>, <#step-4> ;
  schema:description """The article presents a four-step sequence of reconnaissance, foothold acquisition, expansion into data and identity layers, and disclosure with remediation verification."""@en .

<#step-1> a schema:HowToStep ;
  schema:name "Map the public surface"@en ;
  schema:position 1 ;
  schema:text "The agent enumerated Bain's public infrastructure and isolated Pyxis as the most promising exposed target."@en ;
  schema:isPartOf <#research-sequence-howto> .

<#step-2> a schema:HowToStep ;
  schema:name "Extract and use the embedded credential"@en ;
  schema:position 2 ;
  schema:text "The article says a JavaScript bundle exposed a service-account username and password that produced an authenticated production session."@en ;
  schema:isPartOf <#research-sequence-howto> .

<#step-3> a schema:HowToStep ;
  schema:name "Chain database and identity escalation"@en ;
  schema:position 3 ;
  schema:text "The article says the foothold expanded into SQL injection, broad database access, GraphQL account creation, Okta modification, token harvesting, and export paths."@en ;
  schema:isPartOf <#research-sequence-howto> .

<#step-4> a schema:HowToStep ;
  schema:name "Disclose and verify remediation"@en ;
  schema:position 4 ;
  schema:text "The article states that Bain was notified, evidence was shared, credentials were rotated, vulnerabilities were remediated, and only then was the report published."@en ;
  schema:isPartOf <#research-sequence-howto> .

<#faq-1> a schema:Question ;
  schema:name "What platform did the article focus on?"@en ;
  schema:text "What platform did the article focus on?"@en ;
  schema:acceptedAnswer <#faq-1-answer> ;
  schema:isPartOf <#article> .
<#faq-1-answer> a schema:Answer ;
  schema:text "The article focused on Pyxis, described as Bain's competitive-intelligence platform."@en ;
  schema:isPartOf <#article> .

<#faq-2> a schema:Question ;
  schema:name "What was the claimed initial foothold?"@en ;
  schema:text "What was the claimed initial foothold?"@en ;
  schema:acceptedAnswer <#faq-2-answer> ;
  schema:isPartOf <#article> .
<#faq-2-answer> a schema:Answer ;
  schema:text "The article says a hardcoded username and password were embedded in a publicly downloadable JavaScript bundle and used to authenticate."@en ;
  schema:isPartOf <#article> .

<#faq-3> a schema:Question ;
  schema:name "How quickly does the article say access was obtained?"@en ;
  schema:text "How quickly does the article say access was obtained?"@en ;
  schema:acceptedAnswer <#faq-3-answer> ;
  schema:isPartOf <#article> .
<#faq-3-answer> a schema:Answer ;
  schema:text "The article says the agent obtained a foothold on Pyxis within eighteen minutes."@en ;
  schema:isPartOf <#article> .

<#faq-4> a schema:Question ;
  schema:name "What database-level issue was reported after login?"@en ;
  schema:text "What database-level issue was reported after login?"@en ;
  schema:acceptedAnswer <#faq-4-answer> ;
  schema:isPartOf <#article> .
<#faq-4-answer> a schema:Answer ;
  schema:text "The article claims an API endpoint accepted raw SQL payloads and reflected the results back through error messages."@en ;
  schema:isPartOf <#article> .

<#faq-5> a schema:Question ;
  schema:name "What scale of data exposure does the article describe?"@en ;
  schema:text "What scale of data exposure does the article describe?"@en ;
  schema:acceptedAnswer <#faq-5-answer> ;
  schema:isPartOf <#article> .
<#faq-5-answer> a schema:Answer ;
  schema:text "The article highlights 159 billion rows of sanitized consumer transaction data, mapped client schemas, 9,989 AI conversations, and a 2.5 billion-row omnichannel dataset."@en ;
  schema:isPartOf <#article> .

<#faq-6> a schema:Question ;
  schema:name "Why does the article emphasize the GraphQL path?"@en ;
  schema:text "Why does the article emphasize the GraphQL path?"@en ;
  schema:acceptedAnswer <#faq-6-answer> ;
  schema:isPartOf <#article> .
<#faq-6-answer> a schema:Answer ;
  schema:text "Because the article says it allowed arbitrary account creation and Okta directory modification, creating durable persistence beyond simple credential rotation."@en ;
  schema:isPartOf <#article> .

<#faq-7> a schema:Question ;
  schema:name "What role did JWT tokens play in the reported attack path?"@en ;
  schema:text "What role did JWT tokens play in the reported attack path?"@en ;
  schema:acceptedAnswer <#faq-7-answer> ;
  schema:isPartOf <#article> .
<#faq-7-answer> a schema:Answer ;
  schema:text "The article says activity logs stored 36,869 complete JWT tokens with employee emails and one-year expiry, enabling impersonation on the platform."@en ;
  schema:isPartOf <#article> .

<#faq-8> a schema:Question ;
  schema:name "What additional escalation paths were reported?"@en ;
  schema:text "What additional escalation paths were reported?"@en ;
  schema:acceptedAnswer <#faq-8-answer> ;
  schema:isPartOf <#article> .
<#faq-8-answer> a schema:Answer ;
  schema:text "The article lists model access against live tables, bulk export endpoints with attacker-controlled destinations, and a single-call production database clone path."@en ;
  schema:isPartOf <#article> .

<#faq-9> a schema:Question ;
  schema:name "What was reportedly exposed about the AI layer?"@en ;
  schema:text "What was reportedly exposed about the AI layer?"@en ;
  schema:acceptedAnswer <#faq-9-answer> ;
  schema:isPartOf <#article> .
<#faq-9-answer> a schema:Answer ;
  schema:text "The article says an 18,621-character Pyxis system prompt, including methodology and schema definitions, was readable through conversation metadata."@en ;
  schema:isPartOf <#article> .

<#faq-10> a schema:Question ;
  schema:name "What business conclusion does CodeWall attach to the Bain case?"@en ;
  schema:text "What business conclusion does CodeWall attach to the Bain case?"@en ;
  schema:acceptedAnswer <#faq-10-answer> ;
  schema:isPartOf <#article> .
<#faq-10-answer> a schema:Answer ;
  schema:text "The article uses Bain as the third MBB example to argue for continuous AI-driven offensive security testing against real attack surfaces rather than periodic checklist pentests."@en ;
  schema:isPartOf <#article> .
