CoolCMS API

NavigationUrlPolicy
in package

FinalYes

Server-side scheme allowlist for stored external links (user profile, company reference, blog intro panel, article, menu item).

Latte 3 runs href="{$x}" through checkUrl and blanks javascript: and data: schemes, but that only mitigates at render time (it does not apply outside an attribute context, nor to values sent out through Api JSON). The authoritative gate therefore belongs here, before persistence. Modeled on ReturnUrlPolicy, a different domain (a navigation link to click, not an HTTP redirect).

Rule (positive allowlist, not a scheme deny-list):

  • an absolute URL http:// or https:// (case-insensitive scheme) with a non-empty host and no credentials (user:pass@host),
  • mailto: and tel: with non-empty content after the colon,
  • for fields where a relative value makes sense (internal menu, anchor in text) also a relative path starting with exactly one / (not //host, not /\host) and #anchor.

Anything else (javascript:, data:, vbscript:, file:, a schemeless evil.example where no relative path is allowed, control characters including CR/LF, a backslash, inner spaces) is rejected: the caller either does not store the value (form rule) or refuses the save (Api beforeSave()).

Table of Contents

Constants

ADMIN_MESSAGE  : string = '//admin.general.navigationUrl'
Global message key (admin); same trick as {@see \App\Core\Forms\StrictDateInput}.
ADMIN_MESSAGE_RELATIVE  : string = '//admin.general.navigationUrlRelative'
Message key for fields that also allow a link to this site (`/path`, `#anchor`), admin.
FRONT_MESSAGE  : string = '//front.general.navigationUrl'
Global message key (front); `front.general` speaks to the visitor.

Methods

isAllowed()  : bool
rule()  : BaseControl
Server-side rule for a Nette form. An empty value passes (optional field); required-ness is the caller's `setRequired()`, as with {@see \App\Core\Forms\StrictDateInput}.
rules()  : void
Batch variant of {@see rule()} for several fields at once (e.g. `link_<langId>` per language).
isAllowedAbsolute()  : bool
isValidOrEmpty()  : bool

Constants

ADMIN_MESSAGE

Global message key (admin); same trick as {@see \App\Core\Forms\StrictDateInput}.

public string ADMIN_MESSAGE = '//admin.general.navigationUrl'

ADMIN_MESSAGE_RELATIVE

Message key for fields that also allow a link to this site (`/path`, `#anchor`), admin.

public string ADMIN_MESSAGE_RELATIVE = '//admin.general.navigationUrlRelative'

FRONT_MESSAGE

Global message key (front); `front.general` speaks to the visitor.

public string FRONT_MESSAGE = '//front.general.navigationUrl'

Methods

isAllowed()

public static isAllowed(mixed $url, bool $allowRelative) : bool
Parameters
$url : mixed
$allowRelative : bool
Return values
bool

rule()

Server-side rule for a Nette form. An empty value passes (optional field); required-ness is the caller's `setRequired()`, as with {@see \App\Core\Forms\StrictDateInput}.

public static rule(BaseControl $control, bool $allowRelative[, string|null $message = null ]) : BaseControl
Parameters
$control : BaseControl
$allowRelative : bool
$message : string|null = null
Return values
BaseControl

rules()

Batch variant of {@see rule()} for several fields at once (e.g. `link_<langId>` per language).

public static rules(Container $container, array<int, string> $names, bool $allowRelative[, string|null $message = null ]) : void

A missing control is skipped (fields are sometimes built conditionally).

Parameters
$container : Container
$names : array<int, string>
$allowRelative : bool
$message : string|null = null

isAllowedAbsolute()

private static isAllowedAbsolute(string $url) : bool
Parameters
$url : string
Return values
bool

isValidOrEmpty()

private static isValidOrEmpty(mixed $value, bool $allowRelative) : bool
Parameters
$value : mixed
$allowRelative : bool
Return values
bool
On this page

Search results