Etikettarkiv: PHP

Har din WordPress-blogg hackats? Läs det här

Fler och fler WordPress-bloggar hackas och en stor faktor är den sårbarhet som identifierades i TimThumb. TimThumb var inbakad i mängder plugins och teman som inte uppdateras.

Första tecknet på att din blogg hackats kan vara något av följande:

  • Din blogg försvinner från Googles-index. Dvs söker du efter din blogg så dyker den inte upp
  • Någon kontaktar dig gällande viagra eller liknande som din blogg länkar till
  • Du hittar nya filer eller så försvinner filer från din WordPress-installation

Det du måste göra när din blogg hackats är att börja om från början och försöka lista ut hur angriparna tog sig in. Så först och främst måste du se till att du har en backup av både filsystemet och databasen.

Om du har kontroll över underliggande operativsystem så bör du även installera om det då angriparna kan ha tagit sig in i operativsystemet. Att installera om och konfigurera operativsystemet är oftast krävande och tar lång tid.

Ominstallation av WordPress

Börja med att göra en ny installation av WordPress och läs sedan tillbaka databasen, ändra lösenord och titta så att inga nya konton dykt upp i WordPress. Innan du börjar med din nya installation av WordPress måste du se till att det är helt tomt på ditt konto, inga .htaccess-filer som kan vara dolda exempelvis då det finns exempel då angripare placerat bakdörrar i dessa. Om du känner dig osäker gällande dessa steg så bör du anlita eller fråga någon som kan WordPress bra.

Installera alla plugins som du behöver och gå manuellt igenom samtliga och undersök huruvida det har identifierats några sårbarheter i dem på sistone. Secunia har en söktjänst där du kan söka på pluginnamn.

Om du har ett egenutvecklat tema (theme) och vill återställa detta från din backup så bör du gå igenom samtliga .PHP-filer för att säkerställa att ingen bakdörr har tagit sig in.

Det finns även exempel då bloggar hackats genom delade miljöer på webbhotell, då hjälper det inte så mycket att du gör en nyinstallation om inte webbhotellet vidtar åtgärder. Överväg även möjligheterna att angriparen tagit sig in med ditt FTP-konto eller dylikt genom att testa vanliga lösenord eller läckta lösenord från exempelvis BloggToppen.

För att säkerställa att det just inte var TimThumb som används för intrång mot din blogg så kan du installera ett plugin som söker igenom efter den kod som TimTumb använder sig av. Här kan du ladda hem TimThumb vulnerability scanner:

Vidare läsning

Du bör även läsa WordPress FAQ gällande hackade WordPress-bloggar.

Detta blogginlägg kommer att uppdateras löpande med nya tips. Om du är intresserad av WordPress och säkerhet så bör du även läsa mitt inlägg om hur säkert WordPress är.

Nikke Lindqvist skrev även om hur viagra-spammare tar sig in i bloggar mer och mer här.

Så programmerar du för molnet

Bild CC http://www.flickr.com/photos/torley/2311784203/in/photostream/Kanske en klyschig rubrik men det finns många saker man bör tänka på när din avsikt är att placera din kodbas i molnet. Och när jag skriver molnet så menar jag exempelvis Amazon EC2 där du hyr en virtuell server. Dessa åsikter är helt subjektiva och kan variera beroende programmeringsspråk eller molntyp.

Grundfilosofin bör dock alltid vara att skriva portabel kod utan statisk information såsom sökvägar eller annat som kan komma att ändra sig om du ökar eller minskar din kapacitet eller flyttar koden. Det är dock inte alltid helt lätt att skriva flexibel och portabel kod då du alltid någonstans måste inneha ett beroende mot den nuvarande plattformen.

  1. Undvik statiska sökvägar eller URL:er
  2. Dokumentera beroenden såsom Redis, MySQL och eventuella PHP-moduler som används
  3. Undvik versionsspecifika funktioner
  4. Inte direkt specifikt för molntjänster men glöm för all del inte att ta backup (och använd GitHub).
Och glöm framför allt inte säkerheten, som ska vara minst lika viktig i molnet som på din egen server eller VPS. Tyvärr blev detta inlägg inte riktigt så långt och innehållsrikt som jag hade tänkt mig, detta pg.a. att programmering för molnet inte skiljer sig allt för mycket mot ”vanlig” programmering.

