Archive for the ‘Programmering’ category

Sikkerhet i PHP gjort lettere

juli 25th, 2010

Når du utvikler en nettside, enten det er en applikasjon, rammeverk, bibliotek — hva som helst — er det desidert viktigste sikkerhet. Likevel er det mange som tar snarveier, og slurver seg unna. Om du vil unngå å stå med skjegget i postkassen den dagen du blir angrepet via XSS, CSRF eller SQL injections bør du følge med nå.

Hvorfor?

Du skal aldri stole på brukerne dine. Selv om det er familien eller vennene dine. Årsaken er at enkelte personer kan utnytte sårbarhetene i systemet ditt, som kan resultere i at sensitiv informasjon blir samlet, slettet eller endret. Det kan resultere i at noen tar fysisk kontroll over nettsiden din.

Hva kan man gjøre?

Ved å følge prinsippet ovenfor, må du sørge for å validere all data du skal hente inn fra brukerne. Du bør også sanitere data.

Validering: sjekke om data er av riktig type, for eksempel en ordentlig E-postadresse eller postnummer.
Sanitering: manipulasjon av data, som for eksempel å fjerne enkelte tegn/bokstaver/tall og så videre.

I PHP får vi tilgang til brukerdata via super-globalene $_GET, $_POST, $_COOKIE, $_SERVER og $_SESSION.

Her kan brukere bokstavelig talt skrive hva de vil, og det kan betyr store følger om du ikke sjekker dataene ordentlig.

Løsningen

Jeg har skrevet et bibliotek i PHP kalt “PHP Security Wrapper“. Dette biblioteket tar seg av brukerdata fra GET, POST, SERVER og COOKIE, samtidig som du får muligheten til både å validere og sanitere dem.

Biblioteket er selvfølgelig gratis, og oppdateres hyppig. Om du ønsker å lære mer om dette biblioteket kan du lese forumtråden jeg postet på Norsk Webforum, sjekke ut nettsiden og lese dokumentasjonen.

Det er ikke meningen at dette blogginnlegget skulle ta for seg hvordan du kan sikre deg mot angrep, men om du ønsker å lese videre på emnet kan du sjekke ut følgende linker:

Wamp: Sette opp egen hjemmeserver

april 26th, 2010

Tidligere har jeg beskrevet hvordan du kan installere ffmpeg på Wamp, samt hvordan du kan opprette underdomener på Wampserver. Nå tenkte jeg å forklare hvordan du kan sette opp en liten hjemmeserver som du få tilgang til gjennom Internett.

Hva er en hjemmeserver?

Kort sagt er det et Webhotell du har på din egen PC. Du styrer alt av underdomener (forklart i egen artikkel), PHP-, Apache- og MySQL-innstillinger med mer. Veldig fleksibel løsning til utvikling, da du kan invitere andre utenfor nettverket ditt til f. eks. å teste systemet.

For å koble deg på hjemmeserveren, stilles det to krav:

  • WampServer må kjøres, og satt i Online-modus
  • Port 80 må være åpen, det vil si at du har viderekoblet denne i ruteren din til PC-ens IP-adresse.

NB: Du vil ikke bli tildelt et domenenavn (som «minside.com») da dette blir styrt av en DNS, som ofte koster penger.

Hva trenger vi?

Normalt bruker Internett port 80 til å sende og motta informasjon, men noen ISP-er har denne porten blokkert slik du ikke kan sette opp en hjemmeserver. Slapp av — det er mulig å jobbe seg rundt.

Om det skulle vise seg at porten er blokkert, må du konfigurere Apache til å følge med på (eng. «listen») en annen port. Velg gjerne 8080.

Videre i denne guiden tar jeg som utgangspunkt at du kan bruke port 80 uten problem (dette gjelder de aller, aller fleste).

Let’s get to it!

