← Alle checks
BeveiligingTypische ernst: Laag

Scanner voor interne verwijzingen

Detecteert links naar localhost of interne IP's in de HTML, ontwikkelresten die je infrastructuur lekken.

Wat het checkt

Deze scanner bekijkt de HTML van je pagina en detecteert links naar localhost of interne IP-adressen. Hij vindt die ontwikkelrestjes die in de gepubliceerde code vergeten zijn.

Waarom het belangrijk is

Deze interne verwijzingen lekken details over je infrastructuur, zoals serveradressen en -namen die alleen intern bekend zouden moeten zijn. Die informatie helpt een aanvaller te begrijpen hoe je systeem is opgebouwd en zijn volgende stap te plannen.

Hoe je het oplost

Bekijk je code voor je publiceert en vervang alle verwijzingen naar localhost of interne IP's door de echte productie-URL's. Je omgevingsvariabelen netjes per omgeving instellen voorkomt dat deze ontwikkeladressen in de publieke versie belanden.

Hoe deze controle werkt

Scanaris ontleedt de HTML van je hoofdpagina en loopt alle elementen langs met een src-, href- of action-attribuut: scripts, afbeeldingen, stylesheets, links, formulieren. Voor elke waarde controleert hij of die wijst naar een host die buiten je eigen machine of netwerk niet hoort te bestaan: localhost, 127.0.0.1, 0.0.0.0, de privé-IP-reeksen 10.x.x.x, 192.168.x.x en 172.16.x.x tot en met 172.31.x.x, en elk domein dat eindigt op .local. Vindt hij er een, dan opent hij een bevinding met lage ernst en de eerste verwijzingen. Alleen de initiële HTML wordt onderzocht; wat JavaScript daarna opbouwt, wordt langs deze weg niet gezien.

Waarom dit belangrijk is

Een verwijzing naar http://localhost:3000/api/... in productie heeft twee gevolgen. Het eerste is functioneel: voor je gebruiker is localhost zijn eigen computer, dus die afbeelding laadt niet, dat formulier wordt nergens heen gestuurd en dat script faalt stilletjes. Het tweede is informatief: je vertelt iedereen dat je API op poort 3000 draait, dat je interne backend api.bedrijf.local heet of dat je netwerk de reeks 10.0.1.x gebruikt. Niets daarvan is op zichzelf een uitbuitbare fout, vandaar de lage ernst, maar het zijn stukjes die een aanvaller bewaart voor later, en ze verraden dat de deployment zonder controle naar buiten ging.

Waarom het gebeurt

Het is bijna altijd een URL die tijdens de ontwikkeling met de hand is getypt en die niemand heeft veranderd. De AI die het project genereerde zette http://localhost:8000 in de fetch van het formulier, of in de src van een testafbeelding, en het werkte lokaal, dus bleef het staan. Andere oorzaken: een ontwikkel-.env die in de productiebuild terechtkwam, een WordPress gemigreerd vanuit een lokale omgeving zonder de site-URL bij te werken, of een formulier-action gekopieerd uit een voorbeeld.

Hoe je het oplost

  • Haal de URL's uit de code. De basis van je API hoort in een omgevingsvariabele (NUXT_PUBLIC_API_BASE, NEXT_PUBLIC_API_URL, VITE_API_URL) met een andere waarde per omgeving. In productie injecteert het platform (Vercel, Netlify, Railway) die bij de build.
  • Gebruik relatieve paden zodra de bron op je eigen domein leeft: /api/contact in plaats van http://localhost:3000/api/contact. Ze werken lokaal en in productie hetzelfde.
  • WordPress: werk de site-URL's bij onder Algemene instellingen en vervang de oude URL's in de database met een tool die serialisatie respecteert.
  • Doorzoek de build voordat je deployt. Een CI-stap die faalt als de gecompileerde uitvoer deze hosts bevat, pakt het probleem bij de wortel:
grep -rEl "localhost|127\.0\.0\.1|192\.168\.|\.local\b" dist/ .output/public/ 2>/dev/null

Komt er een bestand uit, dan is er een verwijzing om te corrigeren voordat je publiceert.

Controleer of het opgelost is

curl -s https://jouwdomein.nl | grep -oE '(src|href|action)="https?://[^"]+"' | grep -iE "localhost|127\.0\.0\.1|0\.0\.0\.0|10\.[0-9]+\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[01])\.|\.local\b"

Er mag niets uitkomen. Probeer ook een of twee binnenpagina's, vooral die met formulieren.

Veelgestelde vragen

Het is een testafbeelding die niemand ziet. Maakt het uit?

De browser van elke bezoeker probeert hem van zijn eigen computer te laden, en de HTML blijft je interne host aankondigen. Verander of verwijder hem; het is een minuut werk.

Wordt het gecompileerde JavaScript ook gecontroleerd?

Niet door deze controle, alleen de HTML. Maar een interne URL in de bundel gaat meestal samen met andere dingen die er niet horen; geheimen in JavaScript zoekt sleutels en tokens, en HTML-commentaar zoekt restanten in de HTML zelf. De drie samen dekken wat er meestal overblijft van een ontwikkelomgeving.

Mijn link wijst bewust naar een .local-domein.

.local-domeinen zijn gereserveerd voor lokale netwerken (mDNS) en worden op internet niet opgelost. Wil je een intern hulpmiddel linken, gebruik dan een echt subdomein met authenticatie. Wat je app onbedoeld lekt, met meer voorbeelden, staat in geheimen die je app in de browser lekt.

Check het op je site

Scan je site gratis en zie of deze en 44 andere checks slagen, met een fixprompt voor elk probleem.

Mijn site gratis scannen

Gerelateerde checks