Fejlesztés: Miért kapsz rossz minőségű és drága kódot?

Mivel a webes fejlesztés világának része vagyok kb. 15 éve, ismét szeretnék egy olyan témát felhozni, ami kissé vérlázító azok számára, akiknél a pénztárca van. A bejegyzést az ihlette, hogy külsősként dolgozom kell olyan kódban, amit hatalmas refenreciákkal rendelkező, nagyon neves cégek adtak el de a minősége meglehetősen gyatra, a kókányolások igazi iskolapéldái. Sajnos nyilvánvaló okokból nem másolhatok ide kódrészleteket, de hasonlót írhatok, ami szemlélteti a probléma jellegét. 

Fejlesztőt találni sem egyszerű

Így 2018 elején a legnagyobb munkaerő hiánnyal küzdő szakma a fejlesztőké. Már napi szinten találnak meg fejvadászok, pedig 2-3 éve évi 1 megkeresés ha érkezett. Annyira súlyos lett a helyzet, hogy már külföldi fejvadászok is találnak meg ezen a blogon keresztül. Lassan bármilyen írástudót felvesznek majd fejlesztőnek és megpróbálják kiképezni saját pénzen (borítékolom, hogy 100-ból 1 ha sikerülni fog).

A hiánynak szerintem több oka is van, de ezt majd egy másik blogbejegyzésben taglalom, hogy mik is ezek. Most másról lesz szól.

A fejlesztők szintjei

A jelenleg fellelhető álláshirdetések alapján csupán 2 szint alapján próbálják besorolni a tudást: junior és senior. Ez szerintem hatalmas hiba. Arra persze nagyon vigyáz mindenki, hogy ne legyen definiálva mit is jelentenek ezek, de legalább tudományosan néz ki leírva. Találkozni olyan „junior” álláshirdetésekkel, ahol a polihisztor egy írástudatlan hülye az igényekhez képest, ahogy olyan senior hirdetésekkel is, ahol már az önálló munkavégzés is hatalmas képesség. Napi szinten nézem az álláshirdetéseket, igény kirásokat és én magam úgy saccolom, hogy a junior szintet karcolom alulról. Ismerek több fejlesztőt, akik ugyancsak nem ütik meg ezt a szintet, de napi szinten termelnek és értékesítenek, teljes magabiztossággal és profikhoz mérhető árakkal. Nincs ezzel semmi baj, ők csinálják jól.

Szerintem a fejlesztőket nem az alapján kellene besorolni, hogy hány éve vannak a szakmában (én a 15 évvel már szuper-senior lehetnék) és nem is az alapján, hogy hány 3 és 4 betűs rövidítésről hallottak már. Hanem hogy az adott technológiákban mennyire tudnak magabiztosan, gyorsan, és biztonsági szempontokat is figyelembe tartva dolgozni.

A fejlesztés nagyon drága

Az egyedi fejlesztés a legdrágább dolog a világon. Szerintem nem kell leírnom, hogy egy fejlesztőnek milyen infrastruktúrát kell magának felépítenie, mennyit kell tanulnia és végül mennyi ideje marad kitermelni a chipsre és a kólára valót. Csak a webes technológiák is akkora témakört fednek már le, hogy képtelenség egy embernek értenie hozzá. Cserébe viszont hatalmas, platform-független piacot tud lefedni, az okosTV app fejlesztésen át a az asztali- és mobilalkalmazásokig. Viszont specializálódni ezekben csak óvatosan szabad, mert a natív kódok mindig sokkal jobbak, biztosabbak, webes alapra építeni olyan dolgokat amiket nem arra találtak ki, egy kissé kókányolás.

