miniserv – pieni pätkä hakemistojen tietoturvaa

Reading Time: < 1 minute
Photo by Joshua Reddekopp on Unsplash

Miniserv sisältää pätkän koodia, joka tarkistaa selaimen antaman tiedostopyynnön. Tämä on tietoturvasyistä.

Löysin sopivan tuntuisen valmiin paketin, sanitize-filename. Kehittäjiä on kymmenkunta, ja paketti on yli sadantuhannen Github-projektin käytössä. Kehittäjien määrä kertoo siitä, että paketilla on selkeästi yhteistä hyötyä softamaailmassa, koska kyseessä ei ole pelkästään yhden hengen omien intressien kokeilu. Toistasataatuhatta käyttäjää kertoo jotain luottamuksesta. Paketti vaikuttaa sopivalta tähän tarkoitukseen.

Mitä tiedostonimen turvatarkastus tekee node-sanitizessa?

  • puhdistaa tiedostonimet vaarallisista ja epäilyttävistä merkeistä
  • käyttää 5 regex -rimpsua asian ajamiseen
  • estää mm. “path traversal” -hyökkäykset eli vääriin hakemistoihin pääsyn

Annan sanitize-filenamelle suoraan sen merkkijonon, mikä tulee HTTP-pyynnössä asiakkaalta (=web-selaimelta). Jos merkkijono säilyi alkuperäisenä, tiedämme että se on o.k (koska tarkastus ei havainnut mitään muutettavaa). Jos merkkijono ei ole enää alkuperäinen, serveri tiputtaa pyynnön ja palauttaa tilakoodin 400. Pieni googletus paljasti että 400 toimii tässä paremmin kuin perinteinen 404. Status 400 kertoo kohteliaasti, että “äläpä yritä enää tätä samaa pyyntöä”, kun taas 404 antaa mahdollisuuden että resurssi ei ole vain juuri nyt saatavilla, mutta kenties myöhemmin.

