Safeguard
Security

What Is Linting in Code? A Security Perspective

Linting is automated static analysis that catches bugs, style issues, and security anti-patterns before code runs. Here is what it does and where it fits in a secure pipeline.

Yukti Singhal
Platform Engineer
5 min read

Linting in code is the automated analysis of source files to flag programming errors, stylistic inconsistencies, and suspicious patterns without executing the program. A linter reads your code the way a compiler does a first pass, builds an internal representation of it, and checks that representation against a set of rules. When you ask what linting in code is, the short answer is: it is the cheapest form of static analysis you can run, and it catches a surprising number of real bugs and security issues before they reach a review or a runtime.

The name comes from a 1978 Unix tool called lint that flagged questionable constructs in C. The idea stuck, and today nearly every language has one.

How a linter actually works

A linter parses your source into an abstract syntax tree (AST), a structured representation of every function, variable, and expression. Rules then walk that tree looking for patterns. A rule that forbids == in favor of === in JavaScript, for example, looks for binary-expression nodes using the loose-equality operator and reports each one.

Because the linter works on structure rather than raw text, it can reason about things a regex never could: unreachable code, variables assigned but never read, or a catch block that swallows an error silently. This is why linting catches issues that a simple find-and-replace would miss.

Style versus correctness versus security

Linter rules fall into roughly three buckets, and conflating them causes friction:

  • Style rules enforce consistency: indentation, quote style, trailing commas. These matter for readability but have no correctness impact. Delegate most of these to a formatter like Prettier or gofmt and keep them out of the linter where possible.
  • Correctness rules catch likely bugs: comparing against NaN, an unhandled promise, a missing return. These earn their keep.
  • Security rules flag dangerous constructs: using eval, building a SQL string by concatenation, disabling certificate validation, or hardcoding what looks like a secret.

The third bucket is where linting overlaps with application security, and it is the part teams most often underuse.

Linting as lightweight SAST

Static Application Security Testing (SAST) and linting live on a spectrum. A dedicated SAST engine does deep data-flow analysis to trace tainted input from a source to a dangerous sink. A linter is shallower but runs in milliseconds and fits into your editor. Plugins like eslint-plugin-security for JavaScript, bandit for Python, or gosec for Go bring security-specific rules into the linting step.

Here is a concrete ESLint example that catches a common mistake:

// eslint-plugin-security flags this: detect-non-literal-fs-filename
const fs = require("fs");

function readUserFile(name) {
  // reading a path built from user input is a path-traversal risk
  return fs.readFileSync(name);
}

The linter cannot prove name is attacker-controlled, but it can tell you the pattern is risky and worth a human look. That nudge, delivered in the editor, is often what stops a vulnerability from ever being written.

Where linting sits in the pipeline

Run linting in three places for maximum value:

  1. In the editor, via an extension, so developers see problems as they type.
  2. In a pre-commit hook, so obvious issues never enter the repository.
  3. In CI, as a required check, so nothing merges that violates the rules.
# a minimal CI lint step
- name: Lint
  run: npx eslint . --max-warnings 0

The --max-warnings 0 flag turns warnings into a failing build, which prevents the slow rot where warnings accumulate until nobody reads them.

What linting does not do

Linting is not a substitute for dependency scanning or dynamic testing. A linter analyzes your code; it does not know that a package in your node_modules has a published CVE. That is the job of software composition analysis, which our SCA product page covers in depth, and dynamic testing against a running app, which is DAST. Think of linting as the first and fastest gate, not the whole wall. Understanding what a dependency is in programming helps clarify why those layers are separate concerns.

Tuning rules so people actually use it

The fastest way to kill a linting effort is to turn on every rule at maximum severity on a mature codebase. You get thousands of errors, everyone runs --fix blindly or disables the check, and the signal drowns. Instead, start with a recommended preset, add security rules deliberately, and ratchet strictness up over time. Use inline disable comments sparingly and require a reason:

// eslint-disable-next-line no-eval -- sandboxed evaluator, input is validated upstream

An audit trail of why a rule was suppressed is worth as much as the rule itself.

FAQ

Is linting the same as compiling?

No. A compiler checks that code is valid enough to translate and run; a linter checks for patterns that are valid but likely wrong, stylistically inconsistent, or risky. Many interpreted languages have no compile step at all, which makes linting their primary pre-runtime check.

Can a linter find security vulnerabilities?

It can find anti-patterns strongly associated with vulnerabilities, like eval, disabled TLS verification, or string-built SQL, using security plugins. It will not do the deep data-flow analysis of a full SAST tool, so treat it as a fast first pass rather than complete coverage.

Should linting block a merge?

Yes, for correctness and security rules. Run it as a required CI check with warnings promoted to errors so nothing merges that violates the ruleset. Keep purely cosmetic formatting in a separate formatter to reduce noise.

What is the difference between a linter and a formatter?

A formatter rewrites code to a consistent style automatically (spacing, quotes, line breaks). A linter analyzes code for problems and mostly reports rather than rewrites. Most teams run both: the formatter for style, the linter for correctness and security.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.