Categories
Uncategorized

1Password

Det er egentlig ikke fordi jeg vil bruge pladsen her på at reklamere for produkter. Jeg har dog besluttet mig for at gøre en undtagelse, fordi jeg har fundet et produkt, som positivt forandrer, hvordan jeg anvender Internettet til daglig.

1Password er sådan et produkt.

Jeg har dog besluttet mig for at gøre en undtagelse, fordi jeg har fundet et produkt, som positivt forandrer, hvordan jeg anvender Internettet til daglig.

Jeg har nu anvendt 1Password dagligt i over et år, og det er først for nylig, at jeg har indset, præcis hvor dybt integreret i min hverdag produktet er blevet.

Jeg har installeret 1Password på alle mine computere, min smartphone, og i alle mine browsere. Alle mine kodeord (som for længst er skiftet til sikre udgaver med hjælp fra 1Passwords kodeordsgenerator) er aldrig mere end et eller to klik væk.

Det kan føles lidt nervepirrende at springe ud i at bruge en kodeordshusker, fordi det betyder, at du reelt kun kender ét eneste af alle dine kodeord, nemlig det til din kodeordshusker. Selv om mange tech-sider udråber kodeordshuskere til Guds gave til Internettet, vil jeg alligevel råde dig til at læse Stuart Schechters artikel om kodeordshuskere, inden du selv kaster dig hovedkulds ud i at installere en sådan.

Categories
Uncategorized

A New Home

The posts on this blog have a new home here on boolean.dk.

I have no idea if this is a good place to host my blog in the long run, but for now it works just fine.

Categories
Uncategorized

Hej, og velkommen til boolean.dk!

Velkommen til boolean.dk, en spritny WordPress-blog på det store Internet. Her vil der ganske sikkert komme mere indhold hen ad vejen, men i første omgang, skal jeg lige have nogle ting og sager på plads “bag tæppet”…

Hvis du undrer dig over (domæne)navnet, er det fordi danske domæner er en mangelvare efterhånden, på linje med .com-domæner. Min fantasi rakte derfor kun til et meget nørdet og indforstået domænenavn, når det nu heller ikke måtte være taget i forvejen.

Hvis du er nysgerrig, kan du læse mere om, hvad en boolean er for en størrelse her (link til Wikipedia).

Categories
Uncategorized

Google Advanced Protection Program

Efterhånden som vi lægger flere og flere data online, stiger vigtigheden af at holde disse data sikret imod uretmæssig adgang.

Rigtig mange mennesker (mig selv inklusive) har en personlig Google-konto, og anvender denne til at gemme og behandle store mængder personlige data.

For de fleste brugere betyder det, at hvis bare ét enkelt kodeord kompromitteres, bliver der åbnet en ladeport til rigtig mange personlige data.

Heldigvis har Google nogle af verdens førende sikkerhedseksperter ansat, men det hjælper ingenting, hvis brugeren har anvendt et svagt kodeord til sin Google-konto.

Google tilbyder deres sikkerhedsorienterede brugere mange forskellige muligheder for at sikre deres Google-konto, og jeg vil i det følgende skitsere de forskellige muligheder.

Især vil jeg fremhæve en lidet kendt løsning kaldet Google Advanced Protection, som giver den stærkeste beskyttelse af ens Google-konto.

De “nemme” løsninger

Til sikring af ens Google-konto forefindes et antal “lavthængende frugter”—lettilgængelige sikkerhedstiltag—der til sammen giver en rigtig god beskyttelse:

  • Anvend et unikt og langt kodeord, som er unikt for Google-kontoen. En god adgangskodeadministrator kan hjælpe til med at nå dette mål, omend disse programmer indebærer nogen kompleksitet i sig selv.
  • Slå totrinsbekræftelse til.
  • Hold altid softwaren på alle dine enheder opdateret.
  • Fjern adgangen til Google-kontoen for sjældent anvendte apps.
  • Anvend i det hele taget helt almindelig, sund fornuft for at undgå mistænkelige websider, anmodninger og mails.
  • Du kan selv læse flere af Googles egne råd til beskyttelse af din Google-konto på denne side.

Den svære, sikreste løsning

Hvis man anvender alle ovenstående råd, er man nået langt i at beskytte sin Google-konto, og er sikkert mere modstandsdygtig overfor angreb end (langt) de fleste andre brugere.

Hvis man alligevel ønsker gå et skridt videre, selv om det vil ske på bekostning af noget funktionalitet, tilbyder Google alle brugere en ekstra pansring igennem deres Google Advanced Protection Program.

