← Alle Checks
SicherheitTypische Schwere: Niedrig

Offengelegte Dependency-Manifeste

Erkennt erreichbare package.json- oder composer.json-Dateien, die deine genauen Abhängigkeiten und Versionen verraten.

Was es prüft

Dieser Scanner prüft, ob Abhängigkeits-Manifestdateien wie package.json oder composer.json auf deiner Seite öffentlich zugänglich sind. Er erkennt, wenn sie ausgeliefert werden und die Liste der von dir genutzten Bibliotheken samt ihrer genauen Versionen preisgeben.

Warum es wichtig ist

Deine genauen Abhängigkeiten und Versionen zu kennen, macht es einem Angreifer leicht, öffentliche Schwachstellen nachzuschlagen, die genau das betreffen, was du nutzt. Das ist Aufklärungsarbeit, die du ihm ersparst, und sie grenzt stark ein, wo er deine Seite anzugreifen versucht.

Wie man es behebt

Stelle sicher, dass diese Manifestdateien nicht aus dem öffentlichen Ordner ausgeliefert werden; sie gehören normalerweise ins Projekt-Root, nicht ins Web-Verzeichnis. Blockiere ihren Zugriff in der Konfiguration deines Servers oder CDN, falls dein Framework sie standardmäßig offenlegt.

Wie diese Prüfung funktioniert

Scanaris fordert zwei Dateien im Root deiner Domain an: /package.json, das Manifest eines Node-Projekts, und /composer.json, das eines PHP-Projekts. Für jede bestätigt es den Befund nur, wenn sie mit 200 antwortet, der Body kein HTML ist, es gültiges JSON ist und die für das Manifest typischen Schlüssel enthält: dependencies oder devDependencies bei der ersten, require oder require-dev bei der zweiten. So meldet es weder eine Single-Page-App, die für jeden Pfad ihr HTML zurückgibt, noch irgendein JSON, das zufällig dort liegt. Jede gefundene Datei öffnet einen Befund mit niedrigem Schweregrad.

Warum das wichtig ist

Diese Dateien enthalten keine Geheimnisse, aber etwas fast ebenso Nützliches für einen Angreifer: die genaue Liste der Bibliotheken, die du nutzt, mit ihren Versionen. Damit muss er nichts raten: Er gleicht deine Liste mit der Datenbank bekannter Schwachstellen ab und weiß, welchen Exploit er gegen was probiert. Sie verraten außerdem den internen Projektnamen, die Build- und Deploy-Skripte, manchmal die URL des privaten Repositorys und die Namen interner Pakete deiner Organisation, die der Ausgangspunkt von Dependency-Confusion-Angriffen sind. Es ist niedriger Schweregrad, weil es Information ist, kein Zugang; aber Information, die du grundlos verschenkst.

Warum das passiert

Weil der Webserver den ganzen Projektordner statt des Ausgabeordners ausliefert. Ein sauber deploytes Vite, Nuxt oder Next.js veröffentlicht nur dist/, .output/public/ oder .next/static/, und dort gibt es keine package.json. Es taucht auf, wenn das komplette Repository per FTP nach public_html hochgeladen wird, wenn das Root-Verzeichnis eines statischen Hosters auf das Projekt-Root zeigt, oder in PHP-Projekten, in denen composer.json im selben Verzeichnis wie index.php liegt, was bei WordPress mit Composer und handgemachten Installationen üblich ist.

So behebst du es

  • Liefere nur den öffentlichen Ordner aus. Auf Vercel und Netlify prüfst du das „output directory" bzw. „publish directory" des Projekts; es muss der Build-Ordner sein, nicht .. In nginx und Apache zeigt root bzw. DocumentRoot auf public/ oder dist/.
  • In PHP verschiebst du composer.json, composer.lock und vendor/ eine Ebene über das öffentliche Verzeichnis, wenn dein Framework das erlaubt (Laravel und Symfony tun es bereits). Kannst du sie nicht verschieben, sperre sie:
location ~* /(package|composer)(-lock)?\.json$ { return 404; }
location ~* /(yarn|pnpm-lock)\.(lock|yaml)$ { return 404; }
  • In Apache ein <FilesMatch "^(package|composer)(-lock)?\.json$"> Require all denied </FilesMatch> in der Konfiguration oder in der .htaccess.
  • Prüf, was sonst noch hochgeladen wurde. Wo eine öffentliche package.json liegt, liegt meist eine .env, ein .git/ oder eine composer.lock daneben; die Prüfung sensible Dateien sucht die schweren Fälle.

Prüf, ob es behoben ist

for p in package.json composer.json package-lock.json composer.lock yarn.lock; do
  printf "%-20s " "$p"; curl -s -o /dev/null -w "%{http_code} %{content_type}\n" "https://deinedomain.de/$p"
done

Erwartet: 404 oder 403. Ein 200 mit text/html ist das generische HTML einer Single-Page-App und kein Problem; ein 200 mit application/json ist die echte Datei.

Häufige Fragen

Mein Repository ist ohnehin öffentlich auf GitHub.

Dann ist das Manifest bereits öffentlich und dieser Befund fügt keine neue Exposition hinzu; du kannst ihn als akzeptiert markieren. Trotzdem verhindert das Korrigieren des Server-Roots, dass die nächste Datei, die im Projektordner landet, versehentlich veröffentlicht wird.

Und die Lockfiles?

Diese Prüfung schaut auf die beiden Manifeste, aber package-lock.json, yarn.lock und composer.lock sind schlimmer: Sie listen jede transitive Abhängigkeit mit exakter Version. Ist das Manifest exponiert, ist es das Lockfile fast sicher auch; die Sperrregel oben deckt sie ab.

Wenn ich das Manifest nicht ausliefere, kann dann niemand wissen, welche Versionen ich nutze?

Man kann es auf anderen, langsameren Wegen ableiten: Header, Bundle-Pfade, Verhalten. Was veraltete Bibliotheken in deinem JavaScript erkennt, sieht zum Beispiel jeder. Das Manifest zu verbergen nimmt die Abkürzung weg; die Abhängigkeiten zu aktualisieren nimmt das Problem weg.

Prüf es auf deiner Website

Scanne deine Website kostenlos und sieh, ob dieser und 44 weitere Checks bestehen, mit einem Fix-Prompt für jedes Problem.

Meine Website kostenlos scannen

Verwandte Checks