Så importerar du inlämningar från publika formulär till ett privat nätverk
Följ en enda inlämning från ett publikt formulär från mottagningsposten till den privata importören och håll validering, inloggningsuppgifter och hantering av nya försök på rätt sida.
Ett publikt formulär som aldrig pratar med det privata nätverket producerar ändå data som det privata nätverket måste bedöma. Tunneln ändrar bara vem som ringer vem. Allt efter nedladdningen är ett importbeslut, och det hör till den privata sidan. Den här genomgången följer en inlämning från webbläsaren till en intern post som förts in.
Börja där inlämningen landar
Webbläsaren skickar till en publik slutpunkt, som skriver en rad i ett kontrollerat mottagningslager och inte returnerar något mer än en bekräftelse. Det lagret är överlämningspunkten, och det bör vara det enda som det publika lagret kan skriva till. Håll den råa nyttolasten där oförändrad, tillsammans med tiden den kom in och en stabil postidentifierare.
Därefter hämtar en privat arbetare väntande rader genom tunneln och avgör vad som ska göras med var och en. Den körs under sin egen identitet, och det är ämnet för nästa avsnitt.
curl --silent --fail \
--cert /etc/importer/client.crt --key /etc/importer/client.key \
"https://intake.corp.internal/api/pending?limit=20" \
-o /var/lib/importer/pending.json
Ge importören bara den behörighet den behöver
Den publika webbprocessen och identiteten som skriver in i den interna applikationen bör vara två olika parter. En publik server behöver ingen intern administration bara för att den måste leverera formulärdata, och ett delat konto för båda sidor gör varje webbugg till en intern skrivning. Utfärda egna inloggningsuppgifter till arbetaren, begränsa dem till den enda importoperationen och registrera vilken part som utförde varje import. Den separationen är det som gör tunnelgränsen meningsfull i stället för dekorativ.
Begränsa också vilken källa arbetaren får läsa från. Om implementeringen använder en kö eller en överföringstjänst behåller den tjänsten sin egen autentisering och åtkomstpolicy, eftersom VPN inte autentiserar något inne i nyttolasten.
En kortlivad funktion är inte undantagen från samma granskning. Medan den körs ger nätverkspositionen och inloggningsuppgifterna fortfarande behörighet, och en kortare livstid gör bara fönstret smalare. Livstid är ingen ersättning för att avgöra vilka operationer identiteten får utföra.
Validera innan något internt ändras
Publika formulärfält är text som angriparen kontrollerar tills motsatsen bevisats, och OWASPs vägledning för indatavalidering räknar backend-flöden bland opålitliga källor just därför. En krypterad överföring säger att byten kom fram intakt, inte att de beskriver en tillåten begäran. Parsa och validera före varje privilegierat steg, så att en dålig rad aldrig når en kodväg som kan agera.
Definiera de tillåtna fälten, deras format, deras storlekar och de affärsregler som måste gälla. Ett datum kan vara välformat och ändå fel för operationen som begärs, och en nyttolast som namnger ett internt konto eller en godkännandestatus får inte kunna ge sig själv något av dem.
Skicka avvisade rader till ett granskningsresultat i stället för att gissa en rättelse eller vidarebefordra dem till ett skal eller ett rått databasgränssnitt. Logga postidentifieraren och regeln som misslyckades, inte varje fält som sökanden skrev.
Skapa en återförsökspunkt på en operation
Om posten submission-1042 hämtas två gånger eftersom den första bekräftelsen gick förlorad, behöver arbetaren ett varaktigt sätt att känna igen källposten och dess införda resultat. Ett schema som kör jobbet en gång fastställer inte att varje rad tillämpades en gång. Dubbel leverans är normalt, så designen måste absorbera den.
Använd den interna applikationens egen transaktion och mekanism för dubbletter, och håll källidentifieraren, resultatet och bekräftelsen i en sammanhängande sekvens. Bekräfta först efter att den avsedda operationen förts in eller varaktigt tilldelats, och radera aldrig mottagningsraden bara för att byten laddades ned.
Bevisa det sedan med tre fasta testfall: en giltig rad, en felformaterad rad och samma kontrollerade källidentifierare levererad två gånger. Var och en går genom samma slutpunkt som arbetaren använder.
for f in fixtures/valid-submission.json fixtures/bad-date.json; do
curl --silent --fail --cert /etc/importer/client.crt \
-X POST --data @"$f" https://intake.corp.internal/api/records
done
curl --silent --fail --cert /etc/importer/client.crt \
-X POST --data @fixtures/valid-submission.json https://intake.corp.internal/api/records
De två första raderna måste sluta i olika interna tillstånd, och den tredje måste returnera identifieraren som redan förts in för den källposten i stället för att skapa en andra. Allt annat betyder att importen ännu inte är repeterbar.