Google Advanced Protection giver først og fremmest tre ting udover den stærke beskyttelse, alle Google-konti i forvejen beskyttes med:

  • Stærkere beskyttelse imod phishing-angreb via fysiske adgangsnøgler.
  • Konto-adgang for tredjepartsprogrammer begrænset til Googles egne apps samt tredjeparter godkendt af Google.
  • Højere krav til identifikation ved forsøg på kontogendannelse.

Lad os kigge nærmere på dem enkeltvis og se, hvordan de hver især øger bolværket, der beskytter en Google-konto.

Adgang via fysiske adgangs-nøgler

Når Google Advanced Protection er slået til, er totrinsbekræftelse obligatorisk, og SMS eller Google Authenticator app’en på din smartphone kan ikke anvendes i tilgift til kodeordet.

I stedet skal du anvende en fysisk sikkerhedsnøgle, som du kan læse om og købe via et link på denne side.

Bemærk! Kravet til en fysisk sikkerhedsnøgle også vil gælde dine mobile enheder som fx tablet og smartphone, hvorfor det er vigtigt, at du sikrer dig, at alle dine mobile enheder har NFC-understøttelse, da de ellers ikke vil kunne kommunikere med sikkerhedsnøglen.

Hvis du har en enhed, der ikke understøtter NFC, men har en USB-port, kan du måske få det til at virke via et USB OTG (“On The Go”)-kabel som dette fra AV-Cables, men det er ikke alle enheder, har understøttelse for OTP OTG.

På stationære enheder sættes sikkerhedsnøglen ganske simpelt ind i en ledig USB-port, og kræver ingen installation af driversoftware for at fungere, så du kan også anvende den på computere, hvor du ikke har administrator-adgang, fx på biblioteket.

Anvendelsen af en sikkerhedsnøgle, der anvender FIDO U2F (“Universal 2nd Factor”) sikrer imod phishing-angreb på to måder:

  1. Udvekslingen af kryptografiske nøgler mellem Google og sikkerhedsnøglen sammenholdt med den underliggende U2F-protokol (som du kan læse mere om her, og selve specifikationen findes her) sikrer, at hvis du prøver at logge ind på et falsk website, som udgiver sig for at være Google, vil det fejle. Under indrulleringen, som gøres én gang per website, hvor du ønsker at anvende din sikkerhedsnøgle, knyttes et unikt, kryptografisk nøglepar sammen mellem Google og sikkerhedsnøglen. (Præcis hvordan dette fungerer er for detaljeret til at komme ind på her, men kunne være interessant at dedikere indholdet af et særskilt indlæg til.)
  2. Fordi sikkerhedsnøglen kræver et fysisk input fra et menneske, kan et ondsindet website ikke automatisk “trække et nummer” fra sikkerhedsnøglen, uden du selv aktivt har godkendt det ved fx at sætte fingeren på sikkerhedsnøglen. Det er selvfølgelig mere besværligt at skulle bære rundt på (og holde styr på) en separat sikkerhedsnøgle frem for at installere en app som Google Authenticator på sin smartphone, som man alligevel altid har med rundt, men det er prisen for den ekstra sikkerhed, man opnår.

Begrænset kontoadgang for tredjepartsprogrammer

Via en Google-konto kan man give adgang til informationer indeholdt i kontoen, men denne adgang udgører en anselig sikkerhedsrisiko, hvorfor denne adgang lukkes ned for alle tredjepartsprogrammer undtagen Googles egne programmer som fx Gmail og Drive, samt visse tredjepartsprogrammer godkendt af Google.

Det betyder også, at man ikke kan sætte et mailprogram som fx Thunderbird eller Microsoft Outlook op til at forbinde til ens Gmail-konto, men udelukkende læse og besvare sin mail gennem Gmails webinterface i en browser. En enkelt undtagelse er i skrivende stund Apple Mail, som er et tredjepartsprogram, der er blevet godkendt af Google.

Jeg vil forvente, at der i fremtiden kommer flere undtagelser, sådan at man vil kunne bruge flere og flere programmer til at forbinde til Gmail, selv om man har Advanced Protection slået til.

Man kan stadig anvende sin Google-konto til at logge ind på andre websites ved at klikke på “Log in with Google”, sådan som mange gør. Dog vil man blive bedt om en ekstra kode, hvis det website, man logger ind på, beder om adgang til Gmail eller Drive.

Højere krav til identifikation ved kontogendannelse

Vi kender det alle sammen: vi glemmer nogle gange adgangskoden til en af vores mange online-konti, og Google-kontoen er ingen undtagelse.