Miten hyökkääjä voi yrittää vaellella hakemistoissa?

  • tiedostonimi sisältää polkua vaihtavan ‘..’
  • tuplaetukeno (‘//’)

Toisentyyppinen kikka jota hyökkääjä voi käyttää, on terminaattorin eli 0-tavun (zero) lisääminen requestissa. Nolla voi aiheuttaa harmia järjestelmissä, jossa tuota arvoa käytetään merkkijonojen sisäisenä stopperimerkkinä. Nollan jälkeiset merkit ovat jälleen ne, jotka voivat aiheuttaa harmia tulkittaessa ne uudella tavalla.

Lukemistoa

OWASP-tietoturvasivustolla on mielenkiintoinen artikkeli aiheesta: Path Traversal.

Facebook Comments

Miniserv päivä 2 (Node-sarjaa)

Reading Time: 2 minutes

miniserv lähti liikkeelle aivan pienestä kokeilusta. Tein Noden päälle suurinpiirtein “hello worldia” vastaavan tason serverin. Serveri on siis JavaScript-koodia, ja se ajetaan käyntiin nodella.

Aloitustilanne miniserv.js – lähdekoodin laajuus

C:\nodestas>sloc miniserv.js

---------- Result ------------

            Physical :  35
              Source :  18
             Comment :  13
 Single-line comment :  13
       Block comment :  0
               Mixed :  1
 Empty block comment :  0
               Empty :  5
               To Do :  0

Number of files read :  1

----------------------------

Seuraavaksi laajennan tätä, niin että serveri osaa tarjoilla yhden hakemiston sisältöineen, eli tiedostoineen.

Tässä vaiheessa siis tulee jo luultavasti hieman ensimmäisiä harkintaa vaativia asioita.

Muutokset (lisäykset) serverin logiikassa:

  • palvelimen käsittelemä (web-selaimelta tuleva) GET -request saa nyt parametrikseen joko “/” tai tiedostonimen
  • serverin pitää päättää, onko GET perässä tuleva parametri sallittu (jolloin serveri tarjoilee kysytyn tiedoston), vai johtaako parametri pimentoon (tiedostoa ei löydy, tai pääsy on kielletty, tai parametri ei sovellu tiedoston nimeksi)
  • jos GET pyytämä tiedosto oli o.k., annetaan 200 OK ja palautetaan tiedoston sisältö (mahdollisesti jotenkin puskuroituna, todennäköisesti Node hoitaa tämän peltien alla automaattisesti)
  • jos syntyi virhe, annetaan sopiva HTTP virhekoodi (lista Wikipediassa)

Lyhyt recap vielä miten ylläoleva muuttaa tilannetta; ennen muutosta, nykyinen v0.1.0 serveri vain odottaa portissa 8000 selaimen kutsua ja palauttaa staattisen merkkijonon, joka on serverin “allekirjoitus” (signature). Ideana on siis todeta, että “moi, olen elossa, tässä on allekirjoitukseni”.

Uusi ominaisuus: tarjoillaan tiedosto

Nyt serveriä laajennetaan ymmärtämään tiedoston pyyntö. Oikeissa web-servereissä puhutaan reiteistä (‘routing‘). Käytännössä teen nyt miniserv :iin pelkän 1:1 staattisen vastaavuuden resurssin nimen ja serverillä olevan tiedoston nimen välillä. Eli jos käyttäjä antaa URLin:

http://servu.mme:8000/koe.txt 

serveri saa pyynnön “GET /koe.txt”. Tästä serverin koodi eristää vain loppuosan (kaikki ‘/’ merkin jälkeen aina rivin loppuun saakka), ja tarkistaa 2 asiaa: että kyseinen tiedostonimi ei sisällä konnankoukkuja, ja että pyyntöä vastaava tiedosto on olemassa myös serverillä. Jos molemmat ehdot o.k., niin serveri palauttaa tiedoston sisällön.

Kolmen rivin markkinointipuhe ominaisuuksista

  • serveri tarjoilee yhden hakemiston (folder) sisältöineen
  • serveri antaa oikeat HTTP tilakoodit tilanteen mukaan
  • ajokomento on ‘node ./miniserv.js –serve=hakemisto’
  • ei pääsynvalvontaa, joten tiedostot on kaikille näkyvissä jotka tietävät serveristä

Mihin miniserv soveltuisi tässä vaiheessa?

Nodeahan ja sorminäppäryyttä tässä edelleen opiskellaan. Silti ihan oikeakin käyttötapaus serverille voisi olla: haluat jakaa väliaikaisesti hakemiston sisältöineen webin kautta. Joskus voi olla tarve vain nopeasti kopioida tiedostot jonnekin jakoon.

Huom! Tällaisenään serveri ei esimerkiksi mitenkään toteuta pääsynvalvontaa, eli: kuka tahansa, joka sattuu löytämään serverin julkisen IP-osoitteen ja arvaa käytetyn TCP-portin, näkee jakamasi tiedostot (kunnes pysäytät serverin, näppäinyhdistelmä Ctrl-C konsolissa – tai esimerkiksi prosessin tappamalla, ‘kill’-komennolla).

Serverin lupaus resurssin nimen pysyvyydestä

Mietin tätä versiota tehdessä, miten oikeastaan web-serveri tietää, mitä client tarkoittaa antamallaan polulla? Onko request yksikäsitteinen? Vastaus on: riippuu aivan sopimuksesta. Clientin pitää ymmärtää web-serverin tarjoamien resurssien semantiikka. Käytännössä, jos kyseessä olisi perinteinen web-serveri, niin näinhän onkin: yleensä serverit ovat teknisinä alustoina, rakennuspalikoina, osana web-sivustoja. Serverit tallentavat tiedot (niin staattiset HTML-sivut, yksittäiset kuvat ja muut resurssit, kuin myös tarvittaessa dynaamiset sisällöt) – ja tarjoavat sivut HTTP-protokollaa käyttäen. Tällöin sivun rakentajan huolena on pitää referenssit oikeina ja osuvina. Serveri lupaa sivun tekijälle pitää kerran tallennetut tiedot aina samalla tunnisteella saatavina, eli jos web-sivulla oleva kuva on alunperin tallentunut osoitteeseen

http://sivu.mme/kuvat/kartta.jpg

niin web-serveri ei voi yksikantaan itse muuttaa enää kuvan osoitetta. Dynaamisen sisällön suhteen on sama idea, mutta tällöin serverillä on enemmän vapautta tehdä optimointia tai muutoksia sisäiseen tallennusmekanismiin, kunhan ulkoinen sopimus (ts. resurssin osoite) edelleen ylläpitää.

Sivut voi koodata käsinkin, mutta aika usein tässä käytetään myös jotain editoria tai ohjelmistoa, ja yksi syy on juuri viittauksissa esiintyvien virheiden vähentäminen kun sivujen tekijän ei tarvitse suoraan toimia “raakatasolla”.

Teknisesti requestien on oltava yksikäsitteisiä, muuten web-serveri ei toimisi deterministisesti, eli se ei oikeastaan olisi tietokoneohjelma.

Facebook Comments

Node-pöydän antimia

Reading Time: < 1 minute
Photo by Omar Flores on Unsplash

Lyhyehkö mutta toivottavasti joko hyödyllinen tai viihdyttävä päiväkirja Node-kehitykseen.

Paukuttelin tänään muutaman rivin koodia. Olen hyvin alkuvaiheessa vielä Noden kanssa. Näppituntuma alkaa olla hyvä. Tsekkasin Ryan Dahlin videon melkein läpikotaisin, tykkään tyylistä.

Videolta nappasin idean simppelin http-kirjastoa käyttävän servun tekemiseen. Todellakin, siis hyvin simppelin, mutta tästähän kaikki aina lähtee liikkeelle. Nodelle on olemassa paljon valmiita hilavitkuttimia, mutta joskus on kiintoisaa käpistellä perusteita, kunnes ne alkaa tosiaan upota tajuntaan. Nimesin tämän kokeen miniserv.js

Serveri jää muistiin odottelemaan porttiin 8000 GET / requesteja, ja kun sellainen tulee, kysyjälle vastataan text/plain sisältötyypillä, omalla versiomerkkijonolla. Whee! Mitä muuta? Ei. Mitään. Vielä.

Nodehan on varsinaisesti alunperin Googlen Chrome-selaimen JavaScript-tulkki (V8), josta on tehty itsenäinen ajoalusta ja interaktiivinen tulkki. Nodella voi ajaa JavaScriptaa, ja käyttää serverin (tai vaikka kotikoneen) käyttöjärjestelmän resursseja.

Node saattaa olla jo tuttu juttu sulle. Jos ei, suosittelen katsomaan ihan alkuperäisen Ryan Dahlin videon vuodelta 2011. Dahlilla on mielenkiintoinen tapa edetä silloin uutukaisen projektin esittelyssä. Hän kertoo monia pieniä jippoja ja laittaa kuulijankin miettimään, ennenkuin paljastaa asioita. Pidä mielessä koko ajan siis softan alkuperäinen historia: on olemassa hyvä JavaScript-moottori, ja Dahl halusi saada tämän pyörimään itsenäisesti ilman web-selainta.

Facebook Comments

Faster create-react-app scaffolding with a cache

Reading Time: < 1 minute

We know. It takes a “good” 5-10 minutes to run

$ create-react-app myTestApp 
Photo by Nathan Dumlao on Unsplash

The plan: I’m going to installing a npm repository cache npm_lazy, and do 4 measurement:

  • First time elapsed of a ‘create-react-app myApp’ – Without npm_lazy cache
  • Next time elapsed of a ‘create-react-app myApp’ – Without npm_lazy cache
  • Third time is the npm_cache install case, but when “npm install” not yet been ever run.
  • Fourth time elapsed is that of all things configured with npm_lazy cache

So the final benefit of using a npm_lazy cache will be subtracting the time between 4 and 2.

Gonna be back soon! Stay tuned. Second Post will be about the results. Cheers, Jukka

Facebook Comments

Troll management on a WordPress blog

Reading Time: < 1 minute

I am looking for 2 things:

a) near-perfect way of weeding out spam users right in Registration
b) automated deletion of spam Users, if some of these are already registered on a WordPress site

