Scan-Engines

AllyProof nutzt drei Engines parallel, um die Erkennungsabdeckung zu maximieren. Die primäre Engine (axe-core) verfolgt eine Zero-False-Positive-Richtlinie. Kombinierte Abdeckung: ~70 % der automatisierbaren WCAG-Probleme als deterministische Verstöße, plus eine eigene Advisory-Spur für WCAG-Kriterien, die nur teilweise automatisiert werden können und eine menschliche Prüfung benötigen.

Engine-Pipeline

Diagramm der vierschichtigen Scan-Architektur für Barrierefreiheit.
Vier Engines laufen pro Seite – deterministische Befunde treiben den Score an; beratende, Vorschau- und KI-Ebenen werden separat angezeigt.

Barrierefreiheits-Analysepipeline: eine mehrschichtige Scan-Architektur, die deterministische, beratende, Vorschau- und KI-gestützte Ergebnisse erzeugt. Engine 1, axe-core, erzeugt deterministische Verstöße ohne Falsch-Positive – dies ist die primäre Engine. Engine 2, HTML_CodeSniffer, erzeugt zusätzliche Verstöße aus Fehlern und Warnungen. Ergebnisse werden nach Element-Fingerabdruck kombiniert mit WCAG-Kriterium dedupliziert, und eine statische Techniküberschneidungs-Karte verwirft Techniken wie H37, G18 und H44, bei denen axe-core denselben Fehler bereits markiert hat. Engine 2b, HTMLCS-Hinweise, sind beratende Einträge zur manuellen Prüfung mit is_advisory auf true gesetzt. Sie werden mit einer Manuelle-Prüfung-Kennzeichnung angezeigt und niemals in Score, VPAT, Zertifikaten oder öffentlichen Berichten gezählt. Engine 3, APCA, ist eine WCAG-3.0-Vorschau-Kontrastprüfung – nur informativ, neben WCAG 2.x angezeigt, aber niemals zur Konformitätsprüfung verwendet. Engine 4, KI-Analyse, läuft nach dem Scan, ist auf Agency und Enterprise beschränkt und wird asynchron als Ebene 4 ausgeführt. Sie zielt auf Kriterien ab, die menschliches Urteilsvermögen erfordern: WCAG 1.4.1 nur Farbe, 3.3.2 Formatanweisungen und 3.2.3 seitenübergreifende Navigationskonsistenz. Sie erstellt beratende Einträge mit dem Präfix ai- bei rule_id, jeweils mit Vertrauenskennzeichnung. Deterministische Befunde aus den Engines 1 und 2 fließen in den Kern-Score ein. Beratende und Vorschau-Ebenen werden separat angezeigt.

Pipeline als strukturierten Text lesen
  1. Engine 1axe-coreDeterministisch

    Deterministische Verstöße mit einer Garantie für null Falsch-Positive.

  2. Engine 2HTML_CodeSnifferDeterministisch

    Fehler und Warnungen zeigen zusätzliche Verstöße auf. Ergebnisse werden nach Element-Fingerabdruck × WCAG-Kriterium dedupliziert, und eine statische Techniküberschneidungs-Karte verwirft Techniken wie H37, G18 und H44, bei denen axe-core denselben Fehler bereits markiert hat.

  3. Engine 2bHTMLCS-HinweiseBeratend

    Einträge mit is_advisory = true, angezeigt mit einer „Manuelle Prüfung“-Kennzeichnung in der Problemliste. Werden niemals in Score, VPAT, Zertifikaten oder öffentlichen Berichten gezählt.

  4. Engine 3APCAInformativ

    WCAG-3.0-Vorschau-Kontrast. Wird neben WCAG 2.x angezeigt, niemals zur Konformitätsprüfung verwendet.

  5. Engine 4KI-Analyse (Ebene 4)Beratend

    Nach dem Scan, stufenabhängig (Agency und Enterprise). Gezielte LLM-Prüfungen zu WCAG 1.4.1 (Farbe allein), 3.3.2 (Formatanweisungen) und 3.2.3 (seitenübergreifende Nav-Konsistenz). Erstellt beratende Einträge mit rule_id = ai-* und einer Vertrauenskennzeichnung.