Til dette formål har Google en fastlagt procedure for kontogendannelse, sådan at den retmæssige ejermand eller -kvinde kan få adgang til sin konto igen, når det sker, ved at legitimere sig og bevise ejerskabet over kontoen på forskellige andre måder.

Når Google Advanced Protection er slået til for en Google-konto, vil kravene til denne procedure være væsentligt skærpet i forhold til almindelige Google-konti, og det vil således være væsentligt sværere at få adgang til sin konto, hvis man skulle gå hen og glemme sit kodeord.

Dette er for at beskytte den rette ejermand mod at angribere uretmæssigt tiltusker sig adgang til ens konto, og er en anden del af prisen for en forbedret beskyttelse af ens Google-konto.

Præcis hvordan proceduren skærpes fortæller Google ikke noget om, men hvis man nogensinde har prøvet (for sjov eller for alvor) at komme igennem Googles almindelige procedure for kontogendannelse, ved man, at det er alt andet end trivielt at snyde sig ind denne vej, præcis som det retteligt bør være.

Konklusion

Google Advanced Protection giver brugere den stærkeste beskyttelse, Google kan tilbyde i dag.

Prisen for at gøre det er, at man skal leve med begrænsningerne beskrevet ovenfor, man skal betale for to fysiske sikkerhedsnøgler (en backup er påkrævet, før man får lov til at slå Advanced Protection til), og alle ens mobile enheder skal have NFC-understøttelse.

Om Google Advanced Protection er prisen værd, vil jeg lade det være op til dig at afgøre.

Categories
Uncategorized

Escaping Of Like Clauses

All software developers struggle with MSSQL vs. Oracle idiosyncracies at some point in their career.

In this post I’ll recount a recent personal experience I had where the particular idiosyncracies of MSSQL and Oracle clashed, and where a not-quite-fixed bug prevented NHibernate from providing a solution to the problem.

But first, the problem I needed to solve.

I was working on the functionality behind the search field in a user interface.

The search terms entered by the user were (after being properly sanitised) converted into an SQL SELECT statement with a LIKE clause and was subsequently sent to the underlying DBMS to be executed. NHibernate handled the conversion behind the scenes.

Here is an example of a resulting SQL statement:

SELECT * FROM SomeTable WHERE Name LIKE '%UserQuery%';

Where UserQuery is the text entered by the user in the search field.

Now, suppose the underlying DBMS is MSSQL and some rows in the database contains the following strings in some VARCHAR fields:

Foo [number_1], Foo [number_2], Foo [number_3]

Now the user enters the following search string in the search field:

Foo [number_1]

Naïvely, I’d expect the search to be converted by NHibernate into the following SQL statement:

SELECT * FROM SomeTable WHERE Name LIKE '%Foo [number_1]%';

NHIbernate did in fact convert the user query to this SQL statement, but that statement returns 0 rows (given the database contents above).

Why?

Because the _ (underscore) takes on a special meaning in a LIKE clause.

Underscore is interpreted as being part of a regular expression rather than being taken literally.