Az egyetlen módszer a „fröccsöntés”, amivel egy webfejlesztő nyereséges tud lenni. Ezekre a legtipikusabb példa, hogy kérsz egy weblapot a kis vállalkozásodnak, elkérnek százezreket majd kapsz egy Joomla/Wordpress/Drupal (ingyenes) rendszert, hozzá valami maximum $25-os sablont – hogy mutasson is valahogy – és készen is van a weblap. Kb. 1-2 óra munkával máris százezreket kerestünk. Az ügyesebbek már igyekeznek „kiherélni” az ilyen ingyenes motorokat, hogy ne lehessen látni a lehúzást. A kedves ügyfél viszonylag gyorsan megkapja a weblapját és örökre ottmaradnak benne az egyszerű Google keresésssel megtalálható biztonsági rések, a fejlesztő pedig százezreket kaszál egy Knight Rider epizódnyi idő alatt. Mindenki jól jár, nem igaz?

Persze ritkán fordul elő, hogy egy eleve kész és ingyenes rendszer elegendő lesz, mindig jönnek az extra igények. Ilnyekor még mindig lehet kapaszkodni ezekbe a megoldásokba, de már bővítményeket kell bele fejleszteni, ami specializált tudást igényel – hisz’ ismerni kell a rendszer sajátosságait – máris erősen megszűrtük a fejlesztők kínálatát és ezzel újabb százezreket égetünk el, amiből kapunk egy olyan terméket, ami valószínűleg egy frissítést sem fog túlélni.

Marad az egyedi kódfejlesztés, ez a legnagyobb üzlet látszólag. Rengeteg buktatóval sokszoros határidő csúszással, a szomszéd galaxisig elszálló költségekkel. Itt még mindig van lehetőség fröccsönteni keretrendszerek segítségével. Az álláshirdetések 95%-a megkövetel legalább 2-3 keretrendszer ismeretet, ugyanis így még viszonylag gyorsan állítható elő termék és az elkért összegből még marad egy kicsi a zsebben. A kód szépen fog mutatni az ügyfél előtt, a grafikus is örülni fog, mert az MVC menő. Én már leírtam egy korábbi bejegyzésben, hogy miért nem vagyok rajongója ezeknek a keretrendszereknek, de az előnyeiket nem vitatom, igenis van értelme és jó dolog. Viszont az én ügyfélkörömben ezek nem mindig a legmegfelelőbb megoldások. A kisvállalkozások nem tudják megfizetni a folyamatos frissítgetéseket, bizonsági foltozgatásokat és az erőforrás igényeket. Minden kis cég úgy indul, hogy „Ó, simán elég egy wordpress”. Majd lassú lesz, a WooCommerce webshop napi 30 értékesítésnél is szenved. Na ja, mert a WordPress blogmotor, blogolásra van kitalálva, nem webshopnak ügye. Jó dolog az univerzális megoldás, csak éppen nem gyors és még annyira sem biztonságos.

A fejlesztés csúcsa a „natív” fejlesztés. Amikor a lehető legkevesebb kész megoldást használjuk fel. Én ezt csinálom és könnyen belátható, hogy a webes világban ennek van a legrosszabb órabére. A fröccsöntéssel egy komplett hírportál percek alatt beüzemelhető, de szemrebbenés nélkül elkérnek érte százezreket, milliókat. Natív kódként előállítani egy hasonló – de teljesen egyedi igényekre szabott – megoldást hónapokba vagy évekbe telik.

A natív fejlesztés alatt nem mindig azt kell érteni, hogy a semmiből állítunk elő egy kész terméket. A legtöbb esetben egy már meglevő, működő termékben kell módosításokat végrehajtani, kibővíteni, hibát keresni és javítani. Ez érdekesnek hangzik ügye? Hát lefordítom ősmagyarra: Legtöbbször „mások szarát kell takarítani”. Különösen igaz ez a nagyon neves cégek által sok-sok millióért készített megoldásokra. Igazi iskolapéldái a gányolásnak.

A sokmilliós gányolás

Én magam is készítettem nevetséges PHP/HTML/JS tudással portálmotort és webshopot is. Nem vagyok egyikre sem büszke, de furamód sok éve működik. Vannak dolgok, amikből már akkor sem engedtem és próbáltam az aktuális tudásomhoz képest megtenni mindent, hogy lehetőleg biztonságos kód kerüljön ki a kezeim közül. Mindenki tudja, hogy feltörhetetlen kód nincs, de azért a legalapvetőbb dolgokat meg kellene tenni. Nos ezekre sajnos ritkán figyelnek oda. Miért? Mert nem éri meg foglalkozni vele.