Warum vier Spuren statt einer kombinierten Liste

  • Deterministische Verstöße (axe + HTMLCS-Fehler/-Warnungen) fließen in Scores, VPATs, Zertifikate und öffentliche geteilte Berichte ein. Zero False Positives ist die Garantie – alles, was hier auftaucht, lässt sich in einem Compliance-Gespräch verteidigen.
  • Advisory-Elemente (HTMLCS-Hinweise) sind Prompts zur manuellen Prüfung für WCAG-Kriterien, die keine der beiden Engines vollständig automatisieren kann – 1.4.1 (Farbe allein), 3.3.2 (Formularanweisungen), 2.1.1 / 2.4.7 (Fokusverhalten bei Modals, Karussells), 1.2.x (Medienalternativen). Diese wurden früher verworfen; ihre Beibehaltung schließt den Großteil der Lücke bei der manuellen Prüfung ohne zusätzliche Laufzeitkosten.
  • APCA ist eine informative Vorschau des WCAG-3.0-Kontrastalgorithmus – wird neben WCAG-2.x-Ergebnissen angezeigt, aber nie zur Konformitätsprüfung herangezogen.
  • KI-Analyse (Layer 4) führt drei gezielte LLM-Prüfungen für Kriterien durch, bei denen Urteilsvermögen wichtiger ist als Regelabgleich. Nur für die Stufen Agency und Enterprise. Befunde sind Advisory, mit Konfidenz-Label versehen und beeinflussen niemals Scores oder rechtliche Berichte.

Engine 1: axe-core (primär)

EigenschaftWert
QuelleDeque Systems (Open Source)
Regeln91 aktiv + 5 experimentell
StandardsWCAG 2.0/2.1/2.2 A+AA, Best Practice
Falsch-PositiveNull (strikte Richtlinie)
Abdeckung~57 % der automatisierbaren WCAG-Probleme

axe-core ist der Industriestandard. Es verfolgt eine Zero-False-Positive-Richtlinie – es bleibt lieber still, statt riskant etwas zu melden, das kein echter Verstoß ist. Das macht es zur vertrauenswürdigen Basis für alle AllyProof-Scans.

Aktivierte experimentelle Regeln

  • css-orientation-lock – WCAG 1.3.4 Ausrichtung
  • label-content-name-mismatch – WCAG 2.5.3 Label im Namen
  • p-as-heading – WCAG 1.3.1 Informationen und Beziehungen
  • table-fake-caption – WCAG 1.3.1 Informationen und Beziehungen
  • td-has-header – WCAG 1.3.1 Informationen und Beziehungen

Engine 2: HTML_CodeSniffer (sekundär)

EigenschaftWert
QuelleSquiz Labs (Open Source)
Regeln~200 Regeln
StandardsWCAG 2.1 A, AA, AAA
IntegrationBrowser-Skript-Injektion
Falsch-PositiveNiedrig (Fehler), Mittel (Warnungen)

HTML_CodeSniffer nutzt andere Erkennungsalgorithmen als axe-core und findet dadurch Probleme, die axes strikte Zero-False-Positive-Richtlinie überspringt. Regel-IDs tragen zur Quellenidentifikation das Präfix htmlcs-.

So funktioniert die Deduplizierung

Die Deduplizierung erfolgt in zwei Schichten, damit nie doppelt gezählt und nie stillschweigend ein legitimer Befund verworfen wird, wenn sich die beiden Engines im Detail uneinig sind, aber beim Element übereinstimmen.

Schicht 1 – Fingerabdruck pro (Element, Kriterium). Das outerHTML jedes Elements wird normalisiert (Kleinschreibung, Leerraum zusammengefasst, Kommentare entfernt, gekürzt) zu einem stabilen Fingerabdruck. Der Dedup-Schlüssel ist {fingerprint}|{wcag_criterion}. Ein HTMLCS-Befund wird nur verworfen, wenn axe für dasselbe Element einen Verstoß gegen dasselbe Erfolgskriterium gemeldet hat. Meldet axe button-name für eine Schaltfläche und HTMLCS Kontrast für dieselbe Schaltfläche, bleiben beide erhalten – es sind unterschiedliche Probleme.

Schicht 2 – statische Technik-Überlappungskarte. Eine fest codierte Menge von HTMLCS-Technik-Codes (H37, G18, H44, F77, …) listet Fälle, in denen axe eine eigene Regel hat, die die gesamte Fläche abdeckt. Diese HTMLCS-Befunde werden unabhängig vom Fingerabdruck verworfen – ein Sicherheitsnetz gegen Formatierungsunterschiede. Bewusst konservativ gestaltet: Erfasst HTMLCS Randfälle, die axe nicht abdeckt, bleibt der Code aus der Überlappungsliste heraus.

Nachrichtentypen → Kategorien

HTMLCS-TypKategorieFlagGezählt?
Fehler (1)Deterministischer Verstoßimpact=seriousJa
Warnung (2)Deterministischer Verstoßimpact=moderateJa
Hinweis (3)Advisory / manuelle Prüfungis_advisory=trueNein – inline mit einem Manuelle-Prüfung-Badge angezeigt

