Convert the character set of a mysql database

This php-script is for converting content of all tables of a mysql database to another character set. In this case i convert everything (latin 8859-1) to utf8_swedish_ci. The same action can be made from the shell with mysqldump and iconv, but the programmer in me prefers the-php-way. As always, tweaks and comments are very helpful.

<?

set_time_limit(0);

$link = mysql_connect(’localhost’, ’mysql_user’, ’mysql_password’);

mysql_select_db(’db’);

$sql = "SHOW TABLES FROM db";
$result = mysql_query($sql);

while($row = mysql_fetch_array($result))
{
$sql = "ALTER TABLE ".$row[0]." CONVERT TO CHARACTER SET utf8 COLLATE utf8_swedish_ci";
mysql_query($sql);
echo ’Converting table: ’.$row[0].'<br>’;
}

?>

Slug-funktion för svenska tecken

En slug är några ord som beskriver en webbsida. Slug är vanligtvis en URL-vänlig version av sidans titel, alltså något som sökmotorer gillar bättre än en ”konstig” URL som http://www.minsida.se/sida.php?id=45. Exempelvis, om sidans titel är ”Timrå IK är dom bästa!!” så skulle en slug-URL till detta kunna vara http://www.minsida.se/timra-ik-ar-dom-basta

De slug-funktioner i php som jag hittat på nätet har inte haft något stöd för svenska tecken (åäö) så jag var tvungen att skriva en egen sådan function. Om någon kan förbättra den så skicka in er förbättrade version. Hur som haver här är den:

function slug($string)
{
$unPretty = array(’/å/’,’/ä/’,’/ö/’,’/ü/’, ’/Å/’, ’/Ä/’, ’/Ö/’, ’/Ü/’,’/é/’);
$pretty = array(’a’,’a’, ’o’, ’u’, ’A’, ’A’, ’O’, ’U’,’e’);
$string = preg_replace($unPretty, $pretty, $string); // convert swedish characters
$string = preg_replace( ’/[^a-zA-Z0-9- ]/’, ”,$string); // replace non-characters
$string = str_replace(” ”, ”-”, $string); // replace spaces by dashes
$string = strtolower($string); // Make it lowercase
return $string;
}

Monitoring Qmail in Freebsd

I needed a way to monitor qmail on my Freebsd server. In particular I wanted to shut down qmail if ”too many mails” were sent in a specified timeframe. I previously had a problem when one of my websites began to act as a spam proxy due to a ”bug” in php mail function that enables mail injection. I could not google a solution and had to write my own script.

The approach is fairly simple. The qmail-send log folder ( /var/log/qmail/qmail-send/) contains information about all recently sent emails. My script checks one of these log-files too see if it contains the current date. If it does, then Qmail has sent ”too many” emails and qmail should be shut down. Depending on which log file that is checked and how many records you have in each log file you could determine how many emails that are ”too many” for your qmail server. It is simply a matter of tuning the script by changing ”head -n NUMBER”.

Which action to take when qmail runs wild is up to you. On my server I notify myself by sending a sms to my phone and a simple mail. The script is as follows:

#!/usr/local/bin/bash
PATH=$PATH:/usr/local/bin

DATE=”`date +%Y-%m-%d`”
LOGFILE=”`ls -lt /var/log/qmail/qmail-send/@* | awk {’print $9’} | head -n 1`”
MAILDATE=”`cat  $LOGFILE | tai64nlocal | head -c 10`”
QMAILUP=”`svstat /var/qmail/supervise/qmail-send/ | awk {’print $2’}`”

if [ $QMAILUP == ”down” ]
then
  echo No need for checking – Qmail is not running
  exit
fi

echo This date: $DATE
echo Log date: $MAILDATE
if [ $DATE == $MAILDATE ]
then
  echo Equal dates – Mailing qmail-administrator
  /var/qmail/bin/qmail-inject -h < /scripts/smsqmail
  echo ”Qmail is stopped” | mailx -s ”Qmail alert” marcus@blahblah.com
  echo Shutting down qmail in 20 seconds
  sleep 20
  qmailctl stop
else
  echo Different dates – Everything seems to be okey
fi

Display ASP.NET 1.x system information

It is always good to know and master the environment you work in.  Usually you need to keep track of the current ”request headers”, ”environment variables”, ”server variables” and ”session variables. In php you could use the phpinfo()  function to check your installation. However, I do not know about any equivalent in .NET.

On this page you can find an application that give you some of these variables. But I wanted a C# version which displays some more information as well. Therefore I made my own small version. Unfortunately I have no online .NET server and can’t provide a demo (help someone?) 

You can download the application source code here: aspnetinfo.zip

Feel free to customize the application for your need. If you make a superior version, then put it on the web and tell me about it.

Förhindra php mail injection

PHP’s mail-funktion (mail) ska man använda med viss försiktighet eftersom spambot’ar relativt enkelt kan utnyttja en inbyggd svaghet/feature/”kalla-det-vad-du-vill”. Det farliga är att många som utvecklar i php inte vet vad som kan hända med svaga osäkrade webbside-formulär som använder denna funktionalitet. Om en spambot hittar och utnyttjar ”svagheten” på dina webbsidor så kan du på ett ögonblick bli en storspammare och får då stå för konsekvenserna då du förr eller senare blir uppsökt av din internetleverantör eller webbhotell.