I mitt internnettverk har PC-en min (som serveren er installert på) en fast IP-adresse, 192.168.0.197. Ruteren min er en Linksys WRT54GL (som jeg for øvrig anbefaler på det sterkeste). Jeg tar ikke opp emnet om å videreføre porter i denne guide, da alle har hver sin ruter og oppsettet varierer derfor. Men ved å følge Port Forward sin enkle guide, blir det en lek å åpne porten. Sørg bare for at PC-en din er stilt inn med en statisk IP!

Når du har sørget for at porten din er åpen, vel — da er du i bunn og grunn ferdig. Om du er i tvil om du har åpnet porten skikkelig, så kan du ta deg en tur innom CanYouSeeMe og skriver inn 80 som portnummer. Du er nødt til å ha Wamp kjørende for at den skal klare å sjekke det. Om du får opp en feilmelding, er det fordi:

  • Du har gjort en feil da du åpnet porten din. Har du skrevet inn riktig IP-adresse, og haket av for “Enable” ?
  • ISP-en (Internett-tilbyderen) din blokkerer port 80, og du må derfor velge en annen port

Jeg vil råde deg til å passordbeskytte både phpMyAdmin og index.php i www-mappen. På denne måten har du kontroll over at ingen uvedkommende skal ødelegge prosjektene dine.

For å sjekke om du virkelig kan koble deg til serveren din, går du innom WhatIsMyIP og finner ut hvilken IP-adresse du har på Internett. Kopier denne inn i adressefeltet i nettleseren din, og se resultatet!

IP-en peker egentlig til ruteren din (det ytterste elementet i nettverket ditt), men ruteren vil registrere at du kommer fra Internett (port 80), og retter denne forespørselen videre til en PC på lokalnettet. Dette gjelder selvsagt kun dersom du har konfigurert ruteren din slik jeg har beskrevet.

Jeg kan skissere prosessen slik:

Om du føler det blir vanskelig å huske IP-adressen din hver gang du skal innom serveren din, kan du alltids registrere deg hos en gratis DNS-tilbyder.

Håper du fikk nytte av denne guiden! Kom gjerne med tilbakemeldinger i kommentarfeltet.

Yr.no – vise værdata direkte på nettsiden din

mars 12th, 2010

Siden den norske nettbaserte værtjenesten Yr.no frigir sine værdata gratis, er det mange som er i stand til å vise været fra sin hjembygd på nettsidene sine. Men hvordan gjør dem det?

Jeg skrev for en stund tilbake siden en PHP-klasse som gjorde akkurat dette: hentet frem værdata basert på et norsk postnummer.

Funksjonen mellomlagrer værdataene i ti minutter, slik at belastningen på Yrs servere skal minimeres, og at lastetiden hos brukeren skal oppleves raskere.

Kort fortalt er det kun fem linjer med kode du bør konsentrere deg om:

define ('PATH_WEATHER_ICONS', 'img/weather/');
define ('PATH_CACHE', 'cache/');
define ('CACHE_EXPIRATION', 600);
// How many days we are going to show
define ('DAYS_TO_SHOW', 3);

// The Zip code to which place we will fetch information about
// Defaults to 5440
$zip = isset ($_GET['zip']) ? intval ($_GET['zip']) : 5440;

Først av alt må du fortelle hvilken mappe bilde-ikonene ligger i, og hvor PHP-klassen skal mellomlagre dataene. Deretter spesifiserer du hvor lenge dataene skal bli mellomlagret (600 sekunder = 10 minutter), samt hvor mange dager fremover i tid du skal vise.

Sist, men ikke minst må du spesifisere fra hvor du skal hente værdata fra. Du må endre “5440″ til det postnummeret du vil scriptet skal vise ved default. Dersom du vil se værdata fra et annet postnummer, skriver du følgende i adressefeltet:

index.php?zip=<nytt postnummer her>

Laste ned

PHP-klassen er tilgjengelig via tillegg.yr.no, og er som vanlig lisensiert under Creative Commons.

Tips

Du kan meget lett integrere PHP-klassen min med databasesettet mitt over alle norske postnummer. Slik kan du også finne ut om postnummeret brukeren ønsker å vise, faktisk finnes. Mer informasjon om databasesettet finner du i egen artikkel.

Tilbakemeldinger

