/* CX Defense — Insights articles. Real, researched long-form, tied to products.
   Sources are attributed inline by name. Figures reflect public 2025–2026
   reporting; the CX Defense team should verify before any print use. */
const { Nav, Rule, CTA, Footer } = window;

const ARTICLES = {
  'prompt-injection': {
    kind: 'AI Security', date: 'June 2026', read: '8 min read',
    img: 'assets/img/monolith.png',
    title: 'Prompt injection has <em>left the lab</em>',
    dek: 'It is now the number-one risk to production AI — and the real danger isn\u2019t the model. It\u2019s what the model is allowed to reach.',
    body: [
      { t: 'lead', x: 'Three years ago, prompt injection was a party trick at security conferences. In 2026 it sits at the top of the OWASP Top 10 for LLM applications — and, according to Cisco\u2019s State of AI Security 2026, it is a weakness present in 73% of audited production AI deployments.' },
      { t: 'h2', x: 'From curiosity to incident' },
      { t: 'p', x: 'The theoretical phase is over. EchoLeak became the first documented zero-click prompt-injection exploit against a production LLM system. The Freysa experiment showed an AI-controlled crypto wallet talked out of roughly $47,000 through nothing more than role-play. CrowdStrike\u2019s 2026 threat reporting documented prompt-injection activity against more than 90 organisations, and Palo Alto Networks\u2019 Unit 42 observed web-based indirect-injection attempts in traffic from over 30 countries — linking them to credential or payment-data exposure in nearly one in five investigated AI incidents.' },
      { t: 'h2', x: 'The danger is the connection, not the sentence' },
      { t: 'p', x: 'The highest-severity findings almost never come from breaking the model itself. They come from what the model is wired to: tools, databases, document stores, and outbound channels. Researchers demonstrated a KYC pipeline that read a passport image and obediently followed instructions hidden in the OCR text — it could not tell applicant data from attacker commands. Customer-facing chatbots routinely cannot distinguish a trusted product description from an untrusted customer review pulled into the same context.' },
      { t: 'quote', x: 'Prompt injection is the SQL injection of the LLM era.', cite: 'Security research consensus, 2026' },
      { t: 'p', x: 'And like early SQL injection, it resists the obvious fix. Natural language cannot be sanitised the way structured input can. Detectors that rely on pattern-matching are bypassed by new phrasing, obfuscation, and multi-turn assembly — where the attack is harmless in any single message and only becomes malicious once assembled. Adaptive techniques now exceed an 85% success rate against undefended systems.' },
      { t: 'h2', x: 'What actually works: control, not recognition' },
      { t: 'p', x: 'The encouraging finding in the same research is that layered, deterministic controls work where detection alone fails: properly applied, they cut attack success from 73.2% to 8.7%. The winning pattern is not a smarter classifier — it is provenance and taint tracking, hard trust boundaries, privilege separation, and egress checks placed at the points that actually matter: tool calls, database queries, and anything leaving the system.' },
    ],
    callout: {
      kind: 'How CX Defense helps', product: 'CXGuard', status: 'In Development',
      h: 'This is the gap CXGuard is built to close',
      p: 'CXGuard treats detection as advisory and puts the real guarantee in deterministic control over where untrusted data is allowed to flow. Our latest work extends multi-turn taint tracking and tool-call controls, backed by a tamper-evident evidence trail. We are deliberate about what it does and does not do — we don\u2019t claim to catch every prompt injection. We make sure untrusted data cannot silently become trusted, reach a privileged action, launder through a tool, or leave the system without a deterministic check and an evidence record.',
      cta: 'See CXGuard', href: 'technology.html',
    },
    tags: ['Prompt Injection', 'LLM Security', 'Zero Trust', 'CXGuard'],
  },

  'gdpr-cookie-audit': {
    kind: 'Compliance', date: 'May 2026', read: '7 min read',
    img: 'assets/img/ledger-archive.png',
    title: 'Your cookie banner is now an <em>audit target</em>',
    dek: 'GDPR fines have passed \u20ac7.1 billion, and regulators have moved from reading your policy to testing what your website actually does.',
    body: [
      { t: 'lead', x: 'Cumulative GDPR fines since 2018 now exceed \u20ac7.1 billion, with roughly \u20ac1.2 billion issued in 2025 alone — and the curve is still climbing. The ceiling is \u20ac20 million or 4% of global annual turnover, whichever is greater.' },
      { t: 'h2', x: 'Enforcement is a machine now' },
      { t: 'p', x: 'What compliance teams have felt for two years is now measurable: enforcement has shifted from sporadic, headline penalties into a sustained, high-volume operation. France\u2019s CNIL has been the most aggressive regulator on cookie consent and ad-tech, with a \u20ac325 million Google decision and a \u20ac150 million Shein decision both landing in September 2025 — on top of an earlier \u20ac60 million fine for making cookies harder to refuse than to accept. For 2026, the European Data Protection Board\u2019s Coordinated Enforcement Framework is focused squarely on transparency and information obligations.' },
      { t: 'h2', x: 'The gap is between your policy and your page' },
      { t: 'p', x: 'Most organisations have a privacy policy that lives in a PDF while the website behaves differently in practice. That gap is exactly where regulators now look. The recurring red flags are concrete and testable: unequal friction between \u201cAccept\u201d and \u201cReject\u201d, no \u201cReject All\u201d on the first consent layer, pre-ticked boxes, banners that never name the third parties receiving data, and tracking scripts that fire before any consent is given.' },
      { t: 'quote', x: 'Regulators no longer ask whether you have a policy. They test whether your \u201creject\u201d is as easy as your \u201caccept.\u201d', cite: 'EDPB coordinated enforcement, 2026' },
      { t: 'h2', x: 'Compliance is an engineering property' },
      { t: 'p', x: 'The organisations that compound advantage treat privacy as platform engineering, not a banner bolted onto an unchanged stack. That means three habits: test your consent mechanism the way an attacker tests a login; trace where data actually flows across borders, which matters more than ever after Schrems II; and document your legal basis contemporaneously, because Article 6 failures account for roughly a third of all enforcement and retrospective paperwork does not count.' },
    ],
    callout: {
      kind: 'How CX Defense helps', product: 'CXComply', status: 'Live',
      h: 'CXComply sees your site through a regulator\u2019s eyes',
      p: 'CXComply audits from the outside in — launching a real browser to observe exactly what a visitor, or a regulator, would encounter. It goes beyond scanning code: it checks whether your cookie banner\u2019s \u201creject\u201d button actually works, traces data flows across borders, and scrutinises your privacy policy against UK & EU GDPR, India\u2019s DPDP Act, Australia, and US state law. You don\u2019t just get a score — you get a clear, actionable report, every issue backed by evidence and a practical fix.',
      cta: 'See CXComply', href: 'technology.html',
    },
    tags: ['GDPR', 'Cookie Consent', 'Web Compliance', 'CXComply'],
  },

  'infostealers': {
    kind: 'Threat Intelligence', date: 'April 2026', read: '7 min read',
    img: 'assets/img/ops-room.png',
    title: 'The breach usually starts on a laptop <em>you don\u2019t manage</em>',
    dek: 'Stolen credentials — not zero-days — are now the number-one way in. The defence is intelligence, not just better endpoints.',
    body: [
      { t: 'lead', x: 'Recorded Future identified infostealers as the primary initial infection vector across all tracked incidents in 2025 — the first time a single malware category has held that position for a full calendar year. Some 1.8 billion credentials were stolen in the first half of 2025 alone, and more than half of ransomware victims had credentials exposed before the attack began.' },
      { t: 'h2', x: 'A 48-hour supply chain' },
      { t: 'p', x: 'Constella\u2019s 2026 Identity Breach Report processed 51.7 million infostealer packages from 2025 — a 72% year-over-year rise. Of those, 98.6% contained active passwords and 99.5% included the exact URLs where the credentials were used, handing attackers an automated roadmap to each account. Researchers tracing the full lifecycle put the window from infection to dark-web sale at 48 hours or less. Worse, the stolen session tokens let an attacker resume an already-authenticated session — walking straight past multi-factor authentication.' },
      { t: 'h2', x: 'The simple reality behind \u201csophisticated\u201d breaches' },
      { t: 'p', x: 'When the so-called Coinbase Cartel breached more than 100 companies, victims and even some responders attributed it to advanced zero-days and elaborate social engineering. Cybercrime intelligence told a plainer story: the group relied almost entirely on old infostealer logs to access cloud environments, FTP servers, and file-transfer services. The credentials were already for sale; nobody had to break anything.' },
      { t: 'quote', x: 'Attackers increasingly don\u2019t break in. They log in.', cite: 'Identity breach reporting, 2026' },
      { t: 'h2', x: 'Your attack surface includes devices you\u2019ll never see' },
      { t: 'p', x: 'An employee\u2019s home computer. A contractor\u2019s laptop. A personal browser with \u201cremember me\u201d ticked on a corporate app. You cannot patch any of them — but you can watch the open and underground sources where their credentials surface, and you can architect so that a single stolen credential is never enough. That is the discipline of intelligence-led defence: assume breach, monitor exposure from the outside, and make the foothold worthless.' },
    ],
    callout: {
      kind: 'How CX Defense helps', product: 'CyberProof & Specter Intel', status: 'Live',
      h: 'Intelligence is in our blood',
      p: 'CX Defense was founded on digital investigation. CyberProof gives you KEV-first external intelligence with a verifiable evidence chain, while Specter Intel traces credential leaks, maps your exposure from the attacker\u2019s side, and attributes infrastructure with source-cited, defensible findings. We don\u2019t just tell you a breach is possible — we show you exactly how you look from the outside, and prove it.',
      cta: 'See our platform', href: 'technology.html',
    },
    tags: ['Infostealers', 'Credential Theft', 'OSINT', 'CyberProof', 'Specter Intel'],
  },
};