Bättre prestanda med Unix domain sockets

Ett sätt att öka prestandan när det gäller kommunikation internt inom ditt eget system är att använda Unix domain sockets. Istället för att använda TCP för att kommunicera internt mellan processer på ditt system så bör du med fördel använda Unix-sockets då detta påverkar prestandan positivt.

Några exempel på där du kan använda Unix-sockets är i Redis samt om du använder Nginx och PHP-FPM. För att använda Unix-sockets i Redis behöver du enbart lägga till följande rad i redis.conf:

unixsocket /tmp/redis.sock

Och för att använda denna socket när du ansluter kan variera lite beroende på vilken klient du använder, men på följande sätt gör jag:

$redis->connect(‘/tmp/redis.sock’);

Glöm inte att rättigheterna på /tmp/redis.sock måste vara så att både Redis samt klienten kan läsa. Nu över till hur man konfigurerar Nginx och PHP-FPM att använda sockets.

Första steget är att konfigurera FPM att lyssna på en socket, och detta görs i konfigurationsfilen. Min återfinnes här:

/etc/php5/fpm/pool.d/www.conf

Och i denna fil ändrar jag där raden listen återfinnes så det ser ut något i stil med:

listen = /var/run/php5-fpm.sock

Och nästa steg är att ändra så att Nginx vet att vi har en Unix-socket för PHP-exekvering och det kan göras genom att lägga till eller ändra din ”upstream” om du använder en sådan:

upstream php {
        server unix:/var/run/php5-fpm.sock;
}

Och sedan använda fastcgi_pass php på följande sätt till varje server:

     location ~ \.php$ {
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include /etc/nginx/fastcgi_params;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
        }

Vill du fördjupa dig ännu mer gällande Unix sockets kan du läsa här. MySQL och PHP skall enligt manualsidan automatiskt välja Unix sockets om det finns tillgängligt vilket det bör göra standardmässigt.

Så tar du emot och hanterar E-post i PHP

Bild CC flickr.com/photos/9009139@N08/2959912279När jag byggde Bloggy för några år sedan så byggde jag även in en funktion för att ta emot bilder och text från E-post samt MMS-meddelanden till PHP.

Det som sedan händer är att PHP-koden parsar meddelandet och hämtar ut olika delar såsom rubrik (subject), meddelande och eventuella bilder som är bifogade.

Men först lite beroenden, denna guide fungerar enbart om du har en VPS eller egen server med Sendmail, PHP och pear-paketet Mail_mimeDecode. Pear-paketet kan installeras på följande sätt:

# pear install Mail_mimeDecode

Först måste vi konfigurera Sendmail att ta emot brev för vissa adresser. Detta förfarande har jag automatiserat genom att generera en virtusertable-fil i /etc/mail-katalogen. Du kan behöva uppdatera din sendmail.mc med nedan och generera en ny sendmail.cf:

FEATURE(`virtusertable’,`hash -o /etc/mail/virtusertable’)dnl

Alternativt så kan du direkt via /etc/aliases sätta upp följande snutt som gör så att inkommande E-post hamnar hos PHP:

mms:  ”| /usr/bin/php /var/www/bloggy.se/docs/newmail.php”

Det som händer då är att allt som går till [email protected] alternativt det som routas via virtusertable till [email protected] på följande sätt:

[email protected] [email protected]

Hamnar i PHP hos newmail.php och kommer in som stdin. Obs, om du ändrar i aliases, virtusertable eller .mc-filen så måste du generera nya filer (med kommandot newaliases eller makemap hash exempelvis). Följande kod använder jag sedan för att parsa mailet:

  define("DOMAIN", "bloggy.se");

  include_once('Mail/mimeDecode.php');

  $input = file_get_contents("php://stdin");
  $from = "unknown";

  @file_put_contents("/tmp/maillog.txt", $input."\n--- new mail --\n", FILE_APPEND);

  $params['include_bodies'] = true;
  $params['decode_bodies'] = true;
  $params['decode_headers'] = true;
  $params['input'] = $input;

  $structure = Mail_mimeDecode::decode($params);

  $to = $structure->headers['to'];
  $from = $structure->headers['from'];

  #mailme('<pre>'.print_r($header, true).'</pre>'); // For debugging
  $header = imap_rfc822_parse_headers($input);

  foreach($header as $foo => $bar) {
    if($foo == 'to' || $foo == 'cc') {
        foreach($bar as $k) {
            if($k->host == DOMAIN) {
                $dste = $k->mailbox;
            }
        }
    }
  }

  foreach ($structure->parts as $part) {
    // Save text
    if (isset($part->ctype_primary) && $part->ctype_primary == "text") {
        if(strlen($part->body) > 2 && !preg_match("/iPhone$/", $part->body))
            $text = $part->body;
    }
  }
  if(!$text)
    $text = $header->headers['subject'];

  if(!$text)
    $text = $structure->headers['subject'];