Som vanlig setter jeg pris på tilbakemeldinger, som du kan dele i kommentarfeltet!

Komplett databasesett over Norges postnummer (med koordinater)

mars 12th, 2010

Her kommer det er oversikt over absolutt alle postnummer i Norge med tilhørende fylke, kommune og poststed. Hvert postnummer har også en lengde- og breddegrad tilknyttet seg. På denne måten kan du koble opp postnummeret til f.eks Google Maps.

Det er i alt fire tabeller i databasesettet:

  • Comments
  • County
  • Municipal
  • Zip
    • _codes
    • _places

Første tabell inneholder bare seks rader, som forklarer om postnummeret er av typene:

  • Firma med eige postnummer
  • Fleire bruksområde
  • Gateadresser
  • Gateadresser og postboksar
  • Postboksar
  • Serviceboksar

Databasesettet er generert med hjelp av Postnummer-dugnaden Yr.no arrangerte sommeren 2009.

Ved hjelp av lengde- og breddegradene kan du jo også regne deg frem til avstanden mellom to steder, eller finne nærmeste postkontor til en bruker.

For å få lett oversikt over alle postkoder, kjører du følgende spørring:

SELECT
z.zip, c.name as fylke, m.name as kommune, p.name as poststed, cc.comment, z.lat, z.lon
FROM `zip_codes` z
INNER JOIN zip_places p
ON p.place_id = z.place_id
INNER JOIN municipal m
ON m.id = p.municipal_id
INNER JOIN county c
ON c.county_id = m.county_id
INNER JOIN comments cc
ON cc.comment_id = z.comment_id
ORDER BY
z.zip ASC, fylke ASC, kommune ASC, poststed ASC

Med enhver sak kan det forekomme feil, så om dere kommer over noe som skulle vise seg til å være en bug: si i fra.

Liste over alle postnummer:
http://trunk.davidsteinsland.net/zip_codes.htm

Oppdateringer

  • Ser ut til at Jan Mayen og Svalbard har klart å falle ut. Dette er pga. øyene ikke tilhører noe fylke. Skal ordnes.
  • Fikset nå. Poststeder på øyene er plassert i et eget dummy-fylke kalt “Svalbard og Jan Mayen”
  • Fylkene har nå fått korrekt fylkesnummer basert på ISO 3166-2:NO. Fikset opp i kommuner på Jan Mayen og Svalbard

Laste ned

Norske postnummer.zip, lisensiert under Creative Commons.

Tips & triks

Hvordan finne et originalpunkt basert på gitt bredde- og lengdegrad?

Basert på sfærisk trigonometri kan vi “enkelt” regne oss frem til dette. Først av alt må vi gjøre punktene våres om til radianer (fra grader) for at funksjonen skal gjelde. Vi benytter oss også av jordradien i meter.

Distansen mellom punktene er gitt ved s:

s = \cos^{-1}\big( \sin \phi \cdot \sin \phi_0 + \cos \phi \cdot \cos \phi_0 \cdot \cos \Delta \lambda \big) \cdot R_\oplus

Breddegradene (\phi) og lengdegradene (\lambda) må først gjøres om til radianer. Dette gjør du med følgende formel:

{rad} = \frac{180^\circ}{\pi} \cdot {deg}

Dette er igrunn irrelevant, for dette har jeg allerede tatt høyde for i kodene.

For å løse det i MySQL, kan man gjøre det slik:

 SET @MY_LAT = 59.7022480, @MY_LON = 5.3764340;

SELECT z.zip, p.name, z.lat, z.lon, acos(SIN( RADIANS(@MY_LAT)) * SIN( RADIANS(z.lat))
+(cos(RADIANS(@MY_LAT)) * COS( RADIANS(z.lat)) * COS(RADIANS(z.lon) - RADIANS(@MY_LON))
)) * 6378137 AS distance
FROM zip_codes z
INNER JOIN zip_places p
ON z.place_id = p.place_id
HAVING distance <= 2000
ORDER BY distance ASC