const ORDER = ['prompt-injection', 'gdpr-cookie-audit', 'infostealers'];

function renderBlock(b, i) {
  if (b.t === 'lead') return <p className="lead" key={i}>{b.x}</p>;
  if (b.t === 'h2') return <h2 key={i} dangerouslySetInnerHTML={{ __html: b.x }}></h2>;
  if (b.t === 'quote') return (
    <blockquote className="article-quote" key={i}>
      <p>{b.x}</p>
      {b.cite && <div className="cite">{b.cite}</div>}
    </blockquote>
  );
  return <p key={i}>{b.x}</p>;
}

function RelatedCard({ id }) {
  const a = ARTICLES[id];
  return (
    <a className="post" href={'insight-' + id + '.html'}>
      <div className="post-meta">{a.kind} · {a.date}</div>
      <h3 dangerouslySetInnerHTML={{ __html: a.title }}></h3>
      <p>{a.dek}</p>
      <div className="post-foot">{a.read} →</div>
    </a>
  );
}

function Article({ id }) {
  const a = ARTICLES[id];
  const related = ORDER.filter(x => x !== id);
  return (
    <div className="site">
      <Nav active="insights.html" />
      <article>
        <div className="article-hero">
          <div className="ah-img" style={{ backgroundImage: `url(${a.img})` }}></div>
          <div className="ah-inner">
            <div className="ah-meta">
              <span className="ah-kind">{a.kind}</span>
              <span className="ah-dot">·</span>
              <span className="ah-info">{a.date}</span>
              <span className="ah-dot">·</span>
              <span className="ah-info">{a.read}</span>
            </div>
            <h1 dangerouslySetInnerHTML={{ __html: a.title }}></h1>
            <p className="ah-dek">{a.dek}</p>
          </div>
        </div>

        <div className="article-body">
          {a.body.map(renderBlock)}
          <div className="article-callout">
            <div className="co-kind">{a.callout.kind}</div>
            <h3>{a.callout.h}<span className="co-status">{a.callout.status}</span></h3>
            <p>{a.callout.p}</p>
            <a href={a.callout.href} className="btn btn-secondary" style={{ fontSize: 10.5, padding: '11px 22px' }}>{a.callout.cta} <span aria-hidden="true">→</span></a>
          </div>
        </div>

        <div className="article-tags">
          {a.tags.map(t => <span className="svc-tag" key={t}>{t}</span>)}
        </div>

        <div className="article-foot">
          <div className="byline">By the <b>CX Defense</b> team · Cybersecurity Engineering & Digital Investigation</div>
          <a href="contact.html" className="nav-link" style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--accent)' }}>Discuss this with us →</a>
        </div>
      </article>

      <div style={{ marginTop: 72 }}><Rule /></div>
      <section className="section">
        <div className="rel-label">
          <div className="eyebrow brass">Keep reading</div>
          <div className="s-title">More from the <em>practice</em></div>
        </div>
        <div className="related">
          <div className="post-grid">
            {related.map(id => <RelatedCard key={id} id={id} />)}
          </div>
        </div>
      </section>
      <Rule />
      <CTA title="Have a question this raises?"
        actions={<a href="contact.html" className="btn btn-primary">Speak With Us</a>}>
        The fastest way to a real answer is to ask the engineers directly.
      </CTA>
      <Footer />
    </div>
  );
}

window.ARTICLES = ARTICLES;
window.ARTICLE_ORDER = ORDER;
window.renderArticle = function (id) {
  ReactDOM.createRoot(document.getElementById('root')).render(<Article id={id} />);
};
