Statisk typanalys i JavaScript. Försöker Facebook Flow Analyzer


Var och en av teamet] [har sina egna preferenser när det gäller programvara och verktyg för penetrationstestning. Efter en del diskussion fick vi reda på: valet är så annorlunda att du kan göra en riktig gentleman uppsättning beprövade program. På det och beslutade. För att inte göra ett lagpaddling är hela listan indelad i ämnen. Idag ska vi analysera analysatorer för statisk kod för att söka efter sårbarheter i applikationer när du har deras källor till hands.

Närvaron av källkoder i programmet förenklar sökningen efter sårbarheter. Istället för att blindt manipulera olika parametrar som skickas till applikationen är det mycket lättare att se i de slag hur den bearbetar dem. Till exempel, om data från en användare överförs utan kontroller och transformationer når den en SQL-fråga, vi har en SQL-injektionssårbarhet. Om de når utdata i HTML-kod får vi klassisk XSS. En statisk skanner krävs för att tydligt upptäcka sådana situationer, men tyvärr är det inte alltid så enkelt som det verkar.

Moderna kompilatorer

Det låter kanske roligt, men en av de mest effektiva kodanalysatorer är kompilatorerna själva. Naturligtvis är de avsedda för något helt annat, men som en bonus erbjuder var och en en bra källverifierare som kan upptäcka ett stort antal fel. Varför sparar han inte? Ursprungligen ställs inställningarna för sådan verifiering av koden lojalt nog: som ett resultat, för att inte förvirra programmeraren, börjar kompilatorn att svära bara vid de allvarligaste problemen. Men förgäves - om du ställer in varningsnivån högre är det fullt möjligt att gräva upp många tvivelaktiga platser i koden. Det ser ut ungefär så här. Låt oss säga att koden saknar en kontroll av längden på en sträng innan den kopieras till bufferten. Skannern hittar en funktion som kopierar en sträng (eller dess fragment) till en buffert av fast storlek utan att först kontrollera dess längd. Han spårar banan för att skicka argument: från ingångsdata till den sårbara funktionen och ser ut: är det möjligt att välja en sådan stränglängd som skulle orsaka ett överflöde i den sårbara funktionen och inte skulle trunkeras av de kontroller som föregick den. Om det inte finns någon sådan kontroll, hittar vi nästan 100% buffertöverskridande. Det största problemet med att använda en kompilator för att kontrollera är att få den att "svälja" någon annans kod. Om du någonsin har försökt att kompilera en applikation från källan vet du hur svårt det är att tillfredsställa alla beroenden, särskilt i stora projekt. Men resultatet är värt det! Dessutom har, förutom kompilatorn, kraftfulla IDE-enheter inbyggt några andra verktyg för kodanalys... Till exempel kommer följande kodfragment i Visual Studio att visa en varning om att använda _alloca-funktionen i en slinga, som snabbt kan översvämma stacken:

char * b;
gör (
b \u003d (char *) _ alloca (9)
) medan (1)

Detta beror på den statiska analysatorn PREfast. Precis som FxCop, som är utformat för att analysera hanterad kod, distribuerades PREfast initialt som ett fristående verktyg och blev först senare en del av Visual Studio.

RATS - Grovt granskningsverktyg för säkerhet

Webbplats: www.securesoftware.com
Licens: GNU GPL
Plattform: Unix, Windows
Språk: C ++, PHP, Python, Ruby

Felfel - strid. Några av de brister som programmerare gör är inte kritiska och hotar bara programmets instabilitet. Andra tillåter å andra sidan att shellcode-injektion och godtyckliga kommandon körs på en fjärrserver. Kommandon som tillåter buffertöverskridning och andra liknande typer av attacker är särskilt riskabla i kod. Det finns många sådana kommandon, när det gäller C / C ++ är dessa funktioner för att arbeta med strängar (xstrcpy (), strcat (), gets (), sprintf (), printf (), snprintf (), syslog ()), systemkommandon ( access (), chown (), chgrp (), chmod (), tmpfile (), tmpnam (), tempnam (), mktemp ()) samt systemkommandon (exec (), system (), popen () ). Att undersöka hela koden för hand (speciellt om den är flera tusen rader lång) är ganska tråkig. Det betyder att du enkelt kan förbise överföringen av overifierade parametrar till någon funktion. Särskilda granskningsverktyg, inklusive det välkända verktyget, kan underlätta uppgiften Råttor (Grovt granskningsverktyg för säkerhet) från det välkända företaget Fortify. Hon kommer inte bara att klara av bearbetningen av kod skriven i C / C ++, utan kommer också att kunna bearbeta skript i Perl, PHP och Python. Verktygsdatabasen innehåller en imponerande samling med en detaljerad beskrivning av problemområden i koden. Med hjälp av analysatorn kommer hon att bearbeta skrotet som matas till henne och försöka identifiera buggar, varefter hon kommer att ge information om de brister som hittats. Råttor fungerar genom kommandoraden, både under Windows och * nix-system.

Yasca

Webbplats: www.yasca.org
Licens: öppen källkod
Plattform: Unix, Windows
Språk: C ++, Java, .NET, ASP, Perl, PHP, Python och andra.

Yasca precis som RATS inte behöver installeras, medan det inte bara har ett konsolgränssnitt utan också ett enkelt GUI. Utvecklarna rekommenderar att du kör verktyget genom konsolen - de säger att det finns fler möjligheter. Det är roligt att Yasca-motorn är skriven i PHP 5.2.5, och tolk (i den mest trunkerade versionen) ligger i en av undermapparna i arkivet med programmet. Hela programmet består logiskt av en front-end, en uppsättning skanningsprogram, en rapportgenerator och själva motorn, som får alla kugghjul att rotera tillsammans. Plugins dumpas till plugin-katalogen - du måste installera ytterligare tillägg där också. En viktig punkt! Tre av de standardinsticksprogram som medföljer Yascahar otäcka missbruk. JLint, som skannar Java ".class-filer, kräver jlint.exe i resurs- / verktygskatalogen. Det andra plugin, antiC, som används för att analysera Java- och C / C ++ -sorter, kräver antic.exe i samma katalog. PMD, som behandlar Java-kod, kräver Java JRE 1.4 eller högre. Du kan kontrollera om installationen är korrekt genom att skriva "yasca ./resources/test/". Hur ser skanningen ut? Efter bearbetning av källorna som matats till programmet, Yasca ger resultatet i form av en särskild rapport. Till exempel tillåter en av de vanliga GREP-plugins att använda mönster som beskrivs i .grep-filer för att indikera sårbara konstruktioner och enkelt identifiera ett antal sårbarheter. En uppsättning sådana mönster ingår redan i programmet: för att söka efter svag kryptering är auktorisering med "lösenord lika med inloggning", möjliga SQL-injektioner och mycket mer. Var inte lat för att installera ytterligare plugins när du vill se mer detaljerad information i rapporten. En sak är att med deras hjälp kan du dessutom skanna kod på .NET (VB.NET, C #, ASP.NET), PHP, ColdFusion, COBOL, HTML, JavaScript, CSS, Visual Basic, ASP, Python, Perl.

Cppcheck

Hemsida:
Licens: öppen källkod
Plattform: Unix, Windows
Språk: C ++

Utvecklare Cppcheck beslutade att inte spridas om bagateller, och därför fångas endast strikt definierade kategorier av buggar och endast i C ++ - kod. Förvänta dig inte att programmet duplicerar kompileringsvarningarna - det kommer att göra utan en uppmaning. Var därför inte lat för att ställa in den maximala varningsnivån för kompilatorn och använd Cppcheck för att kontrollera minnesläckage, överträdelser av allokerings-deallocation-operationer, olika buffertöverflöden, användning av föråldrade funktioner och mycket mer. En viktig detalj: Cppcheck-utvecklarna har försökt hålla antalet falska positiva till ett minimum. Om programmet fixar ett fel kan du därför med största sannolikhet säga: "Det är det verkligen!" Du kan köra analysen både under konsolen och med ett trevligt GUI-gränssnitt skrivet i Qt och arbetar under vilken plattform som helst.

graudit

Webbplats: www.justanotherhacker.com/projects/graudit.html
Licens: öppen källkod
Plattform: Unix, Windows
Språk: C ++, PHP, Python, Perl

Detta enkla skript, kombinerat med en uppsättning signaturer, låter dig hitta ett antal kritiska sårbarheter i koden, och sökningen utförs med det välkända grep-verktyget. Det är olämpligt att ens nämna GUI-gränssnittet här: allt görs via konsolen. Det finns flera tangenter att starta, men i det enklaste fallet räcker det att ange sökvägen till källorna som en parameter:

graudit / sökväg / till / skanna

Belöningen för flit blir en färgglad rapport om potentiellt utnyttjbara platser i koden. Jag måste säga att, förutom själva skriptet (som bara är 100 rader Bash-kod), är signaturbaser, som innehåller regexps och namn på potentiellt sårbara funktioner på olika språk, av värde. Som standard är baserna för Python, Perl, PHP, C ++ inkluderade - du kan ta filer från signaturmappen och använda i din egen utveckling.

SWAAT

Webbplats: www.owasp.org
Licens: öppen källkod
Plattform: Unix, Windows
Språk: Java, JSP, ASP .Net, PHP

Om graudit använder textfiler för att ställa in sårbarhetssignaturen, då SWAAT - ett mer progressivt tillvägagångssätt med XML-filer. Så här ser en typisk signatur ut:

vuln match - regelbundet uttryck för sökning;
typ - anger vilken typ av sårbarhet:
svårighetsgrad - anger risknivån (hög, medel eller låg)
alt - alternativ kod för att lösa problemet

SWAAT läser signaturbasen och försöker med hjälp av att hitta problemområden för koden i källorna i Java, JSP, ASP .Net och PHP. Databasen uppdateras ständigt och förutom listan över "farliga" funktioner innehåller den typiska misstag vid användning av strängformatering och skrivning av SQL-frågor. Det är anmärkningsvärt att programmet är skrivet i C #, men det fungerar bra under nixar, tack vare Mono-projektet, en öppen implementering av .Net-plattformen.

PHP Bug Scanner

Webbplats: raz0r.name/releases/php-bug-scanner
Licens: Gratisprogram
Plattform: Windows
Språk: PHP

Om du behöver utföra statisk analys av en PHP-applikation rekommenderar jag att du försöker PHP Bug Scanner, som skrevs av vår författare - raz0r. Programmets arbete bygger på att skanna olika funktioner och variabler i PHP-skript som kan användas under webbattacker. Beskrivningen av sådana situationer görs i form av så kallade förinställningar, och programmet innehåller redan 7 speciella förinställningar, grupperade efter kategorier:

  • kodkörning;
  • kommandokörning;
  • kataloggenomgång;
  • globals skrivs över;
  • omfatta;
  • SQL-injektion;
  • diverse.

Det är roligt att programmet är skrivet i PHP / WinBinder och sammanställt av bamcompile, så det ser ut som en vanlig Windows-applikation. Genom ett bekvämt gränssnitt kan pentestern aktivera eller inaktivera kodanalys för förekomsten av vissa sårbarheter.

Pixy

Webbplats: pixybox.seclab.tuwien.ac.at
Licens: Gratisprogram
Plattform: Unix, Windows
Språk: PHP

Verktyget är baserat på att skanna källkoden och bygga grafer för dataströmmar. Den här grafen spårar sökvägen till data som kommer utanför programmet - från användaren, från databasen, från något externt plugin-program etc. Således skapas en lista över sårbarheter (eller ingångar) i applikationer. Med hjälp av mönster som beskriver sårbarheten kontrollerar Pixy sådana punkter och låter dig identifiera XSS- och SQL-sårbarheter. Dessutom kan själva graferna, som byggs under analysen, visas i diagrammappen (till exempel xss_file.php_1_dep.dot) - detta är mycket användbart för att förstå varför en viss kod anses vara Pixy-sårbar. Generellt är själva utvecklingen extremt informativ och visar hur avancerade verktyg för analys av statisk kod fungerar. På dokumentationssidan talar utvecklaren tydligt om de olika stadierna i programmets arbete, förklarar logiken och algoritmen för hur en viss kod ska analyseras av programmet. Själva programmet är skrivet i Java och distribueras i öppen källkod, och på hemsidan finns till och med en enkel onlinetjänst för att kontrollera koden för XSS-sårbarheter.

Uns 6

Webbplats: www.ouncelabs.com/products
Licens: Shareware
Plattform: Windows

Tyvärr är de befintliga gratislösningarna fortfarande en nedskärning under deras kommersiella motsvarigheter. Det räcker att studera kvaliteten och detaljerna i rapporten, vilket är Uns 6 - och förstå varför. Programmet är baserat på en speciell Ounce Core-analysmotor som kontrollerar koden för överensstämmelse med de regler och policyer som utarbetats av ett team av professionella pentestrar som har samlat erfarenhet från välkända säkerhetsföretag, hackersamhälle och säkerhetsstandarder. Programmet upptäcker en rad olika sårbarheter i koden: från buffert till SQL-injektion. Om så önskas integreras Ounce enkelt med populära IDE: er för att implementera automatisk kodkontroll under byggandet av varje ny version av den utvecklade applikationen. För övrigt förvärvades utvecklarföretaget - Ounce Labs - av IBM själv i sommar. Så produkten kommer sannolikt att fortsätta utvecklingen som en del av en av IBMs kommersiella applikationer.

Klocwork Insight

Webbplats: www.klocwork.com
Licens: Shareware
Plattform: Windows
Språk: C ++, Java, C #

Under lång tid implementerade återigen kommersiell produkt statisk kodsökning endast för C, C + och Java. Men så snart Visual Studio 2008 och .NET Framework 3.5 kom ut meddelade utvecklarna stöd för C #. Jag körde programmet på två av mina hjälpprojekt, som jag snabbt skrev i "Sharp" och programmet identifierade 7 kritiska sårbarheter. Det är bra att de är skrivna exklusivt för internt bruk :). Klocwork Insight inleddes först och främst för att arbeta tillsammans med integrerade utvecklingsmiljöer. Integration med samma Visual Studio eller Eclipse görs extremt bra - du börjar allvarligt tänka att sådan funktionalitet bör implementeras i dem som standard :). Om du inte tar hänsyn till problemen med programmets logik och prestandaproblem, då Klocwork Insight gör ett utmärkt jobb med att hitta buffertöverflöden, brist på anpassad kodfiltrering, SQL / Path / Cross-site-injektionsfunktioner, svag kryptering, etc. Ett annat intressant alternativ är konstruktionen av ett applikationskörningsträd, vilket gör att du snabbt kan förstå den allmänna principen för programmets drift och separat spåra, till exempel bearbetning av användarinmatning. Och även ett specialverktyg erbjuds för att snabbt skapa regler för kodkontroll - Klocwork Checker Studio.

Täckning förhindrar statisk analys

Webbplats: www.coverity.com/products
Licens: Shareware
Plattform: Windows
Språk: C ++, Java, C #

En av de mest kända statiska analysatorerna för C / C ++, Java och C # -kod. Enligt dess skapare används lösningen av mer än 100 000 utvecklare runt om i världen. Sofistikerade mekanismer gör att du kan automatisera sökningen efter minnesläckor, obefångade undantag, prestandaproblem och naturligtvis säkerhetsproblem. Produkten stöder olika plattformar, kompilatorer (gcc, Microsoft Visual C ++ och många andra), och integreras också med olika utvecklingsmiljöer, främst Eclipse och Visual Studio. Kärnan i kodgenomgången är inte dumma traversalgoritmer från början till slut, utan något som en felsökare som analyserar hur programmet kommer att fungera i olika situationer efter att ha stött på en gren. Således uppnås 100% kodtäckning. Ett sådant komplext tillvägagångssätt krävdes bland annat att fullständigt analysera flertrådade applikationer, speciellt optimerade för drift på flerkärniga processorer. Center för integritetsskydd låter dig hitta fel som tävlingsförhållanden (ett designfel i ett multitasking-system, i vilket systemet beror på i vilken ordning delar av koden körs), blockeringar och mycket mer. Varför behöver backarna det? Be 0day-utvecklarna om Firefox och IE :).

OWASP Code Crawler

Webbplats: www.owasp.org
Licens: GNU GPL
Plattform: Windows
Språk: Java, C #, VB

Skaparen av detta verktyg, Alessio Marziali, är författare till två ASP.NET-böcker, en auktoritativ kodare för högbelastningsapplikationer för finanssektorn och en pentester. År 2007 publicerade han information om kritiska sårbarheter på 27 italienska statliga webbplatser. Hans hjärnbarn - OWASP Code Crawler - designad för statisk analys av .NET och J2EE / JAVA-kod, den är tillgänglig på Internet, och i slutet av året lovar författaren att släppa en ny version av programmet med mycket större funktionalitet. Men det viktigaste har redan implementerats - analys av källor i C #, Visual Basic och Java. Filerna som ska skannas väljs via GUI och skanningen startas automatiskt. För varje problematiskt avsnitt i koden visas en beskrivning av sårbarheten i avsnittet Hotbeskrivning. Det är sant att fältet OWASP-riktlinjer, antagligen antyder sätt att lösa problemet, tyvärr, är ännu inte tillgängligt. Istället kan du dra nytta av den experimentella funktionen för skanningskod på en fjärrmaskin, tillgänglig på fliken Fjärrskanning. Författaren lovar att allvarligt förbättra den här funktionen och i synnerhet att samla applikationskällkoder för analys direkt från versionskontrollsystemet.

VARNING

Informationen tillhandahålls endast i informationssyfte och visar framför allt hur utvecklare kan undvika kritiska fel under applikationsutveckling. Varken författaren eller redaktörerna ansvarar för användningen av den kunskap som erhållits för olagliga ändamål.

Att utveckla säkra JavaScript-applikationer är en knepig affär. Men ganska genomförbart. I dagens artikel kommer vi att titta på funktionerna i JavaScript som orsakar säkerhetsproblem och prata om hur du kan undvika dem.

Varför är det svårt att skriva säker JS-kod

Så här är 5 skäl till varför det är svårt att skriva säker kod i JS

Kompilatorn hjälper inte

JavaScript är ett tolkat språk. Det betyder att kompilatorn inte kommer att klaga på något hela tiden, vägrar att arbeta och driver dig för att korrigera fel och optimera din kod.

Dynamisk JavaScript

JavaScript är dynamiskt, svagt skrivet och asynkront. Och allt detta är tecken på att det är lättare att komma i trubbel.

1. Språkverktyg som eval och inklusive tredjepartskod via script src kan linjer köras direkt vid körning. Som en konsekvens är det svårt att ge "statiska garantier" för att koden kommer att fungera på ett visst sätt. Detta komplicerar också dynamisk analys (se vetenskapligt arbete).

Använda eval

2. Svag typning leder till att det inte är lätt att tillämpa etablerade metoder för statisk analys - åtminstone i jämförelse med statiskt skrivna språk (till exempel Java).

3. Asynkrona återuppringningar, som JavaScript tillåter samtal genom mekanismer som setTimeout och XMLHttpRequest (samma berömda AJAX), döljer statistiskt de mest smygande felen.

Intrikata JS-funktioner

Så mycket har dragits till JavaScript genom åren! I synnerhet har den prototyper, förstklassiga funktioner och stängningar. De gör språket ännu mer dynamiskt och svårare att skriva säker kod.

1. Prototyper. Deras betydelse är att program skrivs i en anda av ett objektorienterat tillvägagångssätt, men utan att använda klasser. Med detta tillvägagångssätt ärver föremål de egenskaper de behöver direkt från andra objekt (prototyper). Samtidigt kan prototyper i JS omdefinieras direkt vid körning. Och om den här åsidosättningen händer sprids effekten omedelbart till alla objekt som ärver egenskaperna hos den åsidosatta prototypen.

Hur prototyper bearbetas

För rättvisans skull måste det sägas att de nya ECMAScript-specifikationerna också innehåller klasser.

2. Första klassens funktioner. JS har ett mycket flexibelt objekt och en funktionsmodell. Objektegenskaper och deras värden kan skapas, ändras eller raderas direkt vid körning, och alla är tillgängliga via förstklassiga funktioner.

3. Stängningar. Om du förklarar en funktion i en annan funktion får den första åtkomst till variablerna och argumenten för den sista. Dessutom fortsätter dessa variabler att finnas och förbli tillgängliga för den interna funktionen - även efter att den externa funktionen där dessa variabler definieras har slutförts.

På grund av denna flexibilitet och dynamik i JavaScript (se punkterna 1 och 3) är det en olöslig uppgift att bestämma en uppsättning av alla tillgängliga objektegenskaper i statisk analys. Webbutvecklare använder dock dynamiska funktioner på språket överallt, och följaktligen kan de inte försummas när de analyserar koden. Annars, vad är säkerhetsgarantin?

Nära interaktion mellan JavaScript och DOM

Detta för att ge en sömlös uppdatering av webbsidan, precis vid körning. DOM är känt för att vara en plattformneutral och språkneutral standardobjektmodell för rendering av HTML- och XML-dokument. DOM har sitt eget API för att arbeta med det renderade dokumentet: för att dynamiskt komma åt, flytta och uppdatera det renderade dokumentet (dess innehåll, struktur och stil). Ändringar i DOM kan göras dynamiskt via JavaScript. Och dessa ändringar visas omedelbart i webbläsaren.

Tack vare DOM kan webbsidor som laddas in i webbläsaren uppdateras stegvis när data laddas från servern. Det finns dock en nackdel med denna bekvämlighet: kodavsnitten som ansvarar för dynamisk kommunikation mellan JS och DOM är särskilt felbenägna.

De vanligaste felen i webbapplikationer

Komplexa händelseinteraktioner

JavaScript är ett händelsedrivet språk. Det gör det möjligt för utvecklare att registrera så kallade eventlyssnare på DOM-noder. Även om de flesta händelser utlöses av användaråtgärder finns det några som kan utlösas utan den, till exempel tidshändelser och asynkrona samtal. I det här fallet kan varje händelse upprepas i hela DOM-trädet och aktivera flera "lyssnare" samtidigt. Ibland är att hålla reda på allt detta en ganska icke-trivial uppgift.

Hur händelser hanteras

Av dessa skäl kan JS-kod vara svår att förstå, analysera och testa. Specialverktyg gör livet enklare för en webbutvecklare och hjälper dig att skriva säker kod.

JS-kodtestverktyg

Det finns verktyg för tolkning (t.ex. Esprima, Rhino), optimering (t.ex. Google Closure Compiler) och statisk kodanalys för vanliga syntaxfel (t.ex. JSHint).

Dessutom finns det flera beprövade ramar som hjälper webbutvecklare att täcka JS-kod med tester. Bland dem:

  • QUnit är ett populärt ramverk för enhetstestning;
  • Jasmine - Beteende-driven utveckling (BDD) ram för kodtestning;
  • Mocha är ett kodtestramverk som körs i både Node.js och webbläsaren.
  • jsTestDriver är ett ramverk som bland annat kan köra en uppsättning tester över flera webbläsare samtidigt.

Dessutom finns det testramar som efterliknar webbläsarens beteende och gör att testfall kan köras automatiskt. De är särskilt användbara vid felsökning av kodsektionerna som är ansvariga för interaktionen mellan JS och DOM och ger en bekväm infrastruktur för att manipulera DOM.

Till exempel ger Selenium, PhantomJS och SlimerJS ett API genom vilket du kan starta och arbeta med webbläsarinstanser. Genom API: et kan du utlösa händelser och få åtkomst till DOM-element direkt vid körning - det vill säga testa din kod i förhållanden som är så nära verkliga som möjligt. Naturligtvis måste mycket av arbetet göras manuellt, men även detta är redan en bra hjälp vid testning.

Verktyg för statisk analys

Tidigare var verktyg för att identifiera problematiska kodsnitt statiska analysatorer. Det vill säga, med tanke på alla dynamiska särdrag hos JS, kan endast ge begränsad hjälp. De kan dock också vara användbara vid analys. Här är några grundläggande exempel.

WARI är en statisk analysator som undersöker beroenden mellan JS-funktioner, CSS-stilar, HTML-taggar och bilder. Syftet med detta verktyg är att hitta oanvända resurser under statisk analys. Men dynamiken i WARI klarar naturligtvis inte.

JSLint är ett statiskt kodanalysverktyg skrivet i själva JavaScript. Den kontrollerar koden mot god praxis.

Google Closure Compiler är en JS-optimerare som automatiskt skriver om koden för att göra den snabbare och mer kompakt. Samtidigt flyger alla kommentarer och eventuella oanvända kodfragment in i röret.

WebScent (se vetenskapligt arbete) är en avancerad statisk analysator. I sitt arbete utgår han från det faktum att klientens JS-kod (den som laddas in i webbläsaren) inte lagras på serversidan som helhet utan är spridd över hela serverkoden i bitar. "Lukten" i dessa bitar kan inte lätt detekteras förrän en fullständig klientkod genereras från dem. WebScent analyserar klientkoden för att hitta problemområden i serverkoden. Samtidigt går arbetet med den statiska analysatorn WebScent i grund och botten ner på att lösa upp blandningar av HTML, CSS och JS - för att upptäcka duplicerad kod och fel i HTML-syntax.

Dynamiska analysverktyg

JSNose är ett verktyg som kombinerar statisk och dynamisk analys. Den analyserar koden för tretton antimönster. Sju av dem (inklusive lat objekt och lång funktion) är gemensamma för alla programmeringsspråk, och sex andra (stängningslukt, överdrivna globala variabler, kapslade återuppringningar och andra) är JavaScript-specifika.

DOMPletion är ett automatiserat verktyg som hjälper en webbutvecklare att förstå koden när den visas: förklarar varför DOM-strukturer finns, utför dynamisk analys och ger också en smart autofullständighet för kod som interagerar med DOM.

Clematis är ett ramverk som hjälper till att lösa komplexa händelseinteraktioner. Clematis fångar i detalj alla händelser som utlöses under utförandet och visualiserar dem i form av en abstrakt beteendemodell, som återspeglar de temporala och kausala förhållandena mellan komponenter och händelser.

Slutsatser

Så det kan vara svårt att spåra vad som händer när man kör skript i JS, men beväpnad med rätt verktyg kan du hitta och skriva om problemområden även i den mest förvirrande koden. JavaScript står dock inte stilla: nya och nya möjligheter förekommer i den, nu används den ofta för att skriva applikationer (både mobil och stationär) och finns också alltmer på servrar (och inte bara) tack vare Node.js. Detta innebär att konsten att fånga buggar måste tas till en ny nivå.

Och en lärare i Netology, skrev en serie artiklar till bloggen om EcmaScript6. I den första delen, med exempel, kommer vi att överväga dynamisk kodanalys i EcmaScript med Iroh.js.

Statisk och dynamisk kodanalys

Kodanalysverktyg är ett användbart verktyg för att upptäcka och upptäcka fel och särdrag i kodens arbete. Kodanalys kan vara statisk och dynamisk. I det första fallet analyseras källkoden och analyseras utan att den körs, i det andra sker körningen i en kontrollerad sandboxmiljö som ger metainformation om programmets element under dess körning.

Slutsatser

Iroh.js är ett kraftfullt och funktionellt verktyg för dynamisk kodanalys i EcmaScript. Det här verktyget kan användas både för kodanalys, inklusive att bygga ett samtalsdiagram, visa faktiska typer och värden i variabler och objekt, och för kodändring i farten, inklusive kodfixar baserat på händelser.

Dynamisk analys är en ganska komplex metod, men för EcmaScript, med tanke på ankartypning, närvaron av värdobjekt och inbyggda funktioner som gör att du kan ändra beteendet hos koden i farten, är detta det enda sättet att analysera och felsöka koden vid körning. Iroh.js kan också använda kod för att skapa funktionstester utan att behöva ändra den för att exportera värden.

ALEXANDER MAYOROV, programmerare, 11 års erfarenhet av programmering, varav sju ägnas åt utveckling för mobila enheter

Statisk typanalys i JavaScript
Försöker Facebook Flow Analyzer

Facebook har introducerat ett nytt open source-projekt Flow - en statisk kodanalysator för JavaScript. Huvudsyftet med analysatorn är att förenkla sökningen efter fel

Dessutom tillhandahåller Flow ett TypeScript-syntaktiskt JavaScript-tillägg för att specifikt specificera typer. Många av de nya funktionerna i ECMAScript 6-specifikationen stöds.

Ämnet att skriva i programmeringsspråk berörs ofta. Detta är föremål för holivars och bestämmer det positiva eller negativa drag hos ett visst språk. Det har varit en hel del prat på senare tid om att skriva in JavaScript. Någon gillar det som det är. Människor som är bekanta med andra programmeringsspråk, särskilt de med starkt uttryckligt skrivande, anser att detta tillvägagångssätt är "en granat i en apas händer." Vi vet alla att JavaScript är ett löst dynamiskt skrivet språk. Front-end utvecklingsguruer har lärt sig hur man använder detta till sin fördel, men koden är ibland för tung för att förstå. De som bara kommer till JavaScript-programmeringsvärlden är förvirrade av den magi som tolkarna gör och fångar ofta fel ur det blå. Men först, låt oss gräva lite om att skriva i allmänhet. Hur är det?

Skriva i programmeringsspråk

Genom att skriva är programmeringsspråk uppdelade i två stora läger - skrivna och otypade. Till exempel inkluderar skrivade språk C, Python, PHP, Lua, JavaScript. Exempel på otypade språk: assembler, Forth, Brainfuck. Ja Ja exakt. JavaScript, som många andra tolkade språk, skrivs. Säg därför inte i något fall att det är otypat. Särskilt i jobbintervjuer.

I sin tur är typade språk uppdelade i flera överlappande kategorier:

  • Statiskt eller dynamiskt skrivet.
  • Stark eller löst skriven.
  • Explicit eller implicit skrivning.

Statiskt skrivna språk

Med statisk skrivning ställs de slutliga typerna av variabler och funktioner in vid sammanställningstid. Kompilatorn korrigerar dina typavvikelser även innan programmet startar. Exempel på språk: C, Java, C #.

Dynamiskt skrivna språk

I dynamisk typning hittar du alla typer vid körning. Och om du gör ett misstag kommer du bara att veta om det när du kör programmet. Därför, när du skriver dynamiskt, är det mycket viktigt att ägna särskild uppmärksamhet åt att kontrollera och fånga fel. Exempel på språk: JavaScript, PHP, Python, Ruby.

Stark typning (stark)

Starkt skrivna språk tillåter inte blandning av olika typer i uttryck och kommer inte att utföra automatiska implicita konverteringar. Du kan till exempel inte subtrahera ett tal eller någon annan typ än sträng från en sträng. Exempel på språk: Java, Python, Haskell, Lisp.

Lax typing (svag)

Löst skrivna språk utför många implicita konverteringar automatiskt. De gör detta även om förlust av precision eller omvandling kan inträffa, tvetydigt. Exempel på språk: PHP, JavaScript, Visual Basic.

Explicit skrivning

I uttryckligen skrivna språk måste typen av nya variabler / funktioner och argument anges specifikt. Exempel på språk: C ++, D, C #.

Implicit skrivning

På språk med implicit typning överlämnas uppgiften att specificera typer till kompilatorn / tolken. Exempel på språk: JavaScript, PHP, Lua. På sådana språk har objekt som regel speciella metoder som kallas på att gjutas till en typ. Till exempel har PHP en _toString () -metod och JavaScript har en metod med samma namn, men utan understrykning, toString (). Dessa metoder kallas när du kastar ett objekt till en strängtyp. Ibland kallas sådana metoder för magi (alla implicita processer är alltid magiska).

Det är viktigt att notera att alla dessa kategorier överlappar varandra. Baserat på dessa kategorier finner vi att JavaScript typiskt är implicit skrivet. Och om vi talar överdrivet kan språkets natur beskrivas på följande sätt: i alla obegripliga situationer, ta allt till primitiva, främst till en linje. Även om allt i verkligheten är lite mer komplicerat kommer vi inte att gå in på detaljer nu.

"Varför behöver vi skriva?" - kan du fråga. JavaScript har levt bra utan det i 20 år. Svaret är enkelt: JavaScript har aldrig använts för att lösa komplexa företagsnivåproblem. Nu har detta språk gått bortom webbläsaren och gått in i backend-territoriet. När du skriver en stor applikation blir det svårt att fånga fel som ofta är förknippade med typgjutning.

JavaScript-tillägg

Eftersom JavaScript körs på klientsidan (i webbläsare) är ett av alternativen för att lösa problemet att skapa ett språk - en dialekt som kommer att sammanställas till JS. Han fungerar som en monterare.

Språk som TypeScript, Dart, AtScript har dykt upp som lägger till statisk stark skrivning och till och med runtime-typkontroll (även om detta lägger till overhead). Alla dessa språk lägger inte bara till typer, de lägger till antingen syntaktiskt socker eller till och med sin egen VM-implementering, vilket är skrivet i JS.

Läs hela artikeln i tidskriften "Systemadministratör", nr 1-2 för 2015, på sidorna 86-88.

En PDF-version av detta nummer kan köpas i vår butik.

  1. Flow-webbplatsen är http://flowtype.org.

I kontakt med

Inte varje rad i min kod är perfekt första gången. I vissa fall ... Ibland ... Okej - nästan aldrig. Sanningen är att jag spenderar betydligt mer tid på att korrigera mina dumma misstag än jag skulle vilja. Det är därför jag använder statiska analysatorer i nästan alla JavaScript-filer jag skriver.

Statiska analysatorer tittar på koden och hittar fel i den innan du kör den. De utför enkla kontroller, till exempel genomdrivning av syntaxkontroll (till exempel flikar istället för mellanslag) och mer globala kontroller, till exempel kontroll av att funktioner inte är för komplexa. Statiska analysatorer letar också efter buggar som inte kan hittas under testning, till exempel \u003d\u003d istället för \u003d\u003d\u003d.

I stora projekt och när du arbetar i stora team kan du använda lite hjälp för att hitta sådana "enkla" buggar som faktiskt inte är så enkla som de verkar.

JSLint, JSHint och Closure Compiler

Det finns tre huvudalternativ för statiska analysatorer för JavaScript: JSLint, JSHint och Closure Compiler.

JSLint var den första statiska analysatorn för JavaScript. Det kan köras på den officiella webbplatsen, eller så kan du använda ett av tilläggen som kan köras på lokala filer. JSLint hittar många viktiga buggar, men det är väldigt tufft. Här är ett bra exempel:

Var s \u003d "mystring"; för (var i \u003d 0; i< s.length; i++) { console.log(s.charAt(i)); }

JSLint visar två fel i den här koden:

Oväntat "++". Flytta "var" -deklarationer till toppen av funktionen.

Det första problemet är definitionen av variabeln i slingförhållandena. JSLint accepterar inte heller ++ -operatören i slutet av loopdefinitionen. Han vill att koden ska se ut så här:

Var s \u003d "mystring"; var i; för (i \u003d 0; i< s.length; i = i + 1) { console.log(s.charAt(i)); }

Jag uppskattar skaparna av JSLint, men för mig är det överdrivet. Det visade sig vara tufft för Anton Kovalev också, så han skapade JSHint.

JSHint fungerar på samma sätt som JSLint, men den skrivs utöver Node.js och är därför mer flexibel. JSHint innehåller ett stort antal alternativ, så att du kan utföra anpassade kontroller genom att skriva din egen rapportgenerator.
Du kan köra JSHint från webbplatsen, men i de flesta fall är det bättre att installera JSHint som ett lokalt kommandoradsverktyg med Node.js. När du har installerat JSHint kan du köra den på dina filer med det här kommandot:

Jshint test.js

JSHint innehåller också plugins för populära textredigerare, så att du kan köra den medan du skriver din kod.

STÄNGNINGSKOMPILATOR

Googles Closure Compiler är en helt annan typ av program. Som namnet antyder är det inte bara ett testprogram utan också en kompilator. Den är skriven på Java och är baserad på Mozillas Rhino parser. Stängningskompilatorn innehåller ett enkelt läge för att göra grundläggande kodkontroll och mer avancerade lägen för att göra ytterligare kontroll och genomdriva specifika vydefinitioner.

The Closure Compiler rapporterar fel i JavaScript-kod, men genererar också minifierade versioner av JavaScript. Kompilatorn tar bort vita utrymmen, kommentarer och oanvända variabler och förenklar långa uttryck för att hålla skriptet så kompakt som möjligt.

Google har gjort en mycket grundläggande version av kompilatorn tillgänglig på nätet, men chansen är att du vill ladda ner Closure Compiler och köra den lokalt.

Stängningskompilatorn, efter att ha kontrollerat koden, matar ut en lista med filer i en minifierad fil. Så du kan köra den genom att ladda ner filen compiler.jar.

Java -jar compiler.jar --js_output_file compress.js --js test1.js --js test2.js

Välja rätt verifieringsprogram

I mina projekt kombinerar jag Closure Compiler och JSHint. Closure Compiler utför minifiering och grundläggande validering, medan JSHint gör mer komplex kodanalys. Dessa två program fungerar bra tillsammans, och vart och ett av dem täcker områden som det andra inte kan. Dessutom kan jag använda JSHint-tillägget för att skriva anpassade validerare. Ett allmänt program jag skrev testar vissa funktioner som jag inte behöver, till exempel att ringa funktioner som inte borde finnas i mitt projekt.

Nu när vi har täckt några testprogram, låt oss bryta ner en del av den dåliga koden. Var och en av dessa sex exempel är kod som inte är värt att skriva och situationer där kodkontrollprogram kan spara dig.

Den här artikeln använder JSHint för de flesta exemplen, men Closure Compiler genererar vanligtvis liknande varningar.

\u003d\u003d eller \u003d\u003d\u003d?

JavaScript är ett dynamiskt skrivet språk. Du behöver inte definiera typer när du skriver din kod, och de finns vid start.

JavaScript erbjuder två jämförelseoperatörer för att manipulera sådana dynamiska typer: \u003d\u003d och \u003d\u003d\u003d. Låt oss titta på detta med ett exempel.

Var n \u003d 123; var s \u003d "123"; if (n \u003d\u003d s) (alert ("Variablerna är lika");) if (n \u003d\u003d\u003d s) (alert ("Variablerna är identiska");)

Jämförelseoperatör == är rester av C-språket som JavaScript har sina rötter i. Användningen är nästan alltid ett misstag: att jämföra värden separat från typer är sällan något som en utvecklare faktiskt vill göra. Faktum är att talet "hundra tjugotre" skiljer sig från strängen "en två tre". Dessa operatörer är enkla att stava fel och ännu enklare att läsa fel. Kontrollera den här koden med JSHint så får du den här:

Test.js: rad 9, kol 12, Förväntat "\u003d\u003d\u003d" och såg istället "\u003d\u003d".

Odefinierade variabler och sena definitioner

Låt oss börja med en enkel kod:

Funktionstest () (var myVar \u003d "Hello, World"; console.log (myvar);)

Ser du felet? Jag gör detta misstag varje gång. Kör den här koden och du får felet:

ReferenceError: myvar är inte definierad

Låt oss göra problemet lite mer komplicerat:

Funktionstest () (myVar \u003d "Hello, World"; console.log (myVar);)

Kör den här koden så får du den här:

Hej världen

Det andra exemplet fungerar, men det har mycket oväntade biverkningar. Reglerna för att definiera JavaScript-variabler och omfattning är i bästa fall förvirrande. I det första fallet kommer JSHint att rapportera följande:

Test.js: rad 3, kol 17, "myvar" definieras inte.

I det andra fallet kommer han att rapportera detta:

Test.js: rad 2, kol 5, "myVar" definieras inte. test.js: rad 3, kol 17, "myVar" definieras inte.

Det första exemplet hjälper dig att undvika ett runtime-fel. Du behöver inte testa din ansökan - JSHint hittar felet åt dig. Det andra exemplet är värre eftersom du inte hittar ett fel som ett resultat av testningen.

Problemet i det andra exemplet är snyggt subtilt och komplext. Variabeln myVar har nu försvunnit från sitt omfång och flyttat upp till det globala omfånget. Det betyder att det kommer att finnas och ha värdet Hello, World även efter att testfunktionen har körts. Detta kallas global förorening.

Variabeln myVar finns för alla andra funktioner som körs efter testfunktionen. Kör följande kod efter att testfunktionen har körts:

Console.log ("myVar:" + myVar);

Du kommer fortfarande få Hello, World. Variabeln myVar kommer att hänga genom hela din kod som en mall, vilket leder till komplexa buggar som du kommer att söka hela natten före släppet, allt för att du glömde att skriva var.







2020 gtavrl.ru.