@heroku-cli/command
Advanced tools
@@ -7,2 +7,4 @@ import { Interfaces } from '@oclif/core'; | ||
| import { ParticleboardClient } from './particleboard-client'; | ||
| export declare const ALLOWED_HEROKU_DOMAINS: readonly string[]; | ||
| export declare const LOCALHOST_DOMAINS: readonly string[]; | ||
| export declare namespace APIClient { | ||
@@ -9,0 +11,0 @@ interface Options extends HTTPRequestOptions { |
+19
-2
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.APIClient = exports.HerokuAPIError = void 0; | ||
| exports.APIClient = exports.HerokuAPIError = exports.LOCALHOST_DOMAINS = exports.ALLOWED_HEROKU_DOMAINS = void 0; | ||
| const tslib_1 = require("tslib"); | ||
@@ -13,2 +13,4 @@ const errors_1 = require("@oclif/core/lib/errors"); | ||
| const debug = require('debug'); | ||
| exports.ALLOWED_HEROKU_DOMAINS = Object.freeze(['heroku.com', 'herokai.com', 'herokuspace.com', 'herokudev.com']); | ||
| exports.LOCALHOST_DOMAINS = Object.freeze(['localhost', '127.0.0.1']); | ||
| class HerokuAPIError extends errors_1.CLIError { | ||
@@ -133,2 +135,3 @@ constructor(httpError) { | ||
| } | ||
| // eslint-disable-next-line complexity | ||
| static async request(url, opts = {}, retries = 3) { | ||
@@ -151,3 +154,17 @@ opts.headers = opts.headers || {}; | ||
| if (!Object.keys(opts.headers).some(h => h.toLowerCase() === 'authorization')) { | ||
| opts.headers.authorization = `Bearer ${self.auth}`; | ||
| // Handle both relative and absolute URLs for validation | ||
| let targetUrl; | ||
| try { | ||
| // Try absolute URL first | ||
| targetUrl = new URL(url); | ||
| } | ||
| catch (_a) { | ||
| // If that fails, assume it's relative and prepend the API base URL | ||
| targetUrl = new URL(url, vars_1.vars.apiUrl); | ||
| } | ||
| const isHerokuApi = exports.ALLOWED_HEROKU_DOMAINS.some(domain => targetUrl.hostname.endsWith(`.${domain}`)); | ||
| const isLocalhost = exports.LOCALHOST_DOMAINS.includes(targetUrl.hostname); | ||
| if (isHerokuApi || isLocalhost) { | ||
| opts.headers.authorization = `Bearer ${self.auth}`; | ||
| } | ||
| } | ||
@@ -154,0 +171,0 @@ this.configDelinquency(url, opts); |
+1
-0
@@ -12,3 +12,4 @@ export declare class Vars { | ||
| get particleboardUrl(): string; | ||
| private isValidHerokuHost; | ||
| } | ||
| export declare const vars: Vars; |
+13
-1
@@ -5,6 +5,13 @@ "use strict"; | ||
| const tslib_1 = require("tslib"); | ||
| const core_1 = require("@oclif/core"); | ||
| const url = tslib_1.__importStar(require("url")); | ||
| const api_client_1 = require("./api-client"); | ||
| class Vars { | ||
| get host() { | ||
| return this.envHost || 'heroku.com'; | ||
| const { envHost } = this; | ||
| if (envHost && !this.isValidHerokuHost(envHost)) { | ||
| core_1.ux.warn(`Invalid HEROKU_HOST '${envHost}' - using default`); | ||
| return 'heroku.com'; | ||
| } | ||
| return envHost || 'heroku.com'; | ||
| } | ||
@@ -63,4 +70,9 @@ get apiUrl() { | ||
| } | ||
| isValidHerokuHost(host) { | ||
| // Remove protocol if present | ||
| const cleanHost = host.replace(/^https?:\/\//, ''); | ||
| return api_client_1.ALLOWED_HEROKU_DOMAINS.some(domain => cleanHost.endsWith(`.${domain}`)) || api_client_1.LOCALHOST_DOMAINS.some(domain => cleanHost.includes(domain)); | ||
| } | ||
| } | ||
| exports.Vars = Vars; | ||
| exports.vars = new Vars(); |
+1
-1
| { | ||
| "name": "@heroku-cli/command", | ||
| "description": "base class for Heroku CLI commands", | ||
| "version": "11.6.0", | ||
| "version": "11.7.0", | ||
| "author": "Heroku", | ||
@@ -6,0 +6,0 @@ "bugs": "https://github.com/heroku/heroku-cli-command/issues", |
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 17 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 17 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
88076
2.14%1545
2.12%29
3.57%