DLint: Dynamically Checking Bad Coding Practices in JavaScript

Similar documents
DLint: Dynamically Checking Bad Coding Practices in JavaScript

DLint and JITProf. [FSE 15] JITProf: Pinpointing JIT-unfriendly JavaScript code Liang Gong, Michael Pradel, Koushik Sen

DLint: Dynamically Checking Bad Coding Practices in JavaScript

DLint: Dynamically Checking Bad Coding Practices in JavaScript

JITProf: Pinpointing JIT-Unfriendly JavaScript Code

TypeDevil: Dynamic Type Inconsistency Analysis for JavaScript

Understanding and Automatically Preventing Injection Attacks on Node.js

JavaScript: Coercion, Functions, Arrays

INF5750. Introduction to JavaScript and Node.js

JAVASCRIPT AND JQUERY: AN INTRODUCTION (WEB PROGRAMMING, X452.1)

JAVASCRIPT AND JQUERY: AN INTRODUCTION (WEB PROGRAMMING, X452.1)

JavaScript Programming

ADsafety. Type-based Verification of JavaScript Sandboxing. Joe Gibbs Politz Spiridon Aristides Eliopoulos Arjun Guha Shriram Krishnamurthi

The course is supplemented by numerous hands-on labs that help attendees reinforce their theoretical knowledge of the learned material.

The Good, the Bad, and the Ugly: An Empirical Study of Implicit Type Conversions in JavaScript

Introduction to JavaScript p. 1 JavaScript Myths p. 2 Versions of JavaScript p. 2 Client-Side JavaScript p. 3 JavaScript in Other Contexts p.

Synode: Understanding and Automatically Preventing Injection Attacks on Node.js

Principles of Programming Languages

The Typed Racket Guide

JavaScript CS 4640 Programming Languages for Web Applications

Client-Side Web Technologies. JavaScript Part I

Typed Racket: Racket with Static Types

JavaScript: Features, Trends, and Static Analysis

6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

JavaScript CS 4640 Programming Languages for Web Applications

[ANALYSIS ASSIGNMENT 10]

Operators and Expressions

Run-time characteristics of JavaScript

CSE 341, Spring 2011, Final Examination 9 June Please do not turn the page until everyone is ready.

JavaScript: the language of browser interactions. Claudia Hauff TI1506: Web and Database Technology

Javascript Arrays, Object & Functions

Interprocedural Type Specialization of JavaScript Programs Without Type Analysis

Chapter 2 Working with Data Types and Operators

Why Discuss JavaScript? CS312: Programming Languages. Lecture 21: JavaScript. JavaScript Target. What s a Scripting Language?

CS312: Programming Languages. Lecture 21: JavaScript

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Powerful JavaScript OOP concept here and now. CoffeeScript, TypeScript, etc

JavaScript: Sort of a Big Deal,

Refinement Types for TypeScript

Sprite an animation manipulation language Language Reference Manual

Static Analysis of JavaScript. Ben Hardekopf

LECTURE 16. Functional Programming

CalFuzzer: An Extensible Active Testing Framework for Concurrent Programs Pallavi Joshi 1, Mayur Naik 2, Chang-Seo Park 1, and Koushik Sen 1

Program Testing and Analysis: Manual Testing Prof. Dr. Michael Pradel Software Lab, TU Darmstadt

An Actionable Performance Profiler for Optimizing the Order of Evaluations

6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

Web Application Development

Node.js Training JavaScript. Richard richardrodger.com

JavaScript Lecture 1

Ruby: Introduction, Basics

Semantic Atomicity for Multithreaded Programs!

JavaScript: the Big Picture

CS 112 Introduction to Computing II. Wayne Snyder Computer Science Department Boston University

Using Jalangi for Automatic Error Detection in JavaScript Games

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

Thrift specification - Remote Procedure Call

Getting started with Java

Perl Library Functions

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

CMPT 125: Lecture 3 Data and Expressions

Client vs Server Scripting

JavaScript Syntax. Web Authoring and Design. Benjamin Kenwright