Feel free to tip any good tools that you’ve seen being used, or have used yourself. Thanks!

Will be posting about this in the future. For now, found it was easiest to just delete fake users right from the WordPress admin panel (backend). But it seems the incoming registration stream is quite constant, at a few new fake users per day, so in the long run it would be great to solve this in a bit more automated manner.

Facebook Comments

Washing spam user registrations, no worries!

Reading Time: < 1 minute

I received some (few) tens of troll user registrations on Jukkasoft. Looking for better way to manage these, but for now, will just manually delete the users. You don’t need to do anything. Just wanted to let you know.

Cheers & best wishes,
Jukka

Facebook Comments

TV short story synopsis

Reading Time: < 1 minute

Three young gentlemen found a company in 1988,
in the heart of Finnish innovation hub, Otaniemi.

The company, Inducon Consultants, gets its first major consultancy deal from a pulp industry giant.

The company grows into a very lucrative and
diverse IT consultancy.

Juha is looking for a job. He’s a fresh graduate from IT networking campus, without a hint of getting paid for his skills. He can’t stand authorities,
and has no experience from work life, let alone respect for seniority.

Juha gets his first stint, half by accident, from Inducon, as the company are desperately looking for young talent.

Juha causes some stirups, as he gets special treatment from senior management. Juhani, a rather new face at the board, bets all his chips in one basket. He is sure that Juha is exactly what the company needs.

