Skip to main content
interlace
Plugin: pgRules

no-select-all

Discourages SELECT in favor of explicit column lists.

CWE: CWE-693

Discourages SELECT * in favor of explicit column lists.

⚠️ This rule warns by default in the recommended config.

Quick Summary

AspectDetails
SeverityLow (quality/performance)
CategorySecurity

Rule Details

SELECT * fetches all columns, which can:

  • Transfer unnecessary data
  • Break when schema changes
  • Prevent query plan optimizations

❌ Incorrect

await client.query('SELECT * FROM users WHERE id = $1', [id]);

await pool.query('SELECT a, b, * FROM table'); // Mixed

✅ Correct

await client.query('SELECT id, name, email FROM users WHERE id = $1', [id]);

// COUNT(*) is acceptable
await pool.query('SELECT COUNT(*) FROM users');

// `*` over a CTE or derived table whose own SELECT lists the columns
await pool.query('WITH recent AS (SELECT id, total FROM orders) SELECT * FROM recent');
await pool.query('SELECT * FROM (SELECT id, email FROM users) AS u');

Error Message Format

📋 | Avoid SELECT * - explicitly list required columns | LOW
   Fix: Replace * with specific column names

When Not To Use It

  • In development/debugging scripts
  • When schema is stable and all columns are needed

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Dynamic Query Construction

Why: Queries built at runtime are not analyzed.

// ❌ NOT DETECTED - Query from variable
const query = 'SELECT * FROM users';
await client.query(query);

Mitigation: Use template literals directly in query calls. Enable strict query typing.

Query in String Variable

Why: String contents from variables are not traced.

// ❌ NOT DETECTED - Query concatenation
const cols = '*';
await client.query(`SELECT ${cols} FROM users`);

Mitigation: Use explicit column lists stored in typed constants.

Imported Query Strings

Why: Queries from other modules are not visible.

// ❌ NOT DETECTED - Query from import
import { USERS_QUERY } from './queries'; // Contains SELECT *
await client.query(USERS_QUERY);

Mitigation: Apply this rule to query files. Use query builders with column selection.

ORM Generated Queries

Why: ORMs may generate SELECT * internally.

// ❌ NOT DETECTED - ORM may use SELECT * under the hood
const users = await User.find({ where: { active: true } });

Mitigation: Configure ORM to select explicit fields. Use projections/select options.

Use this rule

npm install -D oxlint-plugin-postgresql-security
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-postgresql-security"],  "rules": {    "postgresql-security/no-select-all": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-postgresql-security'],    rules: {      'postgresql-security/no-select-all': 'error',    },  },});

oxlint-plugin-postgresql-security re-exports eslint-plugin-postgresql-security/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.