Advisory-Elemente (HTMLCS-Hinweise)

Hinweise wurden früher als "zu ausführlich" verworfen. Damit ging genau das Signal verloren, das für Kriterien nötig ist, die keine der beiden Engines vollständig automatisieren kann. Hinweise bleiben jetzt als Advisory-Elemente mit is_advisory=true erhalten:

EigenschaftAdvisory-Verhalten
In Verstoß-Summen gezähltNein
Beeinflusst Barrierefreiheits-ScoreNein
Erscheint in VPAT / Zertifikaten / öffentlichen BerichtenNein
Fließt in KI-Fix-Vorschläge einNein
In der Oberfläche angezeigtJa – inline in der Problemliste mit einem Manuelle Prüfung-Badge statt des Schweregrad-Badges. Die Detailseite öffnet sich mit einem gelben Hinweis, der erklärt, was manuelle Prüfung bedeutet.
Über Scans hinweg gespeichertJa, mit nach Kategorie getrennter Resolve-Nachverfolgung
Separat gezähltJa – advisory_count bei Scan-Jobs und Seiten-Scans

Hinweise, deren Technik in der axe-Überlappungskarte steht, werden verworfen (kein Sinn in "bitte Alt-Text manuell prüfen", wenn axe bereits jedes Bild geprüft hat). Alles andere bleibt erhalten.

Engine 3: APCA-Kontrast (Vorschau)

EigenschaftWert
QuelleMyndex / W3C-WCAG-3.0-Entwurf
TypPerzeptueller Kontrastrechner
StandardWCAG 3.0 (Entwurf)
Falsch-PositiveKeine (mathematisch)

WCAG 3.0 ersetzt die WCAG-2.x-Kontrastverhältnis-Formel durch APCA (Advanced Perceptual Contrast Algorithm). APCA berücksichtigt Schriftgröße, -stärke und perzeptuelle Gleichmäßigkeit und liefert dadurch genauere Lesbarkeitsprognosen.

APCA-Lc-Schwellenwerte

Lc-WertAnwendungsfall
90+Bevorzugt für Fließtext
75Minimum für Fließtext (16px normal)
60Minimum für großen/fetten Text
45Minimum für Nicht-Text-UI-Elemente
30Absolutes Minimum für jeglichen Text

Engine 4: KI-Analyse (Layer 4 – Agency + Enterprise)

EigenschaftWert
LäuftAsynchron nach Abschluss des deterministischen Scans
StufenbeschränkungNur Agency und Enterprise
ModellPro-Stufe-Auswahl durch Superadmin (Anthropic / Google / OpenAI)
Kostenobergrenze~40.000 Tokens pro Scan, hart begrenzt
AusgabeAdvisory-Elemente (is_advisory=true, Regel-ID-Präfix ai-)
Fließt in Scores / VPATs / Zertifikate einNein

Nach den Schichten 1–3 sind rund 30 % der WCAG-AA-Kriterien für statische Analyse weiterhin unerreichbar. Die meisten davon erfordern Urteilsvermögen – "wird die Bedeutung dieses roten Punkts anderswo vermittelt?", "sagt dieses Label dem Nutzer, das Datum als TT.MM. einzugeben?", "ist die Navigation auf jeder Seite gleich?" Ein LLM kann über DOM + Kontext auf eine Weise urteilen, wie es keine Regel-Engine kann.

Layer 4 ist bewusst eng gefasst. Es führt drei gezielte Prüfungen dort durch, wo die KI das höchste Signal-Rausch-Verhältnis hat – nicht jedes mögliche WCAG-Kriterium:

PrüfungKriteriumWas die KI entscheidet
Farbe-allein-Indikator1.4.1 Verwendung von FarbeIst Farbe der einzige Hinweis, oder vermitteln auch Text/Icon/Form die Bedeutung?
Fehlende Formatanweisungen3.3.2 Beschriftungen oder AnweisungenKommuniziert ein formatpflichtiges Eingabefeld (Datum, Telefon, Code) das erwartete Format?
Navigationskonsistenz3.2.3 Konsistente NavigationStimmt die primäre Navigation über alle Seiten hinweg überein? (Nur KI kann seitenübergreifend vergleichen.)