Produced by. App Development & Modelling. BSc in Applied Computing. Eamonn de Leastar

Language Based isolation of Untrusted JavaScript

JavaScript Errors in the Wild: An Empirical Study

JavaScript for PHP Developers

JavaScript. Training Offer for JavaScript Introduction JavaScript. JavaScript Objects

A Structural Operational Semantics for JavaScript

JavaScript: The Good Parts. Douglas Crockford Yahoo! Inc.

Recap: Functions as first-class values

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Lexical Considerations

Functional Programming. Pure Functional Programming

PIC 20A Inheritance, Interface, and Polymorphism

Marija Selakovic September 25th, 2015 JSConf, Berlin

Princess Nourah bint Abdulrahman University. Computer Sciences Department

Principles of Programming Languages

COMP520 - GoLite Type Checking Specification

JavaScript Basics. Mendel Rosenblum. CS142 Lecture Notes - JavaScript Basics

JAVASCRIPT AND JQUERY: AN INTRODUCTION (WEB PROGRAMMING, X452.1)

1 Introduction. 3 Syntax

JavaScript Programming

Magento Technical Guidelines

Nomen est Omen: Exploring and Exploiting Name Similarities between Arguments and Parameters

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

CS1520 Recitation Week 2

News. CSE 130: Programming Languages. Environments & Closures. Functions are first-class values. Recap: Functions as first-class values

JavaScript. History. Adding JavaScript to a page. CS144: Web Applications

CS558 Programming Languages

Web Physics: A Hardware Accelerated Physics Engine for Web- Based Applications

Lexical Considerations

Mutable References. Chapter 1

JavaScript. History. Adding JavaScript to a page. CS144: Web Applications

Hava Language Technical Reference

DaMPL. Language Reference Manual. Henrique Grando

Metaprogramming assignment 3

Transparent Object Proxies for JavaScript

Expressions and Assignment

ActionScript Coding Standards. by Michael Williams

Principles of Programming Languages

Transcription:

DLint: Dynamically Checking Bad Coding Practices in JavaScript Liang Gong 1, Michael Pradel 2, Manu Sridharan 3 and Koushik Sen 1 1 UC Berkeley 2 TU Darmstadt 3 Samsung Research America

Why JavaScript? The RedMonk Programming Language Rankings (1 st ) Based on GitHub and StackOverflow Web assembly language Web applications, DSL, Desktop App, Mobile App 2

Problematic JavaScript Designed and Implemented in 10 days Not all decisions were well thought Problematic language features Error prone Inefficient code Security loophole Problematic features are retained backward compatibility 3

4 Problematic JavaScript

What is coding practice? Good coding practices informal rules improve quality Better quality means: Less correctness issues Better performance Better usability Better maintainability Less security loopholes Less surprises 5

Rule: avoid using for..in over arrays var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum? 6

Rule: avoid using for..in over arrays var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum? 11 + 22 + 33 => 66 array index (not array value) 0 + 1 + 2 => 3 array index : string 0+"0"+"1"+"2" => "0012" 7

Rule: avoid using for..in over arrays var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum? 11 + 22 + 33 => 66 array index (not array value) 0 + 1 + 2 => 3 array index : string 0+"0"+"1"+"2" => "0012" 8 Cross-browser issues Result depends on the Array prototype object > "0012indexOftoString..."

Rule: avoid using for..in over arrays var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum? for (i=0; i < array.length; i++) { sum += array[i]; } 9 function addup(element, index, array) { sum += element; } array.foreach(addup);

Rule: avoid using for..in over arrays var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum? for (i=0; i < array.length; i++) { sum += array[i]; } 10 function addup(element, index, array) { sum += element; } array.foreach(addup);

Coding Practices and Lint Tools Existing Lint-like checkers Inspect source code Rule-based checking Detect common mistakes Enforce coding conventions Limitations: Approximates behavior Unknown aliases Lint tools favor precision over soundness Difficulty: Precise static program analysis 11

