Cum să imporți trimiteri din formulare publice într-o rețea privată
Urmărește o singură trimitere dintr-un formular public de la înregistrarea de primire până la importatorul privat și ține validarea, acreditările și gestionarea reîncercărilor de partea corectă.
Un formular public care nu vorbește niciodată cu rețeaua privată produce totuși date pe care rețeaua privată trebuie să le judece. Tunelul schimbă doar cine sună pe cine. Tot ce urmează după descărcare este o decizie de import și aparține părții private. Acest ghid urmărește o trimitere de la browser până la o înregistrare internă confirmată.
Începe acolo unde ajunge trimiterea
Browserul trimite către un punct final public, care scrie un rând într-un depozit de primire controlat și nu returnează nimic mai mult decât o confirmare. Acest depozit este punctul de predare și ar trebui să fie singurul lucru în care nivelul public poate scrie. Păstrează acolo datele brute neschimbate, împreună cu momentul sosirii și un identificator stabil de înregistrare.
Apoi un lucrător privat extrage rândurile în așteptare prin tunel și decide ce să facă cu fiecare. Rulează sub propria identitate, iar acesta este subiectul secțiunii următoare.
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
Dă importatorului doar autoritatea de care are nevoie
Procesul web public și identitatea care scrie în aplicația internă ar trebui să fie doi principali diferiți. Un server public nu are nevoie de administrare internă doar pentru că trebuie să livreze date de formular, iar un singur cont partajat pentru ambele părți transformă orice eroare web într-o scriere internă. Emite lucrătorului propriile acreditări, limitează-le la singura operațiune de import și înregistrează ce principal a efectuat fiecare import. Această separare este ce face granița tunelului semnificativă, nu decorativă.
Restrânge și sursa din care lucrătorul poate citi. Dacă implementarea folosește o coadă sau un serviciu de transfer, acel serviciu își păstrează propria autentificare și politică de acces, deoarece VPN-ul nu autentifică nimic din interiorul conținutului.
O funcție de scurtă durată nu este exceptată de la aceeași analiză. Cât timp rulează, poziția sa în rețea și acreditările sale încă acordă autoritate, iar o durată de viață mai scurtă doar îngustează fereastra. Durata de viață nu înlocuiește decizia privind operațiunile pe care identitatea le poate executa.
Validează înainte ca ceva intern să se schimbe
Câmpurile formularelor publice sunt text controlat de atacator până la proba contrarie, iar îndrumările OWASP privind validarea datelor de intrare includ fluxurile din backend printre sursele neîncrezute exact din acest motiv. Un transfer criptat spune că octeții au ajuns intacți, nu că descriu o cerere permisă. Analizează și validează înaintea oricărui pas privilegiat, astfel încât un rând prost să nu ajungă niciodată pe o cale de cod care poate acționa.
Definește câmpurile permise, formatele lor, dimensiunile lor și regulile de afaceri care trebuie respectate. O dată poate fi bine formatată și totuși greșită pentru operațiunea cerută, iar un conținut care numește un cont intern sau un statut de aprobare nu trebuie să-și poată acorda niciunul dintre ele.
Trimite rândurile respinse către un rezultat de analiză în loc să ghicești o corecție sau să le direcționezi către un shell ori o interfață brută de bază de date. Înregistrează identificatorul rândului și regula eșuată, nu fiecare câmp tastat de solicitant.
Creează un punct de reîncercare la o singură operațiune
Dacă înregistrarea submission-1042 este extrasă de două ori pentru că prima confirmare s-a pierdut, lucrătorul are nevoie de o modalitate durabilă de a recunoaște înregistrarea sursă și rezultatul ei confirmat. Un program care rulează sarcina o dată nu stabilește că fiecare rând a fost aplicat o dată. Livrarea duplicată este normală, așa că designul trebuie să o absoarbă.
Folosește tranzacția și mecanismul de gestionare a duplicatelor ale aplicației interne, și păstrează identificatorul sursă, rezultatul și confirmarea într-o singură secvență coerentă. Confirmă numai după ce operațiunea dorită este înregistrată sau atribuită durabil și nu șterge niciodată rândul de primire doar pentru că octeții au fost descărcați.
Apoi dovedește-o cu trei fixture-uri: un rând valid, un rând formatat greșit și același identificator sursă controlat livrat de două ori. Fiecare trece prin același punct final pe care îl folosește lucrătorul.
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
Primele două rânduri trebuie să se termine în stări interne diferite, iar al treilea trebuie să returneze identificatorul deja înregistrat pentru acea înregistrare sursă, în loc să creeze unul secund. Orice altceva înseamnă că importul nu este încă repetabil.