Indeed, the four characters [ ^ _ % all take on a special meaning for MSSQL, but only in a LIKE clause.

That’s why you must escape occurrences of these four characters in your select statements if you want to search for them literally.

Oracle takes a similar stance, except here only the characters _ % need to be escaped.

The actual query is determined by NHibernate. That means NHibernate must be instructed to escape occurrences of these characters.

But there is currently no way to do so, so it must be done manually through simple string replacement before pushing the input parameters to NHibernate.

But that’s not all. As always, MSSQL and Oracle do many things differently.

MSSQL defines a default escape char [] meaning you can escape the aforementioned special chars by encapsulating them in [], so ^ becomes [^], etc.

Oracle explicitly does not define a default escape char. You must define the escape char used by adding ESCAPE '\' to your statement (if you used \ as the escape char).

Revisiting the query from above, the resulting escaped SQL statement for MSSQL looks like this (we need to escape [ and _):

SELECT * FROM SomeTable WHERE Name LIKE '%Foo [[]number[_]1]%';

For Oracle it looks like this (we only need to escape _ in this case):

SELECT * FROM SomeTable WHERE Name LIKE '%Foo [number_1]%' ESCAPE '\';

Now both queries return 1 row as expected.

How do we get NHibernate to create these queries?

In a pinch, it could be done manually for MSSQL by escaping the prerequisite characters between % and % before passing the query to NHibernate, but that would be hack-ish, to say the least.

Preferably, NHibernate would take care of things automatically when it deteced a character that requires escaping.

NHibernate currently offers two static methods for creating LIKE clauses:

Restrictions.Like() and Restrictions.InsensitiveLike().

In this case, a case insensitive search was required, so Restrictions.InsensitiveLike() was the way to go. Alas, NHibernate does not automatically escape any characters at all, so the hack-ish solution described above is required for that DBMS.

For Oracle, I have found no workable solution to case-insensitive searches, because the Oracle syntax requires changes outside the quotes (‘) in the statement, and NHibernate does not add the prerequisite ESCAPE '\' syntax to the final query.

There is an overloaded version of the (case-sensitive) Like() method that takes an argument called escapeChar that specifies which character is used as the escape character in the LIKE clause. This is a bug fixed (sort of) in https://nhibernate.jira.com/browse/NH-938.

What that means is that if you add the escapeChar parameter to the call to Restrictions.Like(), and you’re running an Oracle DBMS, NHibernate will add ESCAPE '\' to the query automatically.

If you’re running MSSQL, NHibernate won’t add anything, because it’s not required by the DBMS.

For whatever reason, that bugfix did not add an overloaded method for Restrictions.InsensitiveLike(), so the only way I know to do a DBMS-agnostic selection using a LIKE clause with NHibernate is if you can accept the search being case-sensitive.

Categories
Uncategorized

How-To: Develop Spigot Server Minecraft Plugin

For a few years I taught a bunch of kids computer science through the Coding Pirates initiative here in Denmark.

Many of the kids had a keen interest in anything related to Minecraft, and for a while I tossed around the idea in my head of teaching them a lesson on how to write a Minecraft plugin.

Although the idea never materialised into an actual lesson for various reasons, I did sit down with my oldest son one night to see if putting his deep knowledge of Minecraft and my twenty-plus years of coding experience together would result in an actual, working Minecraft plugin for the Spigot server I’d already set up for him some months earlier.

Turns out that indeed it did.

We didn’t do it all by ourselves, or we would have spent days researching before reaching our goal instead of a few hours.

Google whipped up a link to an excellent tutorial on JustDave’s Blog which sped up the whole process by an order of magnitude. Thanks, Dave!

There’s no need to regurgitate everything from Dave’s post, but I’ll just recap the most important steps here:

  • Download and install the Java JDK (not the JRE, mind you).
  • Download and build the Spigot Minecraft server (we’d already done that a few months prior).
  • Install Eclipse IDE, or, I suppose, your Java IDE of choice, though if you don’t install Eclipse, some of the later instructions will differ for your setup, too.
  • Install the YEdit plugin in Eclipse. This is for easy editing of YAML files.
  • Create a new project, a package, the Main class, and the plugin.yml, all in Eclipse.
  • Create your build script, and tell Eclipse to use it.
  • Start implementing the Main class. The Main class must extend the JavaPlugin class, and don’t forget to @Override relevant methods.
  • When you’re done implementing the Main class, export a JAR file from Eclipse, and copy that JAR file to the plugins subdirectory under your Spigot server directory.
  • Restart Spigot, and assert that Spigot picks up the new plugin and loads it without errors.

Lastly, some quick Spigot reference links, taken directly from Dave’s post:

Categories
Uncategorized

Teaching Computer Science

Along with a small team of volunteers I teach computer science to a class of 7-11 year-olds once a week.

Sometimes it’s challenging to the kids’ attention span to keep them interested in what’s going on at the front of the class.

Then there are also those one-on-one moments between teacher and student where the teacher is reminded why teaching another human being a new skill is such a rewarding experience.

I had one such experience when I sat down with 10-year-old Jonah in the class and tried to explain to him how to place an object on a canvas programatically.

“The trick is to see the canvas as part of a coordinate system,” I said.

“Then you can place an object by assigning a pair of (x,y) coordinates to it.”

Jonah was able to follow my explanation thus far, but what happens if you put two objects in the same place by assiging the same coordinates to both objects?

Which one would be visible on the screen and which one would be hidden?

Enter the third dimension.

“Did your math teacher tell you about the X-axis and the Y-axis?” I asked Jonah.

He confirmed, illustrating the axes for me by holding out this thumb and index finger at a right angle.

“Well,” I said, “there’s also a Z-axis that you probably haven’t heard about yet.”

I picked out his middle finger so it was at a right angle to the other two fingers.

“Whoa…”, Jonah said, staring at me with a look of utter non-belief, his eyes wide open and his jaw hanging.

I left the table without another word and let it sink in. After all, I’d just added an entire new dimension to the kid’s universe.

How much more can you ask for in an idle Tuesday afternoon?