Alle indlæg af Michael Fosgerau

Er du opdateret?

Et utal af hjemmesider kommer til på Internettet hver eneste dag. De fleste er små private blogs og mini-sider som kun har en stærkt begrænset bruger/læser skare. Men der findes også den del af nettet som bliver godt besøgt. Uagtet om man driver en hjemmeside med få besøgende pr. år eller flere tusinde pr. time er det vigtigt at have for øje at man dermed også bør tænke over hvad det er disse besøgende får serveret.

Har man ikke beskyttet sin server, hjemmeside, blog eller content-management system grundigt nok kan det gå galt.

Hvor galt det kan det da gå?

AdvarselAdvarsel: Links til eksterne sider fra dette punkt i artiklen kan lede til virusinficerede sider.

Et godt eksempel på dette er komikeren Omar Marzouk, der fornyligt har stiftet et parti kaldet Ny Filionggonggong som det kan læses på Politiken’s blog idag. Hjemmesiden er drevet af det vidt udbredte blogsystem WordPress. Desværre er der ikke tale om en opdateret udgave af WordPress, i skrivende stund er der anvendt version 2.3.2, hvilket har en række ærgelige konsekvenser. Dels er Omar Marzouk’s hjemmeside en fin og sikkert eftertragtet angrebsvektor for personer med urent mel i posen, da der er tale om en højt eksponeret hjemmeside der utvivlsomt har potentiale for at trække nogle tusinde besøg pr. dag. Problemet er at WordPress version 2.3.2 er sårbar overfor en række kendte angreb (hvilket v2.3.3 retter op på), der gør en kyndig angriber istand til helt at overtage hjemmesiden. Vedkommende vil kunne rette/slette indlæg efter eget forgodtbefindende.

Udover at være drevet af en ældre version af WordPress er der tilsyneladende også mangel på moderering af kommentarer på hjemmesiden. Dette har også en ubehagelig sideeffekt. I skrivende stund linkes der fra forsiden til ikke mindre end 5 forskellige virus inficerede eksterne hjemmesider fra boksen “Nyeste kommentarer”.

Min virus scanner rapporterede dette da jeg fulgte første kommentarlink:

Virus or unwanted program ‘HTML/Crypted.Gen [HTML/Crypted.Gen]’ detected in file ‘C:\Documents and Settings\Michael Schøler\Lokale indstillinger\Temporary Internet Files\Content.IE5\WVEVC6CT\songmlin9_forumup_ro[1].htm. Action performed: Deny access

Lektien ved dette

Der følger et “ansvar” med at drive en hjemmeside der tiltrækker mange besøgende kan man godt påstå. Ikke ment på den vis at der ville kunne gennemføres et juridisk gyldigt søgsmål mod det nye “partis” hjemmeside, men nærmere et professionelt stolthedsansvar. Man bør gøre sit ypperste for sikre ens server og ens besøgende ikke mindst.

Det er nemt at undgå

Det er relativt nemt i videst mulige udstrækning at sikre sig mod uforvarende at lede ens besøgende ind på inficerede sider og at have sikkerhedshuller i ens server/software, ved at følge disse simple grundregler:

  • Hold server og software opdateret
  • Anvend en virusscanner
  • Moderer alle kommentarer og/eller beskyt gerne mod anonyme kommentarer
  • Brug gerne anti-spam og captcha plugins på blog og CMS systemer
  • Gennemgå ofte hjemmesiden i sikkerhedsøjemed
  • Følg med på supportsiderne for de software-produkter der anvendes og tilmeld alle eventuelle sikkerhedsmailinglister

Bug i JavaScript eller er weekenden bare for nær?

Jeg er stødt på noget rimelig besynderligt i dag – JavaScript fortolkeren i IE6, IE7 og FF2 opfører sig nemlig tilsyneladende sært når man opretter selvrefererende JavaScript Object Notation (JSON) objekter.

JSON screenshot fra Firebug

Betragt den første variabeltilskrivning jeg udfører i Firebug konsollen i Firefox:

>>> var json = { "foo": 42 };

Den evaluerer til et objekt der indeholder:

>>> json
Object foo=42

Hvis vi gerne vil have oprettet et JSON objekt der refererer til sig selv, kan man angive f.eks.:

>>> var json = { "foo": 42, "selfRef": json.foo };

Hvilket evaluerer til et objekt der indeholder:

>>> json
Object selfRef=42 foo=42

Omskriver man det en smule, så property’en foo tilgås på array form bliver værditilskrivningen til:

>>> var json = { "foo": 42, "selfRef": json["foo"] };

Og det går det lige så fint med, da det også evaluerer til:

>>> json
Object selfRef=42 foo=42