Juha gets a private lab room, fully equipped with all the tinfoil gear that he needs. It’s extraordinarily posh even for Inducon. His budget is also non-disclosed. Another striking exception to company policy.

Juha can develop his breathtaking (but unproven) visions of a new
kind of keyless digital authentication system, Damocles.
He whispers the right growth keywords to management, while
at the same time infuriating some of his senior colleagues.

Inducon is torn into two parts. The fight is clearly
taking apart some of the well-deserved ethos that had
previously taken the company to legendary heights and
undisputed reputation.

As the founder slips to oblivion, the rudder is up for grabs.
What happens next? Find out. Stay tuned!

Facebook Comments

Practical optimizations in programming: boids’ distance to each other

Reading Time: 3 minutes

Let’s say we have 1000 boids: little worms, birds or what-ever-animal is your favorite, moving around in a canvas (restricted to X and Y coordinates, that is a plane). The boids form a beautiful swarm. Collectively they seem to be following some invisible leader, while avoiding crashing each other.

Can we somehow optimize the calculation of distances?

Boids make a fantastically realistic depiction of flocking behavior due to 3 simple rules:

Boids in this context are considered only as a graphics simulation. Boids have AI context as well: in Particle Swarm Optimization (PSO), the search happens via a group of boids. We’re not covering PSO aspects in this post.

Basics

Why distances are important for boids?

Boids, as simulated by computers, only “see” the world through distance calculation alone. So every boid wants to know the distance to every other boid. If there’s 1000 boids, we need to calculate “from each boid, the Euclidean distance to each other boid”.

Boids follow a few rules, and they are based on the distances:

  • cohesion (of swarm)
  • avoid being in the edges of a swarm
  • don’t collide to other boids

So how much is it? How many CPU-based calculations do we need? Is there a low-hanging fruit, some optimization we might use in the algorithm?

Naturally we’re looking at a FOR (loop). In fact, FOR each boid, go through all other boids. So it’s nested FOR.

for each v in vertices:
    for t in (vertices - v):
        dist[v,t] = sqrt(pow(v.x-t.x,2) + pow(v.y-t.y,2))

Since the distance (=edge length) between two vertices is symmetric (from Bob to Alice is same amount as from Alice to Bob), we only need count the distance pairs between all boids. This reduces calculation by 50%.

Let’s induce the “number of edges” formula in a very short manner:

Vertices# of Edges
10
21
33
46
510
Number of edges in a mesh (complete graph) of N vertices

How many CPU cycles needed to calculate one distance?

Approximations will do. We’re quite low level here, not quite exact CPU cycle counting — but close enough. You might have seen this same formula in a bit different format, but it wants to say: you need to calculate a square root of a sum. the sum is composed of second powers of X- and Y- distances (differences) of the two points.

Distance (an edge) is thus:

sqrt( Dx^2 + Dx^2 )

  • Dx is (X1 – X2)
  • Dy is (Y1 – Y2)
  • sqrt counts for 1 CPU operation (op)
  • sum (the ‘+’) is also 1 op
  • powers (^2) are both 1 op, so 2 op total for powers
  • total 4 arithmetic operations per each boid pair

Distance calculation details for boids

  • take one boid as center
  • calculate lines (pythagorean distance) to all N-1 other boids
  • dist = sqrt[ (delta_x)^2 + (delta_y)^2 ]
  • a little trick: there is symmetry. The distance from the other boid to “us” is same as from us to there
  • thus we need only calculate once the distance between two boids
  • store the value so that both boids can use it

We would otherwise do unnecessary calculations. But is the “50% off” of the algorithm runtime the best we can get? Can we shave more out of the algorithm? Or should we ask, at what point it makes sense to even try to shave more off? It’s always sane to optimize only in the right places, what comes to coding. But then again… Well, you get the point, before we’re entering an infinite recursion.

As aside – for practical purposes in a game engine, I’d like to add a “stress causing factor” for the boids. This is related to the density of units in an area, centered around each boid. The stress level would need one thing first calculated: distance of all other boids to the boid itself.

When we have the distances, we can cut-off the population of boids to 2 sets: those within R (range), and the rest are outside of range.

The stress comes from necessity of making a lot of adjustments in a small period of time. So if a worm needs to jiggle a lot, it gets stressed. The jiggle amount is interesting metric. How should I define it in practical terms?

Facebook Comments