Jeg har lige bygget en webshop op helt fra bunden. Det jeg gerne vil vide lidt om, og have folk til at tjekke er sikkerhed omkring den.
Det er f.eks. lige lykkedes mig meget let, at gennemføre en ordre på en unangivet rimelig stor webshop uden at betale, fordi de ikke validerer deres input ordentligt. Har sendt dem en mail og forklaret dem at de har et problem.
Men har folk herinde ikke lyst til at give lidt feedback til hvad man skal være opmærksom på? Tror mange herinde er nysgerrige omkring det.
Hvis i har lyst til at tjekke min shop i gennem for sikkerhed, må i meget gerne sige til, så poster jeg lige linket.
Jeg vil da meget gerne se din shop igennem ved lejlighed :)
Der er en række forbehold du skal tage, når du implementerer en webshop, hvad angår sikkerhed. Heriblandt er det især vigtigt, at
- Validerer samtlige brugerinput, som du selv nævner. Ikke mindst for at undgå hackerangreb, såsom cross-side scripting og SQL-injections. Det er altid bedre at lave en liste over input man accepterer, og så rejecte alt andet, end at lave en liste over ting man ikke accepterer, og tillade alt andet. Det giver langt bedre føling over, hvad der kommer ind i dit system.
- Kontroller for hvért step i din shop, at brugeren er logget korrekt ind (hvis det er nødvendigt), og har de korrekte rettigheder.
- En nyoprettet bruger bør enten følge et aktiveringslink, eller logge sig ind via et auto-genereret password, før sitet kan anvendes. Det sikre, at der ikke er en eller anden spider, som crawler over dit site og lægger ordrer ind.
- Undlad at have href="mailto:xx@xxx.xx" links på dit site, da disse nemt bliver crawlet, og anvendt til spam.
- Andvend hashing af kodeord. Det giver en rigtig god beskyttelse mod, at nogle udefrakommende skulle tilsnige sig adgang til dine brugeres informationer, og handle i deres navn.
- Nu ved jeg ikke om du har valgt selv at implementere en betalingsgateway, eller om du gør brug af 3. parts, men under alle omstændigheder bør denne køre over en 128-bit krypteret SSL linie (går jeg ikke ud fra er nødvendigt at nævne, men er taget med alligevel)
Det var lige et par stykker fra hoften.. vigtige er de allesammen, men vigtigst er nok nummer 1. Praktisér "defensive programming", og valider samtlige input grundigt, så er du i de fleste tilfælde rigtig godt stillet.
Helt sikkert vigtige punkter. Nu bruger jeg ikke login selv, da jeg har indtrykket af at folk synes det er meningsløst, og diverse blog indlæg rundt omkring på nettet bekræfter også dette. Men for folk der gør er det godt at vide.
For at forhindre SQL-injections, har jeg udover validation htmlentities(addslashes(værdi)) rundt om alt der ryger ind i en mysql_query. Er det en god måde at sikre sig på? HVad med cross-side scripting, hvad er det hel præcit at der kan ske der?
Jeg bruger betalingsgateway fra 3. part (Epay).
Min webshop er indtil videre på www.nicker.dk. Den er ikke helt færdig, men der mangler ikke meget.
htmlentities(addslashes(value)) er et rigtig godt udgangspunkt, og sikre dig imod en lang række utilsigtede handlinger. Jeg vil dog anbefale dig også at validere dine input op imod regulære udtryk (regular expressions), hvilket jeg selv altid gør. På den måde kan der ganske enkelt ikke komme "bad content" ind i systemet. Dog er problematikken her, at man kan ende med at lave for mange begrænsninger, så brugerne ikke har udtømmende muligheder. Det er en vurderingssag.
Anvendelse af 3. part betalingsgateway er klart at foretrække, og det regnede jeg også med at du ville gøre :)
Cross-side scripting er, når man f.eks. skriver et lille javascript ind i et inputfelt. Da PHP compiler på runtime, vil scriptet ikke blive vist, men istedet parsed og executed. En klassiker her er at redirecte folk me history objectet i javascript, til andre sider, enten med skadeligt indhold, eller måske en fishing side. Derfor skal < og > ALDRIG være tilladte, og heller ikke < og >, da dei nogle tilfælde kan anvendes til samme formål. Til sammenligning med virkeligheden kan det nævnes, at Microsoft Hotmail blev hacket med denne metode med 2 liniers kode for et par år siden.. så derfor, tillad ALDRIG script-tegn :)
Hvad angår login, så er det fornuftigt at lægge sig op af meningsudtalelser på nettet. I mit eget modul har jeg dog lavet det således, at det både er muligt at handle anonymt og som registreret bruger. Det vil sige, at hvis en besøgende har handlet, checkes der ved check-out, om han/hun er logget ind. Er det tilfældet, anvendes oplysningerne i databasen, og hvis ikke, vises en formular, hvor man kan indtaste sine shipping- og billinginformationer.
Ja har godt læst det eksempel med hotmail faktisk. Læste også at Google havde på et tidspunkt.. Det lyder rimelig farligt. Men for at undgå at < > er tilladte, skal man så lave reg. exp. på alle sine input, eller er der en anden måde at komme uden om problemet.
- F.eks. ved navn og efternavn, vil jeg gerne undgå at begrænse folk og komme til at "støde" dem hvis man nu ikke tillader deres navn, derfror tjekker den kun for om der findes input i feltet. Men bliver man stadig nødt til at lave reg. exp. for at undgå at de udfører scripts...
Ja ok det er også smart nok at have begge dele.
Ja er ved at blive gråhåret over de æ, og å. Det er kun når man ser det AJAX overlay, at den ikke viser dem ordentligt, ikk?
En anden hyggelig one-liner (såfremt ens tekst er utf8-encodet) er denne
$val = preg_replace('!p{C}!u', '', $val);
Den fjerner lidt "underlige" tegn ("Other" klassen af utf-8 tegn..) fra ens tekststreng.. Måske burde man også fjerne Cc klassen (control-characters).. hmm.. Vil jeg lige undersøge
Og hvis man virkeligt vil, så husk at valider at ens data faktisk er utf-8 encodet (igen, såfremt at man kører med utf-8 encoding.. ) Der er en hyggelig funktion som denne:
praktisk (returnere true/false alt efter om strengen er gyldig utf8)
Husk desuden at angiv charset til htmlentities hvis du ikke kører iso-8859-1
--
For at sikre SQL-injections findes desuden mysql_real_escape_string som sikre mod tegn der kan lave injections på MySQL..
--
Generelt kan mange problemer og huller skyldes forskellige encoding af data når de sendes ind..
--
Dit problem ang ÆØÅ er nok også utf-8/iso-8859-1 baseret. Husk, AJAX skal sendes og modtages som utf-8.. (undtagen Safari der er hr modsat og vil have iso-8859-1)
Bah.. det skal være preg_replace('!\p{C}!u', '', $val) (back-slash før p).. (og fandt lige ud af at Cc er et subset af C.. så lærte jeg også noget idag)
jeg ville klart anvende reg. exp. til totalt at forbyde < og >.. jeg kan umiddelbart ikke komme på nogen steder de skulle være nødvendige, ud over scripting..
og havde helt glemt mysql_real_escape_string.. den bør også klart benyttes (antaget du bruger mysql).
- men vil man gerne kunne kommunikere med resten af verden og udveksle data (og hvad skulle meningen med WWW ellers være?), er det lettest at bruge utf-8, über alles ;o)
Darn - nåh, men så har jeg da også lært noget. Men faktum er stadigt at et standard AJAX går ud fra at det modtagne data er UTF-8 encodet. At man så kan ændre dette vidste jeg ikke..
Lige for at dele lidt info med alle, så findes der en eBog ved navn E-Pusher, som det varmt kan anbefales at læse af alle, som overvejer at beskæftige sig med e-handel. Prisen er lidt pebret, mener det er 1.500,00 kroner for et pdf-dokument på 123 sider. Men vil man være seriøs indenfor e-handel, skulle det være pengene værd.
Fik løst mit problem med de tegn. Det var en simpel htmlentities() rundt om ouput fra database der skulle til. Så nu er der ingen problemer med det.
Men tilbage til det med sikkerhed. Nu har jeg siddet og kæmpet med sikkerhed de sidste par dage, og validerer nu alt input til databasen. Jeg har dog opdaget et par major sikkerhedsfejl. Ved ikke om det kun gælder min eller også andre sider.
Jeg har på min side en Godkend ordre side lige før man betaler, hvor man bliver præsenteret for det samlede beløb. Fra denne side sendes så et beløb til betalingsmodulet med et hidden input. Man kan ændre i hidden input feltet, men det gør ikke så meget, da der bliver genereret en md5 streng, der bliver sammenlignet i betalingsmodulet, og hvis de ikke stemmer overens afvises betalingen. Det problem jeg har fundet, er a hvis man er på Godkend ordre siden, og åbner en side på siden i nyt vindue, så kan man tilføje en vare, uden at denne vares beløb bliver lagt til det samlede beløb. Det må anses som en sikkerhedsfejl, ikk?
Du har ikke løst problemet. Godt nok har du trådt på termometeret, så du ikke kan se, om patienten er syg - men 'han' har stadig 41,8 i feber ;o)
htmlentities slører kun problemet. Du kører stadig med forskelligt tegnsæt i de forskellige led af kæden og får derfor også flere problemer med tiden. Den eneste måde at løse problemet på er at bruge samme tegnsæt overalt.
Ja men hvis du bare skrev Læg i indkøbskurv eller tilføj ønskeliste på siden der blev hentet, så blev det vist uden problemer. Det var kun når indholdet blev hentet fra min database at den viste det forkert. Det var derfor jeg kom frem til løsningen med htmlentities.
Og det var kun når indholdet fra databasen blev vist på den specifikke side der var problemer. Andre steder på sidden kører det fint. Men alle mine tabeller har kollation: latin1_swedish_ci. Det er bare ikke noget jeg har valgt selv, det må være automatisk.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.