Her har jeg satt variablene utenfor selve spørringen slik at det blir litt lettere å få det med seg.

I PHP kan man gjøre det slik:

$lat_1 = deg2rad (59.7022480);
$lat_2 = deg2rad (59.7022480);

$lon_1 = deg2rad (5.3764340);
$lon_2 = deg2rad (5.3764340);

$R = 6378137; // meters

$distance = acos ( sin($lat_1) * sin($lat_2) + cos ($lat_1) * cos($lat_2) * cos ($lon_2 - $lon_1)) * $R;
echo 'Distance: ' . (int)$distance/1000 . ' km'; 

Hva betyr dette? Hva kan man nytte det til?
Dersom du bruker en pakkeløsning hvor du kan dra frem koordinatene til en bruker basert på hans IP, kan du finne ut en circa-plassering på hvor han er i Norge. Formelen har en feilkilde på rundt 1 meter.

Bruke jQuerys Ajax-funksjonalitet til å hente ut data om postnummer

1. Opprett en fil kalt “get_postal.php” med følgende kode:
http://norskwebforum.no/pastebin/11243

2. Opprett så index.html med følgende kode:
http://norskwebforum.no/pastebin/11244

3. Opprett en mappen “cache”

Test ved å skrive inn et postnummer (fire siffer langt) eller et poststed. Informasjon om postnummeret/-stedet vil etterhvert poppe opp i avsnittet under skjemaet.

LaTeX på nett: matematiske formler til bilder

mars 12th, 2010

Innenfor realfagene matematikk, fysikk og kjemi skriver jeg alt av rapporter og øvinger i LaTeX, som er et typesettingssystem for dokumentproduksjon. Det er spesielt egnet for matematisk litteratur, og blir definert av den engelske Wikipedia slik:

A document-typesetting system derived from TeX and used mainly to create scientific and mathematical literature.

LaTeX er originalt skrevet for Linux, men er per i dag tilgjengelig på alle plattformer gjennom ulike distribusjoner. Personlig bruker jeg distribusjonen MikTeX med versjonsnummer 2.8. Redigeringsprogrammet jeg bruker heter LaTeX Editor — forkortet LEd.

Det er tusenvis av fordeler for å bruke LaTeX kontra såkalte What You See Is What You Get-program (Microsoft Office, OpenOffice, Lotus Symphony etc.). Den største er at i LaTeX så er det du som har kontrollen: What You See Is What You Mean.  Ting blir faktisk slik du sier det skal være!

Du har vel sett noen matematiske formler på Wikipedia? Der anvender de nemlig  LaTeX, og ser omtrent slik ut:

Det er nemlig dette jeg har tenkt å ta tak i, i denne posten: nemlig forklare deg hvordan du også kan få slike deilige formler på din nettside!

Hva må gjøres klart?

For å skrive LaTeX på PC-en din, og for at alt skal gå optimalt, krever det en rekke program som f.eks MikTeX (LaTeX-distro), LEd (redigering) og GhostScript / Ghost View (postscript-støtte). For å skrive LaTeX på nett krever jeg derimot at du kun har MikTeX installert!

PS: Jeg tar som utgangspunkt at webserveren din er din egen PC. Veldig få webhotell-leverandører som installerer LaTeX…

Last så ned siste versjon av MikTeX og installer denne på PC-en din. For din egen del er det nok lurest å velge “Basic Installer”. Her vil kun de mest nødvendige pakkene bli installert (pakker kan oversettes som plugins). Om du ønsker å installere alle pakker tilgjengelig, velger du “Complete MikTeX System”.

La oss begynne!

Det aller første du må gjøre rede for er følgende:

  1. Hvor installerte du MikTeX?

La oss si du installerte programmet i C:\Programfiler\MikTeX 2.8\

Da må du leite frem til miktex\bin\latex.exe og \miktex\bin\dvipng.exe.

Dersom disse programmene ikke er tilstede, vil du ikke være i stand til å gjennomføre denne guiden: prøv da å re-installere MikTeX.

Har du lokalisert programmene? Flott — da går vi videre.