Och slutligen så hamnar antingen innehållet i mailet eller rubriken i $text om vi har tur.

Så analyserar och använder du iPhone Appars API

Visste du att majoriteten av alla iPhone och iPad-appar använder någon form av API?

Jag tänkte gå igenom hur du själv kan använda dessa API:er i dina egna implementationer med hjälp av exempelvis PHP eller Python. Observera att informationen som du hämtar via API:er eventuellt inte användas till vad som helst då den kan omfattas av upphovsrätt eller andra lagar.

Först och främst så måste vi ladda hem någon form av Proxy-programmvara som medger analys av den API-trafik som går fram och tillbaka från iPhonen och Appen. Jag rekommenderar Charles Proxy som är gratis att använda men det finns även en betalversion för ynka 50$ som jag har köpt (du slipper ”nag-screens” och sådant). Charles Proxy fungerar för Linux, Mac och Windows.

Här är en skärmdump på hur det ser ut när du startat upp Charles Proxy:

Så, det första vi ska göra är att stänga av så att vi ej ser all webbsurf till och från vår egna dator och det kan man göra under Proyx-fliken och sedan se till att ”Windows Proxy” ej är förkryssad.

Nästa steg är att vi ska skicka ett E-brev med Charles SSL-certifikat till vår iPhone för att ges möjlighet att analysera krypterad HTTPS-trafik till och från telefonen. Ladda hem följande ZIP-fil: charlesproxy.com/ssl.zip och packa upp den där du sedan hittar en .CRT fil som du bifogar i ett mail som du sedan kan öppna på din iPhone (Dropbox eller annan typ av filöverföring går säkert också bra).

När du lagt in Charles certifikat i din telefon bör det se ut så här under Inställningar -> Allmän -> Profil (längst ner):

Då var det nästa steg, och det är att ta reda på IP-adressen till din dator. Jag brukar använda cmd.exe och sedan skriva ipconfig så bör det se ut något i stil med:

Denna IP-adress skall vi ange under inställningarna som det nätverk vår iPhone är ansluten till. I mitt fall så är det via WiFi och längst ner under inställningarna för det trådlösa nätverket anger jag IP-adressen till min dator som kör Charles Proxy så det ser ut så här:

Sedan är det bara att starta den App som vi vill analysera på iPhonen, i mitt fall så startar jag Swedavias App vid namn Arlanda flygplats. Och se hur Charles Proxy visar API-anropen efter varandra. Eftersom vi är intresserad av Avångar så klickar jag helt enkelt på Avångar i Arlanda Appen och får upp följande intressanta API-anrop i Charles:

Fleratalet parametrar är intressanta att anteckna eftersom de behövs vid anrop från PHP eller Python. Det varierar från app till app men i detta fall är det URL:en för anrop som innehåller flygplats (airport=arn_utr) samt datum (searchDate=2011-08-10).

Tittar vi på XML-svaret så ser det ut enligt följande:

När vi sedan implementerat en funktion som härmar denna förfrågan så bör vi få ut samma XML-svar i slutändan och kan då exempelvis hämta hem avgångar med PHP och CURL på följande sätt:

<?php
  $today = date("Y-m-d");
  $path = '/ArrivalsDeparturesMobile/ArrDepMobileService/ArrDep.asmx/GetDeparturesFlightTable?airport=arn_utr&language=sv&searchString=&searchDate='.$today;
  $host = "wsc1.swedavia.se";

  $headers = array(
    "GET $path HTTP/1.1",
    "Host: $host",
    "User-Agent: Arlanda/1.4 CFNetwork/485.13.9 Darwin/11.0.0",
    "Authorization: Basic V1NBcnJEZXBNb2JpbGU6c1AtR0U1NWJlY3I4c1BhKWhlMHBlNXJ1NkVmYUNyRSE=",
    "Accept: */*",
    "Accept-Language: sv-se",
    "Accept-Encoding: gzip, deflate",
    "Pragma: no-cache",
    "Connection: keep-alive"
  );

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "http://".$host.$path);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

  $sXML = curl_exec($ch);

  $oXML = new SimpleXMLElement($sXML);

  print_r($oXML);

