Abstract
Static analysis is a tried-and-tested approach to eliminate vulnerabilities in software. However, despite decades of successful use by experts, mainstream programmers often deem static analysis too costly to use. Mainstream programmers do routinely use linters, which are static analysis tools geared towards identifying simple bugs and stylistic issues in software. Can linters serve as a medium for delivering vulnerability detection to mainstream programmers?
We investigate the extent of which linters can be leveraged to help programmers write secure software. We present new rules for ESLint that detect—and automatically fix—certain classes of cross-site scripting, SQL injection, and misconfiguration vulnerabilities in JavaScript. Evaluating our experience, we find that there is enormous potential in using linters to eliminate vulnerabilities in software, due to the relative ease with which linter rules can be implemented and shared to the community. We identify several open challenges, including third-party library dependencies and linter configuration, and propose ways to address them.
Access this chapter
Tax calculation will be finalised at checkout
Purchases are for personal use only
Similar content being viewed by others
Notes
- 1.
ESLint no longer accepts new rules into the core rule set, as of 2020.
- 2.
This is a slightly simplified version of the original, from ESLint core.
- 3.
Rules are not strictly required to follow this format; some deviate from it.
References
Cpplint (2009). https://github.com/cpplint/cpplint/
Spotbugs (2017). https://spotbugs.github.io/
Gosec - golang security checker (2018). https://github.com/securego/gosec
Bandit (2019). https://github.com/PyCQA/bandit
Arteau, P.: Find security bugs (2012). https://find-sec-bugs.github.io
Ayewah, N., Hovemeyer, D., Morgenthaler, J.D., Penix, J., Pugh, W.: Using static analysis to find bugs. IEEE Softw. 25(5), 22–29 (2008)
Ball, T., et al.: Thorough static analysis of device drivers. In: Proceedings of the 2006 EuroSys Conference, Leuven, Belgium, 18–21 April 2006, pp. 73–85. ACM (2006)
Bessey, A., et al.: A few billion lines of code later: using static analysis to find bugs in the real world. Commun. ACM 53(2), 66–75 (2010)
Brat, G., Klemm, R.: Static analysis of the mars exploration rover flight software. In: Proceedings of the First International Space Mission Challenges for Information Technology, pp. 321–326 (2003)
Calcagno, C., Distefano, D., O’Hearn, P.W., Yang, H.: Compositional shape analysis by means of bi-abduction. In: Proceedings of the 36th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL 2009, Savannah, GA, USA, 21–23 January 2009, pp. 289–300. ACM (2009)
Chess, B., McGraw, G.: Static analysis for security. IEEE Secur. Priv. 2(6), 76–79 (2004)
Crockford, D.: Jslint (2002). https://www.jslint.com/
Ernst, M.D.: Invited talk: static and dynamic analysis: synergy and duality. In: Proceedings of the 2004 ACM SIGPLAN-SIGSOFT Workshop on Program Analysis For Software Tools and Engineering, PASTE 2004, Washington, DC, USA, 7–8 June 2004, p. 35. ACM (2004)
Evans, D., Larochelle, D.: Improving security using extensible lightweight static analysis. IEEE Softw. 19(1), 42–51 (2002)
Feldman, M.B.: Who’s using ADA? real-world projects powered by the ADA programming language, November 2014 (2014). https://www2.seas.gwu.edu/~mfeldman/ada-project-summary.html
Guarnieri, S., Livshits, V.B.: GATEKEEPER: mostly static enforcement of security and reliability policies for JavaScript code. In: 18th USENIX Security Symposium, Montreal, Canada, 10–14 August 2009, Proceedings, pp. 151–168. USENIX Association (2009)
Guarnieri, S., Pistoia, M., Tripp, O., Dolby, J., Teilhet, S., Berg, R.: Saving the world wide web from vulnerable JavaScript. In: Proceedings of the 20th International Symposium on Software Testing and Analysis, ISSTA 2011, Toronto, ON, Canada, 17–21 July 2011, pp. 177–187. ACM (2011)
Guha, A., Saftoiu, C., Krishnamurthi, S.: The essence of JavaScript. In: D’Hondt T. (ed.) ECOOP 2010 - Object-Oriented Programming, 24th European Conference, Maribor, Slovenia, 21–25 June 2010. Proceedings. LNCS, vol. 6183, pp. 126–150. Springer, Heidelberg (2010). https://doi.org/10.1007/978-3-642-14107-2_7
Hahn, E.: Helmet (2012). https://helmetjs.github.io/
Henry, J.: Typescript eslint parser (2019). https://www.npmjs.com/package/@typescript-eslint/parser
Inc., F.: React (2013). https://reactjs.org/
Johnson, B., Song, Y., Murphy-Hill, E.R., Bowdidge, R.W.: Why don’t software developers use static analysis tools to find bugs? In: 35th International Conference on Software Engineering, ICSE 2013, San Francisco, CA, USA, 18–26 May 2013, pp. 672–681. IEEE Computer Society (2013)
Johnson, P.: 11 software bugs that took way too long to meet their maker (2015). CSO, From IDG Communications. https://www.csoonline.com/article/3404334/11-software-bugs-that-took-way-too-long-to-meet-their-maker.html
Johnson, S.C.: Lint, A C Program Checker. Bell Telephone Laboratories, New Providence (1977)
Kaur, A., Nayyar, R.: A comparative study of static code analysis tools for vulnerability detection in C/C++ and Java source code. Proc. Comput. Sci. 171, 2023–2029 (2020)
Keinänen, M.: Creation of a web service using the MERN stack (2018)
Kovalyov, A.: Jshint (2011). https://www.jshint.com/. Accessed 25 Jun 2020
Meyerovich, L.A., Livshits, V.B.: Conscript: specifying and enforcing fine-grained security policies for JavaScript in the browser. In: 31st IEEE Symposium on Security and Privacy, S&P 2010, 16–19 May 2010, Berleley/Oakland, California, USA, pp. 481–496. IEEE Computer Society (2010)
Mitchell, J.C.: Programming language methods in computer security. In: Proceedings of the 28th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, POPL 2001, London, UK, 17–19 January 2001. ACM (2001)
OWASP Foundation: OWASP Top Ten (2017)
OWASP Foundation: source code analysis tools (2020). https://owasp.org/www-community/Source_Code_Analysis_Tools
Rice, H.G.: Classes of recursively enumerable sets and their decision problems. Trans. Am. Math. Soc. 74(2), 358–366 (1953)
Sadowski, C., Aftandilian, E., Eagle, A., Miller-Cushon, L., Jaspan, C.: Lessons from building static analysis tools at google. Commun. ACM 61(4), 58–66 (2018)
Sharipov, I.: Ruleguard: dynamic inspection rules for Go (2020). https://quasilyte.dev/blog/post/ruleguard/
SonarSource: Sonarlint (2008). https://www.sonarlint.org/
Stack Exchange Inc.: Stack overflow developer survey (2020)
StrongLoop: Express (2010). https://expressjs.com/
Team, E.: Espree (2014). https://github.com/eslint/espree
Team, E.: Eslint: contributing new rules (2020). https://eslint.org/docs/developer-guide/contributing/new-rules
Tómasdóttir, K.F., Aniche, M., Van Deursen, A.: The adoption of JavaScript linters in practice: a case study on ESLint. IEEE Trans. Softw. Eng. 46, 863 - 891 (2018)
VeraCode: State of software security: Open source edition (2020)
Voss, L.: NPM and the future of Javascript (2018). https://slides.com/seldo/npm-and-the-future-of-javascript/. invited talk at JSConf US 2018
Wedyan, F., Alrmuny, D., Bieman, J.M.: The effectiveness of automated static analysis tools for fault detection and refactoring prediction. In: Second International Conference on Software Testing Verification and Validation, ICST 2009, Denver, Colorado, USA, 1–4 April 2009, pp. 141–150. IEEE Computer Society (2009)
Wheeler, D.: Flawfinder (2001). https://dwheeler.com/flawfinder/
Wing, J.M.: A call to action: look beyond the horizon. IEEE Secur. Priv. 1(6), 62–67 (2003)
Zakas, N.C.: Eslint (2013). https://eslint.org/
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
A ESLint
A ESLint
1.1 A.1 How ESLint Works
ESLint builds on Node.js and can be installed through npm. After that a configuration file is created, ESLint can be run on source files, e.g. from the command line or within an IDE [46]. ESLint takes as parameters which source file to lint and a configuration which e.g. specifies which rules to use.
First, ESLint parses the source file to render an abstract syntax tree (AST) from it. Each node in the resulting AST is a record which contains, amongst others, the type of the syntactic element it represents (e.g. , , , etc.), and information about where in the source file the syntactic element is located (for blame assignment). In case the information in this AST is insufficient (e.g. when writing advanced rules), ESLint lets one specify a different parser from the default one (i.e. Espree [38]), to construct an AST that stores additional information.
Next, ESLint traverses this AST to check that all rules are upheld. Each rule in ESLint is represented by an object. A rule object maintains its own state and exports methods which ESLint calls while traversing the AST. At each node, both while going down and up the AST, ESLint invokes, on each rule object, a method representing the type of the node ( , etc.; see above) and code paths ( , , etc.). If a rule detects an issue, then the rule reports the issue to a , which ESLint passes as a parameter when it creates the rule object.
1.2 A.2 Rules
Each rule in ESLint consists of three files(See footnote 3): a source file, a test file, and a documentation file.
Source filesFootnote 2,(e.g. Fig. 2), are stored in lib/rules. They have the following formatFootnote 3. A source file exports an object with two properties.
The objects \( meta \) and \( docs \) have four properties.
In \( docs \), is a description of what the rule checks. is the URL to the rule’s documentation. specifies whether this rule should be added to the list of recommended ESLint rules (which can all be turned on with a single option in the configuration). specifies where this rule should appear in the rules index; valid values include , , , & . In \( meta \), specifies the type of the rule; valid values are for a rule that identifies bad behavior, for a rule that provides improvement suggestions, and for a rule that provides stylistic tips. If a rule does not automatically fix an issue, then the property should be omitted. Otherwise, should be set to if it only affects whitespace, and otherwise. \( schema \) specifies which configuration options the rule accepts and should be omitted if the rule accepts no such options. \( create \), called when the rule object is created, returns an object which contains the functions that ESLint calls while traversing the AST (see above). The rule in Figure 2 gives an example of how a rule can maintain state and traverse the AST. Its state is a stack of code paths, which it uses, upon encountering a statement, to examine the AST to see if the statement is occurring within a constructor.
Test files are stored in tests/lib/rules. The test file contains sample inputs, along with the expected result of applying the rule on said input (valid, invalid). The unit test can then be run using the testing facility built in ESLint. Documentation files, stored in docs/rules, are written in Markdown syntax, and provide a description of what rules check, and how to configure them.
Plugins. Additional rules can be added to ESLint by downloading ESLint plugins. A plugin is a collection of ESLint rules. Plugins are routinely created by individuals and organizations, and shared as packages on npm. At present, npm contains thousands of ESLint plugins, each of which often contains tens of rules.
Rights and permissions
Copyright information
© 2020 Springer Nature Switzerland AG
About this paper
Cite this paper
Rafnsson, W., Giustolisi, R., Kragerup, M., Høyrup, M. (2020). Fixing Vulnerabilities Automatically with Linters. In: Kutyłowski, M., Zhang, J., Chen, C. (eds) Network and System Security. NSS 2020. Lecture Notes in Computer Science(), vol 12570. Springer, Cham. https://doi.org/10.1007/978-3-030-65745-1_13
Download citation
DOI: https://doi.org/10.1007/978-3-030-65745-1_13
Published:
Publisher Name: Springer, Cham
Print ISBN: 978-3-030-65744-4
Online ISBN: 978-3-030-65745-1
eBook Packages: Computer ScienceComputer Science (R0)