DLint Dynamic Linter checking code quality rules for JS Open-source, robust and extensible framework Formalized and implemented 28 rules Counterparts of static rules Additional rules Empirical study Compare static and dynamic checking 12

Jalangi: A Dynamic Analysis Framework for JavaScript Koushik Sen, Swaroop Kalasapur, Tasneem Brutch, and Simon Gibbs a.f = b.g PutField(Read("a", a), "f", GetField(Read("b", b), "g")) if (a.f())... if (Branch(Method(Read("a", a), "f")())... x = y + 1 x = Write("x", Binary( +,Read("y", y), Literal(1)) analysis.literal(c) analysis.branch(c) analysis.read(n, x) analysis.write(n, x) analysis.putfield(b, f, v) analysis.binary(op, x, y) analysis.function(f, isconstructor) analysis.getfield(b,f) analysis.method(b, f, isconstructor) analysis.unary(op, x)... 13

Runtime Patterns Single-event: Stateless checking Multi-event: Stateful checking 14

Language Misuse Avoid setting properties of primitives, which has no effect. var fact = 42; fact.istheanswer = true; console.log(fact.istheanswer); > undefined DLint Checker Predicate: propwrite(base,*,*) Λ isprim(base) 15

Avoid producing NaN (Not a Number). var x = 23 "five"; > NaN Uncommon Values DLint Checker Predicate: unop(*, val, NaN) Λ val NaN binop(*, left, right, NaN) Λ left NaN Λ right NaN call(*, *, args,nan, *) Λ NaN args 16

Uncommon Values Avoid concatenating undefined to string. var value;... var str = "price: ";... var result = str + value; > "price: undefined" 17 DLint Checker Predicate: binop(+, left, right, res) Λ (left = undefined right = undefined) Λ isstring(res)

Beware that all wrapped primitives coerce to true. var b = false; if (new Boolean(b)) { console.log("true"); } > true API Misuse DLint Checker Predicate: cond(val) Λ iswrappedboolean(val) Λ val.valueof() = false 18

19

20

21

DLint Overview JS program Jalangi Instrumented JS program DLint Checkers Behavior Information Final Report Instrument SpiderMonkey to intercept JavaScript files Transpile JavaScript code with Jalangi [Sen et al. FSE 2013] DLint checks runtime states and find issues Report reason and code location 22

Evaluation Research Questions DLint warning vs. JSHint warning? Additional warnings from DLint? Coding convention vs. page popularity? Experimental Setup 200 web sites (top 50 + others) Comparison to JSHint 23

% of Warnings: DLint vs. JSHint JSHint Unique Common DLint Unique Websites 24 0% 20% 40% 60% 80% 100% % of warnings on each site Some sites: One approach finds all Most sites: Better together

Additional Warnings Reported by DLint Logarithmic average. # warning / site (base 2) 84 43 2 1 0 Checker shares warning with JSHint Checker shares no warnings with JSHint I5 T6 L3 T5 A2 V2 L4 A5 T1 L2 L1 A6 A8 A3 T2 A4 I1 I4 V3 L5 I2 T4 L6 A7 T3 DLint checkers 53 warnings per page 49 are missed by JSHint 25

Coding Convention vs. Page Popularity Quartile 1-3 Quartile 1-3 # JSHint Warning / LOC 0.16 0.14 0.12 0.1 0.08 0.06 0.04 0.02 0 Mean # DLint Warn. / #Cov. Op. 0.02 0.0175 0.015 0.0125 0.01 0.0075 0.005 0.0025 0 Mean Websites traffic ranking Websites traffic ranking 26 Correlation between Alexa popularity and number of DLint warnings: 0.6

27 Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley.

28 Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley.

29

30 Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley.

Rule: avoid setting field on primitive values From Google Octane Game Boy Emulator benchmark: var decode64 = ""; if (datalength > 3 && datalength % 4 == 0) { while (index < datalength) { decode64 += String.fromCharCode(...); } if (sixbits[3] >= 0x40) { decode64.length -= 1; } } 31

Rule: avoid setting field on primitive values From Google Octane Game Boy Emulator benchmark: var decode64 = ""; if (datalength > 3 && datalength % 4 == 0) { while (index < datalength) { decode64 += String.fromCharCode(...); } if (sixbits[3] >= 0x40) { decode64.length -= 1; } } No effect because decode64 is a primitive string. 32

Rule: avoid no effect operations window.onbeforeunload= "Twitch.player.getPlayer().pauseVideo();" window.onunload= "Twitch.player.getPlayer().pauseVideo();" 33

Rule: avoid no effect operations window.onbeforeunload= "Twitch.player.getPlayer().pauseVideo();" window.onunload= "Twitch.player.getPlayer().pauseVideo();" window.onbeforeunload = function () { Twitch.player.getPlayer().pauseVideo(); } 34

Takeaways Dynamic lint-like checking for JavaScript Static checkers are not sufficient, DLint complements DLint is a open-source, robust and extensible tool Works on real-world websites Found 19 clear bugs on most popular websites More information: Paper: DLint: Dynamically Checking Bad Coding Practices in JavaScript Source Code: https://github.com/berkeley-correctness-group/dlint Google DLint Berkeley 35

Takeaways Dynamic lint-like checking for JavaScript Static checkers are not sufficient, DLint complements DLint is a open-source, robust and extensible tool Works on real-world websites Found 19 clear bugs on most popular websites More information: Paper: DLint: Dynamically Checking Bad Coding Practices in JavaScript Source Code: https://github.com/berkeley-correctness-group/dlint Google DLint Berkeley Thanks! 36

Formalization: declarative specification 1. Predicates over runtime events propwrite(base, name, val) propread(base, name, val) cond(val) unop(op, val, res) binop(op, left, right, res) call(base, f, args, ret, isconstr) Example: propwrite(*, "myobject", val) isprim(val) 37

Missing 'new' prefix when invoking a constructor. eval can be harmful. Implied eval (string instead of function as argument). Do not override built-in variables. document.write can be a form of eval. The array literal notation [] is preferable. The object literal notation {} is preferable. The Function constructor is a form of eval. Do not use Number, Boolean, String as a constructor. 74 4933 2335 202 62 1401 416 191 359 79 8 26 15 6 167 125 62 205 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% Fount by JSHint Only Common with DLint 38

A8 L4 A1 L1 T5 ConstructorFunctions ArgumentsVariable DoubleEvaluation Literals WrappedPrimitives 181 77 31 833 74 413 187 79 8 6 Found by Dlint Only 0% 20% 40% 60% 80% 100% Common with JSHint E.g., 181 calls of eval(), Function(), etc. missed by JSHint 39

40 Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley.

41 Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley.

42

43

NaN case study for IKEA <prices> <normal> <pricenormal unformatted="9.9">$9.90</pricenormal> <priceprevious /> <pricenormalperunit /> <pricepreviousperunit /> </normal> </prices> XML: Empty Element previousprice = JS: undefined getelementvalue("priceprevious" + suffix, normal); parsefloat(previousprice).tofixed(2).replace(...).replace('.00', '')); JS: NaN 44

Type Related Checker Avoid accessing the undefined property. var x; // undefined var y = {}; y[x] = 23; // { undefined: 23 } propwrite(*, "undefined",*) propread(*, "undefined", *) 45

a.f = b.g Chained Analysis PutField(Read("a", a), "f", GetField(Read("b", b), "g")) Chained Analysis functions PutField Read Checker-1 functions PutField Read Checker-2 functions PutField Read Checker-n functions PutField Read 46

Rule: avoid using for..in on arrays www.google.com/chrome, included code from Modernizr: for (i in props) { // props is an array prop = props[i]; before = mstyle.style[prop];... } https://github.com/modernizr/modernizr/pull/1419 47

API Misuse eval is evil, do not use eval. var fun = eval;... fun("var a = 1;"); 48 call(builtin, eval,,, ) call(builtin, Function,,, ) call(builtin, settimeout, args,, ) isstring(args[0]) call(builtin, setinterval, args,, ) isstring(args[0]) call(document, write,,, )

49