?>

Ovan kod kan du sedan köra från kommandotolken enligt följande:

$ php swedavia.php

Tadaa! Nu slipper vi använda vår iPhone varje gång vi ska se avgångar från Arlanda. I detta exempel så behövdes ej SSL-certifikatet användas då anropen skickas i klartext.

Serverstrul

Denna vecka så har mer eller mindre alla mina servrar strulat. Jag fick för mig att uppgradera Redis till en lite nyare version som har buggfixar samt äter mindre CPU och passade samtidigt på att uppgardera det PHP bibliotek jag använder för att prata med Redis till owlient/phpredis. Så klart så gick något fel och cachningen i Redis ballade ut och servern dog sakta men säkert pga alla SQL-frågor som ej cachades.

Nästa problem dyker upp på Bloggy då flertalet InnoDB-databasfiler försvinner vid en hastig omstart av servern och MySQL vägrar starta så jag får manuellt använda strace till att lista ut vilken databas som strular och bygga om flertalet tabeller. Då passar jag även på att uppgradera Varnish till senaste versionen och lägger in lite kod för att ej cacha WordPress-adminsidor vilket får till följd att inloggningen på Bloggy misslyckas för alla användare.

Samt så har även den server som sköter bloggsökmotorn Bloggz strulat.. vilket lärdom kan man dra av detta då? Jo, att om du uppgraderar eller ändrar minsta lilla så testa att det verkligen fungerar, lägg till exemeplevis dold HTML-kod som berättar om sidans element verkligen cachas eller ej.

Bildkälla: http://retecool.com/post/computable-awards--fail/1/

Sökmotoroptimera Googles förhandsvisning

För några dagar sedan så gjorde jag ett litet sökmotorexperiment: Jag ser sedan några veckor tillbaka en förhandsvisning på webbsidor i Googles sökresultat. Jag lyckades lista ut den unika sträng som Googles robot använder vid skapande av förhandsvisningsbilden och på så sätt så ändrar jag bakgrundsfärgen till röd då just bilden skapas. En ny typ av område inom sökmotoroptimering kanske?

Lägg bara till följande PHP-kodsnutt där din <head>-kod finnes:

<?php
if(FALSE != strstr($_SERVER['HTTP_USER_AGENT'], "525.13")) // Find Google preview unique string

print '<style type="text/css">body { background-color: #f00 !important; }</style>';
?>

Och så här ser User-agent strängen ut i sin helhet:

Mozilla/5.0 (en-us) AppleWebKit/525.13 (KHTML, like Gecko; Google Wireless Transcoder) Version/3.1 Safari/525.13,Mozilla/5.0 (en-us) AppleWebKit/525.13 (KHTML, like Gecko; Google Wireless Transcoder) Version/3.1 Safari/525.13

Före:

Efter:

Sen är ju frågan om det verkligen kan innebära mer klick på en länk bara för att förhandsvisningen av sidan är röd, kanske bättre att skriva ut ”Klicka!” med stor text ;)

Så kommer du igång med Nginx + PHP-FPM

Nginx är en supersnabb webbserver/proxy skriven av ryssen Igor Sysoev och används av exempelvis WordPress.com och Loopias höghastighetstjänst Autobahn. I dagsläget så använder ca 8% av världens webbservar just Nginx som webbserver eller front-end proxy.

Nginx är även mitt självklara val vid installation av nya servrar, men dock är installationen inte helt enkel eftersom det inte finns inbyggt PHP-stöd vilket är det primära programmeringsspråk jag använder vid webbutveckling. Nginx är således beroende av exempelvis PHP-FPM (FastCGI Process Manager for PHP).

Installation

Först och främst så ska vi lägga till dotdeb i vår sources.list genom följande kommando:

$ sudo sh -c ‘echo ”deb http://php53.dotdeb.org stable all” >> /etc/apt/sources.list’

Lägg sedan till rätt nycklar:

$ gpg –keyserver keys.gnupg.net –recv-key 89DF5277