So funktioniert es

  1. Snippet-Erfassung während des Browser-Durchlaufs für jede Seite: bis zu 3 Navigationen, 20 Formularfelder (mit Labels + 300 Zeichen umgebendem Kontext + Pattern-/describedby-Flags) und 15 statusfarbige Elemente (gefiltert nach berechnetem Farbton). Jeder Bereich ist größenbegrenzt und wird in page_scans.ai_snippets gespeichert.
  2. Stufenprüfung + Modellauswahl. Der Orchestrator prüft den Plan der Organisation gegen aiScanAnalysis und liest das vom Superadmin konfigurierte Modell für den Scan-Analyse-Workload.
  3. Seiten-Stichprobe. Bis zu 3 Seiten pro Scan – die Startseite wird immer einbezogen, falls vorhanden, plus die Seiten mit der interessantesten Snippet-Masse. Deterministisch, sodass Wiederholungen cache-freundlich sind.
  4. Gebündelte LLM-Aufrufe. Jede Prüfung sendet kompakte JSON-Payloads mit einem konservativen System-Prompt. Befunde werden defensiv geparst – fehlerhafte Ausgaben werden verworfen, statt die gesamte Prüfung zum Absturz zu bringen.
  5. Upsert als Advisory. Gültige Befunde werden auf violations mit is_advisory=true, Regel-ID-Präfix ai- und einem Konfidenz-Label abgebildet. Sie erscheinen inline in der Problemliste mit demselben Manuelle Prüfung-Badge wie HTMLCS-Hinweise; die Detailseite öffnet sich mit einem gelben Hinweis, der KI-basierte Befunde erklärt.

Konservative Ausgabe-Richtlinie

  • Farbe-allein: muss das Fehlen eines konkreten redundanten Hinweises belegen; im Zweifel "unklar".
  • Formatanweisungen: Freitextfelder werden standardmäßig als "kein Format erforderlich" eingestuft – nur eindeutige Fehlstellen werden gemeldet.
  • Navigationskonsistenz: Befunde mit geringer Konfidenz werden komplett verworfen – seitenübergreifende Diffs haben ein hohes Falsch-Positiv-Risiko.

Modellauswahl

Der Superadmin wählt das Modell pro Plan-Stufe im KI-Scan-Analyse-Panel, analog zum KI-Fix-Vorschläge-Panel. Typisches Setup: ein günstigeres Modell der Haiku-Klasse für die Scan-Analyse (läuft häufig), ein stärkeres Modell für Fix-Vorschläge (läuft seltener, tiefere Analyse). Verfügbare Anbieter: Anthropic (Claude), Google (Gemini), OpenAI (GPT).

Abdeckungsvergleich

Engine / SchichtRegelnStufeAbdeckungsbeitrag
axe-core91Alle57 % deterministisch (Basis)
HTML_CodeSniffer (Fehler & Warnungen)~200Alle+10–15 % deterministisch
HTML_CodeSniffer (Hinweise → Advisory)dasselbe 200er-RegelwerkAlleSchließt ~60 % der Lücke bei manueller Prüfung
APCA1 (Kontrast)AlleWCAG-3.0-Vorschau
KI-Scan-Analyse (Layer 4)3 gezielte PrüfungenAgency + EnterpriseDeckt 1.4.1 / 3.3.2 / 3.2.3 ab – die wirkungsstärksten Kriterien, die KI zuverlässig beurteilen kann
Kombiniert~290 + 3 KIStufenabhängig~70 % automatisierbar + KI-markiert + HTMLCS-markiert zur manuellen Prüfung für den Rest

Sicherheitsmauer um die KI

Die KI-Schicht verarbeitet HTML, das von Drittanbieter-Websites extrahiert wurde. Dieses HTML ist nicht vertrauenswürdig – eine bösartige Website könnte versteckten Text einbetten, der das Modell anweist, Daten abzugreifen, Befunde falsch zu klassifizieren oder eine Antwort mit XSS auszugeben. Das LLM selbst hat nie direkten Zugriff auf unsere Umgebungsvariablen oder die Datenbank; die eigentliche Angriffsfläche ist (1) eine vergiftete Antwort, die Nutzer täuscht, (2) gespeichertes XSS in gerenderter KI-Ausgabe, (3) Erkundung nach Tools/Prompts, (4) Ressourcenerschöpfung durch aufgeblähte Ausgaben und (5) feindliche URLs in KI-Inhalten.

Physische Isolation – der ai-worker-Dienst