Filmen lader dog til at knække helt hvis den nøgle man anvender er et tal, hvilket er fint gyldigt iøvrigt:

>>> var json = { "2": 42, "selfRef": json["2"] };

Nu har vi nemlig kun objektet:

>>> json
Object 2=42

Så jeg tænkte at jeg enten havde fundet en generel implementationsfejl i JavaScript fortolkerne i IE og FF (hvilket må siges at være overvejende usandsynligt), eller også er mine forsøg herover fejlbehæftede. Sidste mulighed viste sig at være årsagen.

Det går nemlig fint at erklære cykliske JSON strukturer hvis de basis data der skal indgå i selvreferencerne allerede er erklærede på forhånd. Og det er de netop hvis man afprøver dette forløb:

>>> var json = { "foo": 42 };
>>> var json = { "foo": 42, "selfRef": json.foo };
>>> json
Object selfRef=42 foo=42

Hvis json.foo ikke indledningsvist havde været erklæret fejler den selvreferende erklæring:

>>> var json = { "foo": 42 };
>>> var json = "";
>>> var json = { "foo": 42, "selfRef": json.foo };
>>> json
Object foo=42

Så det var udelukkende på grund af weekenden der var lige om hjørnet, og fordi forsøget på at indsætte en hidtil utilskrevet talnøgle i JSON strukturen gjorde at “fejlen” fremstod. Man kan dog fortsat være lidt tvivlende overfor hvordan en tilskreven property bare kan forsvinde ud i den blå luft. Man kunne forvente at selfRef som minimum var tilstede og blot indeholdt værdien "undefined" eller endnu bedre null. Alternativt havde en kastet exception også været ok.

XSLT konvertering til store/små bogstaver

Den almene metode til at konvertere strenge til f.eks. små bogstaver (minuskler) for at udføre en sammenligning, eller blot for at præsentere det transformerede resultat på den vis, er at benytte sig af XPath funktionen translate. Flere steder finder man netop denne løsning implementeret og den fremføres ofte som en god måde at konvertere strenge til f.eks. minuskler, blandt andet i XSLT 2nd Edition Programmer’s Reference af Michael Kay, der må siges at være “biblen” indenfor XSLT-området.

En XSLT transformationsfil der skal kunne foretage konvertering af danske strenge vil typisk indeholde:

<!-- translate strenge -->
<xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyzæøå</xsl:variable>
<xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ</xsl:variable>
...
<!-- til versaler -->
<xsl:value-of select="translate($toconvert,$lcletters,$ucletters)"/>
...
<!-- til minuskler -->
<xsl:value-of select="translate($toconvert,$ucletters,$lcletters)"/>

Problemet med translate-løsningen er, at den ikke tager højde for andre tegn end dem man eksplicit angiver – og det kan være en stor opgave hvis tegnsættet der anvendes er UTF-8 eller blot ISO-Latin-1. Der er henholdsvist flere tusinde / hundrede tegn i disse tegnsæt. Tegn der ikke er angivet slipper uændrede igennem transformationen med translate.

Med nedenstående XML-datafil i hånden vil førnævnte translate-strenge fejle, da “umlaut”-tegnene ikke er dækkede.

<?xml version="1.0" encoding="UTF-8"?>
<items>
  <item>
    <title>Dette er danske tegn æøåÆØÅ</title>
  </item>
  <item>
    <title>Dette er andre tegn üöäÜÖÄ</title>
  </item>
</items>

En anden metode jeg derfor har nørklet med i dag, der dog kun fungerer i Internet Explorer, er at indlejre et JavaScript i XSLT transformationsfilen, og herfra udnytte JavaScript’s toLowerCase() funktion. Firefox har endnu ikke understøttelse for XSLT 1.1 <xsl:script>, hvorimod Internet Explorer tilbyder en Microsoft-proprietær implementation der fungerer ganske udemærket, nemlig <msxsl:script>.

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:tns="urn:thisnamespace:tns"
exclude-result-prefixes="tns msxsl">
<msxsl:script language="JavaScript" implements-prefix="tns">
function lCase(item) {
  return (''+item).toLowerCase(); 
}
</msxsl:script>
<xsl:template match="/">
  <xsl:for-each select="items/item">
    <xsl:variable name="aparam" select="title"/>
    <xsl:value-of select="tns:lCase(string($aparam))"/><br />
  </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Du kan ved brug af, Internet Explorer (version 6 eller nyere), se resultatet af at udføre XSL + JavaScript transformationen her. Det forventede resultat er at samtlige tegn i XML-datafilen er konverteret til minuskler.

Jeg leder fortsat efter en elegant cross-browser løsning, men for nuværende er ovenstående dækkende pga. krav til opgaven specifikt kun er rettet imod slutbrugere der anvender Internet Explorer.