Commit Graph

72 Commits

Author SHA1 Message Date
Sebastian Poxhofer 17466ceb32 fix(host-rules): ignore URL credentials when matching matchHost (#46128)
feat(host-rules): ignore URL credentials when matching matchHost

`matchesHost()` compared the raw href of the searched URL against
`matchHost`, so a URL carrying `user:pass@` userinfo (often a literal
placeholder such as `${USER}:${PASS}@`) never matched a `matchHost`
without credentials, including path-scoped ones. Callers worked around
this by stripping `username`/`password` off the URL by hand before
calling `hostRules.find()`.

- Add `stripUrlCredentials()` to `lib/util/url.ts`, returning the URL's
  `href` without userinfo (or `null` if unparseable), covered by
  `lib/util/url.spec.ts`.
- `matchesHost()` in `lib/util/host-rules.ts` now strips credentials
  from the searched URL before comparing it against an HTTP(S)
  `matchHost`, so `hostRules.find()` ignores userinfo on every caller's
  URL. Covered by new cases in `lib/util/host-rules.spec.ts` (a
  `matchHost` rule matches a URL carrying `user:pass@`, including a
  path-scoped `matchHost`).
- Remove the hand-rolled strip in
  `lib/modules/datasource/pypi/host-rules.ts`'s
  `findPypiIndexCredentials()`, now redundant since `find()` does it.
  `lib/modules/datasource/pypi/host-rules.spec.ts` already covers this
  behaviour and needed no changes.

This is strictly additive: more URLs match `matchHost` than before,
and nothing that matched before stops matching.
2026-09-18 10:53:12 +00:00
Jamie Tanna 7386ea49c4 refactor(host-rules): add an inherited trust tier
As part of looking to allow Inherit Config to manage Host Rules' grants,
we need to perform a prefactor to create an additional trust tier
between the global self-hosted administrator's config, and presets/repo
config.

The `find()` method already resolves sensitive fields - `headers`,
`enabled`, and the computed internal-host grant - a "trust tier" at a
time, so that the outcome cannot depend on how specific a rule from a
less trusted tier makes itself. The new `inherit` tier slots in between
the two we had:

- `headers` are applied untrusted first, then inherited, then the
  administrator's, so theirs still win outright
- `enabled` is taken from the administrator's rules, falling back to
  inherited config's, then a repository's
- an administrator's `allowInternal: false` acts as a veto: it is
  resolved before inherited config's rules, and clears the scoped
  and implicit grants too, so inherited config cannot re-grant the
  host in any shape by out-scoping it. Meanwhile any inherited rule
  naming a host in its `matchHost` - credentialed or not - now
  implicitly permits it, like the admin's own rules do

We introduce a separate field than `trusted` to avoid Inherit Config
gaining the same precedence as the admin themselves.

Co-authored-by: Claude Fable 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-10 14:52:01 +01:00
Jamie Tanna 09d2da2f1b feat(host-rules): add allowInternal
As part of follow-up changes, we're looking to tighten the way that
Renovate handles outgoing HTTP traffic.

Before we do this, we can introduce a new config option,
`hostRules[].allowInternal`, that allows a self-hosted administrator to
mark an internal host as "trusted" for access.

This wires in the new global-only config option, `allowInternal`, which
implies a new internal field `internalHostGrant`.

We'll add full documentation in a future commit, when the full
enforcement is in place, as there are some wider changes to enforce it
fully.

Co-authored-by: Claude Fable 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-10 14:52:01 +01:00
Jamie Tanna 7d3fe44060 fix(util/host-rules): resolve enabled per trust tier
As part of follow-up changes, we're looking to tighten the way that
Renovate handles outgoing HTTP traffic, and a self-hosted administrator
disabling a host needs to be something a repository cannot undo.

In a similar change to
4732da7d2b, we can resolve `enabled` per
trust tier, so that a repository or preset rule can no longer re-enable
- or disable - a host the administrator's own rules set, which was
previously possible with a longer `matchHost`.

Within a tier nothing changes: the most specific rule still wins, so a
repository disabling a host of its own keeps working, as does an
administrator masking their own broad rule with a narrower one.

This is a behaviour change for repository config that previously relied
on overriding an admin rule's `enabled`.

Co-authored-by: Claude Fable 5 <jamie.tanna+claude-code@mend.io>
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-10 14:52:01 +01:00
Jamie Tanna 4732da7d2b fix(util/host-rules): apply the admin's headers over a repository's
As part of changes we've recently made to the merging of
`hostRules[].headers`, it highlighted that a repository - or a preset
it extends - could lead to a header an admin has configured for one host
to be sent to another.

This happened due to the way we additively merged i.e.
`Object.assign({}, ...matchedHeaders)`.

This doesn't require the repository to know a credential is being
set (for a specific host), or to act maliciously - any header of their
own for that host is enough to bring the administrator's masked one
back, with nothing logged or failing to show it happened.

To fix this, we can:

- apply admin headers last, as they are "trusted"
- stop repositories from being able to unset an admin-set header
- retain the existing logic for the "most specific rule" being used
- make sure that `trusted` isn't a field that could be injected by a
  repository, and make sure we explicitly only set it where we know
  we're using self-hosted administrator config
- make `filterAllowedHeaders` drop `headers` if every header name was
  denied, so `{}` isn't returned and used to suppress headers when
  merged

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 08:01:41 +01:00
Jamie Tanna c98f4f71c8 fix(util/host-rules): enforce allowedHeaders within add()
We previously enforced `allowedHeaders` by making sure that each
`hostRules.add()` call had `filterAllowedHeaders`.

This isn't super future proofed, and although we could add a linting
rule, we should instead enforce this by making sure that
`hostRules.add()` applies the filtering.

This also catches cases like host rules from `.npmrc` which wasn't
currently being filtered - albeit there was no means to bypass
`allowedHeaders`.

Moving `filterAllowedHeaders` into `lib/util` removes a dependency from
the global bootstrap and `config-validator` importing from
`lib/workers/repository/init/`.

While doing so, we can also make sure that:

- we log only one WARN for global `hostRules` being invalid, rather than
  once per `repositories[]`
- `renovate-config-validator` validates a global config file's
  `hostRules` against that file's own `allowedHeaders`, like a real run
  would after parsing it

Co-authored-by: Claude Fable 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 08:01:41 +01:00
Jamie Tanna 3d56c38cf6 fix(util/host-rules): merge headers across matching rules
Previously, if there was a `hostRule[].headers` value for a given host
set in both global self-hosted configuration and repo config, the repo
config would overwrite /all/ headers set by the admin.

To resolve this, we can now correctly merge the keys, with the repo
config taking priority.

This still only takes into account the `allowedHeaders`, so a repository
cannot bypass admin settings.

Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
2026-09-03 08:01:41 +01:00
Sebastian Poxhofer 16ef1715e9 refactor(linters): add rules for @sindresorhus/is helpers (#45229)
* feat(lint): add renovate/prefer-is-helpers and renovate/prefer-is-object rules

Flag ad-hoc type checks that have @sindresorhus/is equivalents:
- .filter(Boolean) -> .filter(isTruthy)
- typeof x === 'string' -> isString(x)
- x === null || x === undefined -> isNullOrUndefined(x) (and negation)

The typeof x === 'object' shape lives in a separate suggestion-only rule
(renovate/prefer-is-object, kept at warn) because isObject()/isPlainObject()
are not drop-in equivalents: null, arrays and functions behave differently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: fix renovate/prefer-is-helpers violations

Replace ad-hoc type checks with @sindresorhus/is helpers across lib/:
- 13x .filter(Boolean) -> .filter(isTruthy)
- 36x typeof x ==/!== 'string' -> isString(x) / !isString(x)
- 6x x === null || x === undefined -> isNullOrUndefined(x) (and negation)

Promote renovate/prefer-is-helpers to error now that the codebase is clean.
renovate/prefer-is-object stays at warn: its 15 remaining sites guard
parsed YAML/JSON or unknown values where isObject()/isPlainObject() are
not provably equivalent (null/array/function semantics).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: enforce renovate/prefer-is-object at error level

Resolve the 15 remaining warnings and raise the rule from warn to error:

- Migrate 10 sites to isObject() where the guarded value provably cannot
  be a function (parsed YAML/JSON, typed exec command arguments, or
  test-controlled fixtures): helm-values, woodpecker, bun, pre-commit
  managers, exec utils, file package cache, and the github http spec.
  In the bun manager this also fixes a latent crash where a null
  `workspaces` value would throw on the `in` operator.
- Keep 5 sites as reasoned oxlint-disable comments where excluding
  functions is load-bearing: the byte-exact fingerprint canonicalizer
  (2), the circularity walker, the zod result guard, and the generic
  hasKey helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 14:22:03 +00:00
Jamie Tanna 54384ff3e5 fix(util/host-rules): sanitise TLS credential fields in hostRules (#45119)
* chore(util): note that `httpsCertificate` and `httpsCertificateAuthority` aren't secret

Although we're currently treating them as such, they're not technically
unsafe to appear in the logs, as a Certificate (and the authority) are
public.

* fix(util/host-rules): sanitise TLS credential fields in hostRules

We previously noted that the `httpsPrivateKey`, `httpsCertificate`, and
`httpsCertificateAuthority` fields would be marked as confidential, but
we weren't correctly sanitising them.

We can make sure that these fields are correctly flagged as secret
("confidential") and that they need to be sanitised when referenced.

Although the `httpsCertificate` and `httpsCertificateAuthority` aren't
secret, we can keep them sanitised for consistency with how we've
currently documented them as being sanitised.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

* test(util/host-rules): ensure that all secret fields are marked as secret

As a way to make sure that new fields being added `HostRule`s are
considered as to whether the field should be marked as secret
("confidential") or not, we can add a test (and a compile-time
exhaustive check) to validate that `redactedFields` and
`confidentialFields` are kept in sync.

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>

---------

Co-authored-by: Claude Sonnet 5 <jamie.tanna+claude-code@mend.io>
2026-08-06 15:15:54 +00:00
Sergei Zharinov 930cf6633c refactor: Rewrite imports with .ts extensions (#40700)
fix: Additional vi.mock path corrections and prettier formatting
2026-01-26 22:48:17 +00:00
Michael Kriese 9fe353adb4 test: add coverage (part1) (#40636) 2026-01-23 15:09:01 +00:00
RahulGautamSingh 76f911041a refactor: use named exports (#39196)
* use named exports

* fix test

* add missing imnport

* fix prettier
2025-11-10 12:00:35 +00:00
Tobias b7347fd1c9 fix(util/host-rules): compare normalized URLs when matching hostRules (#36311) 2025-06-05 06:34:39 +00:00
renovate[bot] eb8c08079e chore(deps): update typescript-eslint monorepo to v8 (major) (#30750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2024-08-14 10:33:02 +00:00
Sergei Zharinov 8d183d6b25 feat(http): Force default rate limits for some known hosts (#30207)
Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2024-07-22 16:59:29 +00:00
RahulGautamSingh b8b760768d feat(hostRules/matchHost): massage and validate (#29487)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2024-06-28 07:20:00 +00:00
Sergei Zharinov 5c0628bf3b feat(host-rules): Support readOnly request matching (#28562)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2024-04-23 03:26:20 +00:00
Sergei Zharinov 49afe4e3b2 refactor(host-rules): Simplify ordering and matching (#28512)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2024-04-21 06:28:06 +00:00
Sergei Zharinov d6d1e57763 refactor: Rename validateUrl to isHttpUrl (#28484) 2024-04-17 15:57:33 +00:00
Sergei Zharinov e7d9c053ac refactor(host-rules): Refactor matching logic (#28482) 2024-04-17 15:06:54 +00:00
Sergei Zharinov a39ca89101 refactor: Host rule types (#28454) 2024-04-17 05:00:00 +00:00
Sergei Zharinov b69416ce17 refactor(prettier): Force trailing commas (#25631) 2023-11-07 15:50:29 +00:00
Rhys Arkins a268816a88 refactor(host-rules): log hostType (#24939) 2023-10-09 10:32:56 +00:00
Rhys Arkins 36e2b328bb chore: update types reference 2023-08-15 11:31:15 +02:00
renovate[bot] fe739befbf chore(deps): update linters to v6 (major) (#23325)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2023-08-02 15:07:49 +00:00
Sergei Zharinov 53263bbfda feat: Clone objects via wrapper (#22970) 2023-06-27 13:09:59 +00:00
Sergei Zharinov 4eb11d1120 fix: Sanitize utils coverage (#22995) 2023-06-27 06:53:08 +00:00
RahulGautamSingh be2a89520b refactor: replace as assertions (#22442) 2023-06-05 19:18:30 +00:00
RahulGautamSingh 0d85cead02 fix(migration): throw error for invalid hostRules (#20540) 2023-05-22 07:49:26 +00:00
Jamie Magee a6dfa70c1d chore: migrate to structuredClone (#20885)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2023-04-27 05:06:22 +00:00
Michael Kriese 8270d5512d refactor: fix lint issues (#16779)
* refactor: fix lint issues

* Update lib/renovate.ts

* chore: revert toplevel await for ts
2022-07-26 08:32:12 +00:00
Michael Kriese fb9303c190 feat(core:changelogs): better platform detection (#14989)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2022-04-06 14:56:40 +00:00
Rhys Arkins f3d4e29c8a fix(hostRules): sort by matchHost length (#14264) 2022-02-28 19:23:43 +00:00
Rhys Arkins b130bf5afb refactor: base64 util functions (#14422) 2022-02-26 10:16:54 +01:00
Jamie Magee 3b7e9a17cb refactor: set importsNotUsedAsValues to error (#14052) 2022-02-07 06:37:17 +00:00
Sergei Zharinov cdd9b44ae8 refactor: Use null-safe Boolean filtering (#14039)
* refactor: Use null-safe Boolean filtering

* Simplify and remove file
2022-02-06 16:30:53 +00:00
Rhys Arkins 0bad22b254 chore: rename sanitize functions for better searchability (#13826) 2022-01-26 10:57:21 +01:00
Sergei Zharinov f4dbff9bd3 refactor(util/host-rules): Strict null checks for host rules (#12868)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2021-11-28 16:31:11 +01:00
Tobias 87c5e8e022 feat(gomod): use git host rules as authentication for gosum updates (#12230)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2021-10-31 07:06:59 +00:00
David Straub 8fb9197d0c fix(host-rules): support matchHost with a dot prefix (#11523)
Co-authored-by: Rhys Arkins <rhys@arkins.net>
2021-09-02 17:03:51 +00:00
renovate[bot] b8e36daa87 chore(deps): update dependency prettier to v2.3.0 (#10012)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2021-05-17 08:06:24 +00:00
Rhys Arkins b6e5c32f07 refactor: improve host-rules error logging 2021-05-14 12:02:56 +02:00
Rhys Arkins f00413c298 feat(host-rules): use only matchHost (#9892)
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2021-05-13 20:53:18 +00:00
Rhys Arkins 89ad6401d9 fix(hostRules): domainName matching (#9884) 2021-05-06 11:30:42 +02:00
Rhys Arkins 856b28841d feat: hostRules.matchHost (#9815)
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2021-05-06 07:57:44 +00:00
Rhys Arkins 4e9e0a63ec refactor: hostRules.hosts() simplification 2021-05-01 23:34:16 +02:00
Rhys Arkins 49272cc003 chore: hostRules resolvedHost simplification 2021-05-01 23:30:24 +02:00
Rhys Arkins 52687368cb refactor: hostRules error 2021-05-01 23:18:14 +02:00
Rhys Arkins 0918679cf6 refactor(hostRules): precalculate resolvedHost (#9811) 2021-05-01 18:19:38 +02:00
Rhys Arkins 5246e6b34e refactor: host-rules ruleMatch -> resolvedHost 2021-05-01 16:21:59 +02:00