$ gpg -a –export 89DF5277 | sudo apt-key add –

Nu kan vi synkronisera paketlistorna:

$ sudo apt-get update

Sen måste vi lägga till några paketberoenden:

$ wget http://us.archive.ubuntu.com/ubuntu/pool/main/k/krb5/libkrb53_1.6.dfsg.4~beta1-5ubuntu2_i386.deb

$ wget http://us.archive.ubuntu.com/ubuntu/pool/main/i/icu/libicu38_3.8-6ubuntu0.2_i386.deb

$ sudo dpkg -i *.deb

Och sist men inte minst så installerar vi paketen via apt:

$ sudo apt-get install php5-fpm php5-cgi nginx

Sen måste nginx konfigureras och lättast är att utgå från den standard-konfiguration som medföljer och återfinns i filen /etc/nginx/sites-available/default. Om du vill se hur min konfigg-fil ser ut kan du utgå från denna.

Starta sedan om php-fpm samt nginx om de inte redan startas:

$ sudo sh /etc/init.d/nginx restart

$ sudo sh /etc/init.d/php5-fpm restart

Om php5-fpm klagar om pm.min_spare_servers eller liknande så måste du eventuellt ta bort en kommentering i filen /etc/php5/fpm/php5-fpm.conf

Thats’s it! Återkommer om jag hittar något lättare sätt att komma igång med nginx och php-fpm.

GovData nu med JSON API

Uppdatering: GovData stödjer nu ännu fler argument. Det är nu även möjligt att se alla myndighetskunder för ett specifikt organisationsnummer.

Äntligen så finns det ett första utkast till ett API för GovData. Jag har valt att stödja JSON med tillhörande JSONP vilket fungerar med de flesta programmeringsspråk.

Ett exempel hur information gällande Skatteverkets utgifter för 2003 hämtas ut med hjälp av PHP:

<code><?php

$data =  file_get_contents("http://govdata.se/api/toplist/2003/skatteverket");
$datar = json_decode($data);
print_r($datar);

 ?></code>

Alla myndigheter som stödjs med hjälp av toplist-argumentet går att lista med följande URL:

http://govdata.se/api/lista

All information som finns på GovData kommer att vara tillgängligt via API:et. Du får använda informationen som du vill, dock så uppskattas  alltid en länk tillbaka.

Mer information finns på API-sidan för GovData: govdata.se/api

AlchemyAPI – Analys av textmassor

I vissa av mina projekt så är jag i behov av att automatiskt tagga upp text. Och efter att ha testat ett antal olika API:er som tillhandahåller detta så tänkte jag dela med mig av mina erfarenheter i form av en serie blogginlägg.

Först ut att testas är AlchemyAPI som verkar vara det mest avancerade när jag tittar på deras hemsida ”AlchemyAPI utilizes machine learning and natural language parsing technology, analyzing web or text-based content to identify people, organizations, locations, and other information!”.

Nåväl, först och främst så tar jag en exempeltext som jag avser att jämföra mellan de tre API:erna (hämtad från PRNewsWire.com).

Efter att införskaffat en API-nyckel från AlchemyAPI så skriver jag om den exempelkod som hittas i examples/keywords.php till att se ut enligt nedan. Exempelkoden kan hittas i deras SDK.

<?php

 // Load the AlchemyAPI module code.
 include "../module/AlchemyAPI_CURL.php";

 // Create an AlchemyAPI object.
 $alchemyObj = new AlchemyAPI();

 // Load the API key from disk.
 $alchemyObj->loadAPIKey("api_key.txt");

 $xml = $alchemyObj->TextGetRankedKeywords(file_get_contents("/home/je/exempeltext.txt"));
 $result = simplexml_load_string($xml);

 foreach($result->keywords->keyword as $key) {
     echo $key->text.", ";
 }

 echo "\n";
?>

Nyckelorden som kommer fram ur texten är följande:

FIPS 140-2, fips 140-2 validation, secure mobile voice, voice calling security, Federal Information Processing Standard, Secure Voice, Cellcrypt products, Cellcrypt’s cell phone, certificate provides assurance, PALO ALTO, mobile phone, cryptographic module, highest standard, gateway applications

Här hämtar du hem PHP SDK:

Testa även deras demo-sida som visar lite mer vad de är kapabla till. Samt så tillhandahåller de även ett WordPress-plugin.