Finn frem til root-mappen på serveren din (bruker du WampServer er dette C:\wamp\www\). Opprett en mappe som du kaller for “latex”.
Inni den nye mappen, oppretter du så følgende mapper:

  • images
  • tmp

«Images» er mappen hvor de endelige formlene kommer til å bli plassert, og «tmp» er mappen hvor produksjonsfilene våre ligger. Når du kompilerer et dokument i LaTeX vil det bli opprettet totalt 4 filer per prosjekt. Disse er respektivt .tex, .aux, .log og .dvi. Tex-filen inneholder selve dokumentet vårt, og DVI-filen er selve outputen etter kompilering. Disse to er essensielle.

PHP-klassen

Jeg har allerede skrevet klassen ferdig, som du skal få. Før jeg overrekker den, vil jeg ta tiden til å forklare litt hva den gjør.

Det er to ting du umiddelbart må få i stand etter at du har lastet ned klassen:

- Øverst i klassen er det deklarert to variabler: _latex_path og _dvipng_path. Disse må du endre til hva du fant ut i punkt #1 (under «La oss begynne!»). Det er veldig viktig at du følger denne regelen når du endrer sti: Variabelen må være omgitt av to enkle apostrofer, og selve stien til programmene må være omgitt av gåseøyne.

Dette er fordi at dersom det er mellomrom en plass i stien (i C:\Program Files\MikTeX\ er det mellomrom i “Program Files”) må teksten være omgitt av gåseøyne, som forteller at teksten skal tolkes som én sti, og ikke to.

Dersom stien til latex.exe på PC-en din er følgende: C:\Program Files\MikTeX 2.8\miktex\bin\latex.exe skal _latex_path være formet slik:

 $_latex_path = '"C:\Program Files\MikTeX 2.8\miktex\bin\latex.exe"';

Utover dette, skal klassen fungere ut-av-boksen (dersom du har opprettet de korrekte mappene).

Laste klassen ned

PHP5 LaTeX Renderer, lisensiert under Creative Commons.

Hvordan fungerer klassen?

I seg selv er den ganske liten, og rett frem. Det er en innebygget cache-funksjon som lagrer bildene ved hjelp av:

  • den matematiske formelen
  • tekst-størrelsen

Om du vil endre tekst-størrelse, gjør du slik:

$latex = new LaTeX();

$latex->set ('font_size', 16); // 16 is the font size, measured in "points"

Dersom du vil endre artikkel-klassen for dokumentet, gjør du slik:

$latex->set ('article_class', 'article'); 

Ved default er det «scrartcl» som fungerer som dokumentets klasse, men dette er en tilleggspakke som må installeres. Derfor kan du anvende «article» som kommer ferdig-installert via MikTeX.

… og slik setter du innholdet:

$latex->set ('tex_content', '\frac{1}{2}');

For å rendere dokumentet, og vise den endelige formelen som et bilde, gjør du slik:

$data = $latex->render ();
echo '<img src="' . $data['img'] . '" alt="' . $data['tex'] . '" />';

Klassen støtter naturligvis linking, og kan brukes slik:

$latex = new LaTeX();

$data = $latex->set ('font_size', 16)->set ('tex_content', 'ax^2 + bx + c = 0')->render ();

Dersom du ønsker å skrive ABC-formelen (som jeg viste lengre oppe i artikkelen), skriver du den slik:

 x = \frac{ -b \pm \sqrt{b^2 - 4ac}}{2a}

Flyteskjema

For de av dere som er interessert i flowcharts (meg inkludert): slik er fremgangsmåten i klassen:

Det var det!

Nå er du i bunn og grunn ferdig, og kan begynne å eksperimentere selv. Det rådes selvsagt at du har noen kunnskaper innen LaTeXs måter å skrive ting på. Om du vil lese deg opp på emnet, er det mange gode ressurser for det:

Om det er noen spørsmål om hjelp, tips til forbedringer etc, kan dette tas opp i kommentarfeltet.

PS: LaTeX uttales Lah-tek. Vil ikke høre om noen som sier det rett ut..