A funkcionális kód fejlesztési ideje töredéke egy technikai ajánlásoknak megfelelő kódénak, a PHP ráadásul sokat segít a gányolásban ( automatikus típuskonverzió, a nem definiált értékek csak warningot/noticet dobnak, … ). Ha csak egy kicsit is odafigyelünk arra, hogy mit is csinálunk, máris simán lehet hatszorosa a fejlesztési idő. Ki fizeti azt ki? Senki. Naná, hogy gányol mindenki. 

Hogyan is néz ki ez a gyakorlatban? Miért állítok ilyesmiket? Nem kell programozónak lenni, hogy lássuk a különbséget, már csak gépelési időben. Az egyik legtipikusabb ilyen, az adatbázisból lekérdezés, felhasználó által bevitt szöveg alapján, pl. keresés egy weboldalon:

<?php
$kereses = $_POST['keresos_beviteli_mezo']; // "Szuper jó cikk"
$sql = 'SELECT id, cim, tartalom FROM hirek WHERE cim = '.$kereses.' ORDER BY publikalva DESC';
   foreach ($conn-&gt;query($sql) as $talalat) {
// talalatok
}
}
?>

Látszik, hogy milyen szép rövid. Igazi iskolapéldája az SQL injection alapú támadásnak. De hogyan is néz ki ez akkor, ha egy picit adunk is arra – de még mindig lusták vagyunk -, hogy mit csinálunk? Valami ilyesmi erősen leegyszerűsítve és a megfelelő lustaság faktorral megírva:

<?php
$eredmenyek = [];
try {
$stmt = $PDO->prepare("SELECT id, cim, tartalom FROM hirek WHERE cim = :kereses ORDER BY publikalva DESC");
$stmt->execute([
':kereses' => $_POST['kereses_beviteli_mezo']
]);
$talalatok_szama = (int) $stmt->rowCount();
if ( $talalatok_szama ) {
$eredmenyek = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
catch( Exception $e ) {
Log::adatbazisHiba( $e->getMessage() );
}
?>

De persze ez szépen úgy nézne ki, ha le lenne egy Hirek adatobjektum, ami Hir objektumok tömbje lenne és abba kérdeznénk le és így tovább lehet végtelenségig szaporítani a sorok számát, csak nem mindig érdemes. (Nem kell mindig ész nélkül OOP-ra erőltetni mindent, meg szuper jól kinéző miniobjektumokba – szerintem).

A következő szupertipikus dolog a script/program betöltése felhasználói paraméterek alapján, pl. http://hirportal.hu/kategoriak/sport és http://hirportal.hu/tartalom/impresszum, amit a fejlesztő úgy dolgoz fel, hogy „szétrobbantja” a címet, a számára értékes tartalom pedig a „kategoriak” és a „sport” lesz valamint „tartalom” és „impresszum”. Igen ám, de a kategória nézet és a tartalom nézet teljesen más, azt külön programkód generálja. Segáz, a fejlesztő is ember, tehát lusta:

$url_parameterek = [
0 => 'kategoriak',
1 => 'sport'
]

és

$url_parameterek = [
0 => 'tartalom',
1 => 'impresszum'
]

Hogyan is csináljuk meg ezt jóra? Hát biztos nem fog felsorolni mindent egyenként, inkább megcsinálja hogy ezt automatán tegye meg helyette a rendszer:

include_once 'bovitmenyek/'.$url_parameterek[0].'.php'; // kategoriak

Lustaság fél egészség, csak hogy mi teljesen egészségesek akarunk lenni ügye? Ezt a példát nagyon gyakran látom sokmillió Forintos kódokban, amit olyan cégek gyártottak, akik büszkén verik rá a mellüket és Magyarország vezető weblapjai alá adják a motort. Mi ezzel a baj? Hát az, hogy így bármit betölt, szűrés és válogatás nélkül, azt is, amit nem lenne szabad. „Ó, de a PHP fordító úgyis lefordítja a config.php-t, nem látszanak a jelszavak” – na ja, de a képfeltöltőt az adminban és a hasonlókat is ilyen alapossággal kezelik, szal’ a kód/fájl injektálást szépen megkönnyítik ezzel. Az meg már külön jó, ha a weboldal a saját mappájába sincs bezárva és mondjuk lementjük a /etc/passwd -t és hasonlókat.

A kód vizsgálat mértékegysége, miaf***/perc : http://commadot.com/wtf-per-minute/

Professzinális kódok felimserése

Pár tipikus eset, amikkel találkozom a „pro” kódokban:

  • SQL injection lehetősége
  • fájl/script injection lehetősége
  • a képfeltöltések nincsenek szűrve (emlékszik még valaki a kép EXIF infoba épített PHP kód hackre, amit az Apache simán végrehajtott?), még csak azt sem vizsgálják meg, hogy kép-e, sőt! azt se, hogy legalább a kiterjesztése képet sugall-e
  • az adminisztrációs felület érvényes munkamenet nélküli részein is feltételezik, hogy megbízható a használó (pl. admin felület belépés kezelése, feltöltés elfogadása, módosítás elfogadása)
  • ciklusban SQL kérésben ciklusban SQL kérésben ciklusban SQL kérésben ciklusban SQL kérésben ciklusban ciklus (nem, nem a PHP-MySQL lassú, a fejlesztő lusta/hülye)
  • minden adatbázisban van definiálva, de az id-k alapján hardcode beégetésekkel van tele az egész
  • memcache használata korlátozás nélkül (nem csak localhostról érhető el, vagy nem csak az a kód éri el, aminek szabad lenne)
  • adatbázishoz kapcsolódás rootként
  • verziókezelés az éles kódban
  • irdatlan mennyiségű utólagos hack (a szuperül megtervezett rendszerhez)
  • kísérlet egy szép „template kezelő” /  „URL router” / „űrlap kezelő”  létrehozására, majd sok-sok utólagos hack hozzá mindenféle JavaScript és PHP trükkökkel – hogy azért még szép maradjon a kód – a gányt meg eldugjuk egy functions.php-ben
  • angol és magyar változónevek véletlenszerűen, bárminemű logika hiánya a változó- és függvény nevekben
  • még fcgi-ben sincs bezárva a PHP script a saját mappájába
  • tranzakció, foreign key, lock, hibakezelés ugyan minek, hisz’ csak számlákkal dolgozunk
  • indexet mindenre, mer’ az gyorsít ügye

Mi a megoldás?

Nincs. A pénzed, a céged online arculata a fejlesztő kezében van. Te nem értesz hozzá, ő meg összegányol valamit, ami működik, téged meg amúgy sem érdekel hogyan. Ha egy buta script indiából kiteszi a péniszt a nyitólapra, majd keresünk valakit aki megoldja. Ha ellopják az összes adatot, kit érdekel? Hol érdekel engem supercsaj23 jelszava? Hát, jobban fájhat, mint gondolnád: https://www.adatvedelmirendelet.hu/a-rendelet-szovege/ . Sohasem fogod ránézésre felismerni azt a fejlesztőt, aki próbálja az elvárható dolgokat alkalmazni. Ezek a fejlesztők amúgy is erősen kihalófélben vannak, mert éhenhalnak. Az üzlet a gányolásban van. Most különösen, amikor ez a top1 hiányszakma a világon.

Én hobbi szintű webes fejlesztő vagyok. Egyik részében sem vagyok profi, magabiztos vagy végletekig alapos, sőt… De legalább próbálom az aktuális tudásomhoz képest úgy megcsinálni a dolgokat, hogy az alapvető dolgokat betartom. Lehetne többet is tenni, de nem érdemes. Lehetne sokkal kevesebbet – mert én is pénzből élek – de nem merném kiadni a kezemből. Inkább legyen benne 1000 működési hiba, de az alapvető dolgok meglegyenek.