Vanligtvis har man ”kontakta oss” eller andra sidor där användare får skriva in sitt namn, e-postadress, ämne samt meddelande. Då man sedan skriver koden som ska maila till den som ska ha informationen så kontrollerar man vanligtvis  att e-postadressen är riktig samt att några av fälten inte är tomma. Eventuellt filtrerar man även meddelandet och tar bort html, konstiga tecken eller liknande. Då man processat variablerna så skickar man in dessa i mail-funktionen som skickar ut mail till den/de som ska få det.

Mail-funktionen anropas enligt följande:

bool mail ( string $to, string $subject, string $message [, string $additional_headers [, string $additional_parameters]] )

Exempel på användning:

$to = ”kontakt@person.se”
$subject = $[Ämne från webbformuläret];
$message = $[Meddelande från webbformuläret];
$additional_headers = ”From:”.$[sändaradress från webbformuläret];
mail($to,$subject,$message,$additional_headers);

Eftersom man hårdkodar mottagaradressen så kan man tro att det enbart är den personen som kommer att få mailet. Men så är INTE fallet utan mejlet kan skickas till ett mycket stort antal personer utan din vetskap (om du nu inte läst detta innan) med så kallad mail injection. Detta nämner inte php-manualen utan kodaren måste själv veta hur mail skickas och hur mail är formaterade. Med tanke på att nivån på php-programmerare varierar kraftigt så är det viktigt att man har koll på något sånt här.

Hur fungerar då detta?
Spambot’arna injicerar ytterligare mottagare i parametern för additional_header som kommer från formulärets sändaradress-input ruta. Genom att lägga till fler mottagare genom CC samt BCC i oskyddade formulär så agerar ditt webbformulär som en spam-proxy.

Exempel på mail injection av sändaradress:

sender@anonymous.www%0ACc:recipient@someothersite.xxx %0ABcc:somebloke@grrrr.xxx,someotherbloke@oooops.xxx

Lösning
Använd rigorösa kontroller även på simpla formulär. Kontrollera att det inte går att injicera mail headers. Använd exempelvis en mail-class som har skydd mot denna typ av problem eller något reguljärt uttryck.

Länkar
mailinjection.com – Mailinjection – Mer om problemet
SecurePhp – Email injection – Beskrivning av problemet och lösningar
Hardened PHP – Suhosin patch – Patch som bl.a används av freebsd ports

Enkelt sätt att undvika spam från webbformulär

Jag har på ett flertal sajter haft problem med att spam-robotar letar upp ”oskyddade” formulär och fyller i dessa med en massa junk som sedan submittas. En lösning på problemet skulle vara att använda någon slags Captcha som är ett slags turing-test som avgör om användaren är människa eller spam-bot. Men detta känns som lite väl mycket overkill för mina sajter.

En lösning som jag använt mig av är att användaren får en input box där de måste fylla i årets år, ex: 2007, för att få gå vidare. Den lösningen har fungerat bra och innebär inte särskilt mycket kod för mig som utvecklare. Men det innebär ett extra steg för användaren som kan upplevas som jobbig eller onödig. Så jag undersökte om det finns ett alternativ som innebär lite kod samt att användaren slipper mata in ytterligare uppgifter.

Den enkla lösningen är att lägga in en extra textarea-kontroll i formuläret som inte visas för användaren genom CSS. Självklart så kan inte spam-roboten hålla sig ifrån att fylla även denna med junk eftersom dom vanligtvis inte förstår sig på CSS. När formuläret sedan valideras på server-sidan så kontrollerar man om fältet är ifyllt eller inte. Om det är ifyllt så är det en spam-robot på sidan och annars är det en människa. 

I formuläret:

<textarea name=”to_adress” style=”display: none;”></textarea>

I formulär-kontrollen

if($_REQUEST[”to_adress”] == ””)
{
// Människa
} else if($_REQUEST[”to_adress”] != ””)
{
// Robot
}

Detta är en fast-and-dirty lösning och se det som en sådan. Använd Captcha eller något mer avancerat om du vill ha en mer avancerad kontroll. Men till enkla low-profile formulär så funkar detta alldeles ypperligt.

Samma lösning i .NET bör fungera enligt följande:

I formuläret:

<textarea runat=”server” id=”to_adress” name=”to_adress” style=”display: none;”></textarea>

eller

<style type=”text/css”>    .gommig {display: none;}</style>
<textbox Runat=”server” CssClass=”gommig” TextMode=”MultiLine” id=”to_adress2″></textbox>

I formulär-kontrollen;

   // Alt textarea
   if( to_adress.Value == ”” )
   {
    // Människa
   }
   else
   {
    // Robot
   }

 // Alt textbox
   if( to_adress2.Text == ”” )
   {
    // Människa
   }
   else
   {
    // Robot
   }