Jeder LLM-Aufruf in der Produktion verlässt die Hauptanwendung per HTTP an einen isolierten Nebendienst unter services/ai-worker/. Dieser Dienst besitzt ausschließlich die LLM-Anbieter-Schlüssel und ein per HMAC geteiltes Geheimnis. Er hat keinen Supabase-Client, keine Paddle-Schlüssel, keine Resend-Schlüssel, keine R2-Zugangsdaten, keine Dateisystem-Schreibzugriffe (Container läuft mit --read-only und --cap-drop=ALL) und keinen Zugriff auf andere Dienste. Er ist an das interne Docker-Netzwerk gebunden und niemals dem Internet ausgesetzt. Anfragen sind HMAC-SHA256-signiert mit einem 60-Sekunden-Replay-Fenster und einer 1-MB-Body-Obergrenze.

Die Hauptanwendung ruft den Worker über einen einzigen Engpass auf (src/lib/ai/worker-client.ts). Anbieter-SDK-Importe sind dynamisch und durch einen Nur-Entwicklung-Fallback abgesichert, der in der Produktion hart blockiert ist. Eine Kompromittierung des LLM-Pfads – Prompt-Injection, Supply-Chain-Angriff oder anderes – verbrennt daher Tokens, legt aber keine Nutzerdaten, keine Mandanten-Geheimnisse und keine Abrechnungsdaten offen.

Prompt-Ebenen-Mauer (Verteidigung in der Tiefe, innerhalb beider Prozesse)

SchichtWoWas sie tut
Eingabe-SanitizerHauptanwendungEntfernt <script>, <style>, <iframe>, Event-Handler, javascript:-/vbscript:-/data:text/html-URIs, Zero-Width- und Bidi-Zeichen, HTML-Kommentare, data-*-Attribute und bekannte Prompt-Injection-Marker, bevor ein DOM-Snippet einen Prompt berührt. Visuell versteckte Elemente werden geleert.
Prompt-WrapperHauptanwendungAller nicht vertrauenswürdiger Inhalt steht zwischen UNTRUSTED_START-/UNTRUSTED_END-Markern mit einem expliziten Leitplanken-Absatz und einer wiederholten Erinnerung nach dem Block. System-Prompts beginnen mit einer gemeinsamen Sicherheits-Präambel, die Vertrauensebenen trennt und dem Modell verbietet, seinen System-Prompt, Tools oder die Umgebung offenzulegen.
Worker-Bereinigungai-workerLetzte Chance, bevor eine Antwort die Grenze überschreitet. Entfernt Script-/Style-/Iframe-/Event-Handler-/gefährliche-URI-Inhalte aus Fließtext (erhält eingezäunte Codeblöcke), entfernt Unsichtbares, begrenzt die Antwort auf 16 KB.
Ausgabe-ValidatorHauptanwendungJede Antwort wird gegen ein striktes Zod-Schema geparst. Freitext wird bereinigt (HTML-Tags entfernt, unsichtbare Zeichen entfernt, Länge begrenzt). URLs müssen zu http(s) auflösen. Alles, was die Validierung nicht besteht, wird stillschweigend verworfen.
UI-EscapingHauptanwendungKI-Ausgabe wird über React-Textknoten und eigene Code-Highlighter gerendert – kein dangerouslySetInnerHTML. Selbst wenn eine Bereinigung etwas übersehen hat, erhält der Browser escapten Text.

Keine einzelne Schicht ist für sich allein eine Sicherheitsgrenze. Der Wert entsteht durch die Kombination aus einem physischen Isolationsperimeter mit mehreren Prompt-Ebenen-Stolperdrähten. Eine vergiftete Antwort, die die Bereinigung des Workers übersteht, muss immer noch die Zod-Validierung der Hauptanwendung passieren – und selbst dann würde sie nur einen Prozess erreichen, der nicht die Schlüssel besitzt, die ein Angreifer wollen würde. maxTokens ist pro Aufruf begrenzt, und Layer 4 erzwingt ein Budget von 40.000 Tokens pro Scan, das bei Erschöpfung vorzeitig endet.

Was auch mit Layer 4 manuell bleibt

Selbst mit Advisory-Elementen und KI-Analyse bleiben diese Kriterien für jeden statischen oder asynchronen Scanner unerreichbar – sie erfordern menschliches Testen oder Laufzeit-Sonden:

  • 2.3.1 Fotosensitives Blitzen – erfordert Bildwiederholrate-Analyse (PEAT)
  • 3.3.1 / 3.3.3 Timing der Fehleransage – nur zur Laufzeit, erfordert assistive Technologie
  • 1.2.3 / 1.2.5 Qualität von Untertiteln / Audiodeskription – Vorhandensein ja, Korrektheit nein
  • 2.1.1 / 2.4.3 Modal-Fokusfalle / Fokus-Rückkehr – Laufzeitverhalten, erfordert Playwright-Interaktionssonden (zukünftige Arbeit, ohne LLM skriptierbar)