Hacker DirectoryHacker Directory

WEB / WEB-06.01

URL anatomy and resource addressing

Separate URL components, resource identity, representations, and access decisions. Follow query multiplicity, encoding, and fragment boundaries in native parser results.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Absolute URL

  1. Input is unparsed

    The catalogue address is only text; there is no parsed result or request.

    Address text
    Input: catalogue URL
    Local URL parser
    Parser: pending
    Application view
    View: pending
  2. Authority is parsed

    Scheme, hostname, and explicit port were separated locally. No DNS ran.

    Address text
    Input: unchanged
    Local URL parser
    https: / books.example / 8443
    Application view
    View: pending
  3. Path/query/fragment are separated

    The query contains two tag values; #summary remains a fragment.

    Address text
    Input: unchanged
    Local URL parser
    /catalog/atlas; tags: network, web; #summary
    Application view
    View: pending
  4. A request-target candidate is prepared

    The path/query candidate excludes the fragment. This calculation sends no HTTP.

    Address text
    Input: unchanged
    Local URL parser
    Parser: success
    Application view
    Target: /catalog/atlas?lang=tr&tag=network&tag=web
  5. Fragment remains in the client view

    Summary is a candidate client selection, with no network or scrolling evidence.

    Address text
    Input: unchanged
    Local URL parser
    Parser: success
    Application view
    Fragment: summary; network: not run

No base

  1. A relative reference exists

    /catalog/atlas does not carry a host on its own.

    Address text
    /catalog/atlas
    Local URL parser
    Base: absent
    Application view
    Result: pending
  2. Constructor is called without a base

    The native URL constructor requires a base for this relative input.

    Address text
    /catalog/atlas
    Local URL parser
    Parse: failure / TypeError
    Application view
    Result: pending
  3. No success result is produced

    The exception is not a network failure; no valid absolute result exists.

    Address text
    /catalog/atlas
    Local URL parser
    TypeError retained
    Application view
    Destination: absent
  4. Context must be supplied separately

    Supplying a base starts a new local resolution; it does not rewrite the failed operation.

    Address text
    /catalog/atlas
    Local URL parser
    Base required
    Application view
    HTTP: not sent

ACTORS · STATE · DATA FLOW

Separate the resource from its address

Duru opens Atlas in a book catalogue. The resource is the application’s conceptual entity; the URL is an identifier addressing it. The server can offer an HTML or JSON representation of that entity. Reading an address does not establish the returned bytes, existence, or Duru’s permission.

RFC 3986 presents URI as the general identification framework and URL as a category associated with location or an access mechanism. The modern browser API is named URL; WHATWG specifies interoperable browser parsing. Generic RFC syntax and browser parsing are not identical algorithms for every edge case.

Parsing is local text processing, distinct from DNS, transport, TLS, or sending an HTTP request. books.example is an educational name and is never contacted by this scene.

Read a URL by its components

Read https://books.example:8443/catalog/atlas?lang=tr&tag=network&tag=web#summary as scheme, authority with host/port, path, query, and fragment. Component delimiters matter; splitting everything on slashes is insufficient.

The artifact records protocol, hostname, host, port, pathname, search, and hash from new URL(input). protocol includes its colon, search begins with ?, and hash begins with #. Distinguish the URL record concept from the getter’s serialized representation.

hostname is books.example; host includes :8443. The path is /catalog/atlas, the query contains three pairs, and the fragment identifies summary. These are parser observations, not an HTTP request or server routing decision.

What does the scheme select?

The scheme selects how an address is interpreted. http and https address web resources; other schemes such as mailto do not promise the same transport or path structure. A valid URL does not universally imply an HTTP GET.

An https string expresses intended HTTPS use. Successful parsing has not validated a certificate or established a secure connection; TLS has its own handshake and validation boundaries.

An application accepting only HTTPS resource links applies its scheme policy to the parsed result. Syntax validity and suitability for an application are separate decisions, neither of which proves network success.

Host and port are separate from the path

The authority’s host identifies a target and can use a domain name or an IP address form. DNS resolves domain names; a parser producing hostname has not obtained a DNS answer or proved that a server exists.

The numeric port contributes to selecting a service endpoint. This fixture explicitly chooses 8443; that number is not a universal secure alternative to HTTPS. A listener and its protocol behavior require separate evidence.

HTTPS has default port 443. Parsing https://books.example:443/catalog removes the default port from serialization, and the port getter returns an empty string. The service has not become portless. Non-default 8443 remains and changes origin comparisons.

host can include a port while hostname does not. For logs and configuration, use the components produced by a consistent parser rather than searching the raw string for familiar text.

A path is an application address

/catalog/atlas is the hierarchical path following the authority. Its segments may be inputs to an application’s route contract. They need not correspond to a catalogue directory and an atlas file on the server: a handler can produce a database-backed response.

The server or framework gives the path its application meaning; the URL parser does not know the route table. Case or a trailing slash can select a different resource, a redirect, or the same route according to that contract. No filesystem result is implied here.

The query is not part of pathname. For /catalog/atlas?lang=tr, routing, locale selection, and cache-key construction are subsequent operations with explicit rules.

Read query pairs without losing multiplicity

The query starts with ?. Its business meaning is application-defined. Key/value pairs separated by & are a common form representation handled by URLSearchParams; allowed keys and values still need application rules.

This example repeats tag. get("tag") returns the first value, network, while getAll("tag") preserves network and web. Code assuming a single value can silently lose the second label. Multiplicity belongs to the schema contract rather than being resolved by syntax alone.

Do not hand the entire URL string to URLSearchParams as if it were a query. Use a URL object’s searchParams or the separated search text. lang=tr is a locale candidate, not evidence of object ownership or identity.

Where does the fragment stay?

#summary is a fragment. It is excluded from the target of a normal HTTP resource request and can guide the client to a part of the representation. The derived origin-form path/query is /catalog/atlas?lang=tr&tag=network&tag=web, without #summary.

Client-side handling does not make a fragment a secret vault. Page code can read it and send it in a separate request. The narrower claim is that the initial URL’s fragment component is not included in its ordinary resource request.

The scene prepares a path/query candidate while keeping the fragment separate. It does not send HTTP or execute scrolling; derivation and fragment consumption remain distinct local operations.

Encoding represents data for transport

Percent-encoding represents a byte using % and two hexadecimal digits. Converting Unicode text to bytes first requires an encoding. URLSearchParams uses UTF-8 and form serialization: the fixture’s q value notlar ı becomes q=notlar+%C4%B1.

In form query serialization a space becomes +; a literal plus is preserved as %2B. A plus does not universally mean a space in every URL component. URL.search and URLSearchParams can serialize the same values differently, so identify the layer being observed.

Encoding is not encryption or authorization: the decoded value remains application input. Treating already encoded text as a raw value changes its representation on another encoding pass. Keep parsing and validation order explicit.

The artifact contains small normal-text native API round trips, with no custom server decoding pipeline or parser-bypass model.

Absolute addresses and relative references

An absolute URL supplies its own scheme and required parsing context. A relative reference such as /catalog/atlas cannot identify its host without a base. new URL("/catalog/atlas") throws TypeError; a valid HTTPS base makes resolution possible.

Resolution is not string concatenation. The base path’s last slash, root-relative versus directory-relative form, and query/fragment references affect the result. WEB-06.03 follows those calculations separately.

After parsing, inspect the resulting absolute URL’s components again. Reachability and suitability for the application remain separate from resolution, naming, and permission.

2. Red · Trust & Impact

Read every scenario without motion

Query values

  1. The normal catalog reference was selected

    Duru selects the Atlas catalog link at books.example on port 8443. Its query contains lang=tr and two tag values; #summary is a separate fragment. The consumer retains each component’s purpose.

    URL reference evidence
    Atlas URL / query + fragment
    Structured parsing
    No parsed fields
    Consumer boundary
    No application policy
  2. Parser fields were separated

    The parser separates hostname books.example, host books.example:8443 and pathname /catalog/atlas, producing origin https://books.example:8443. Text similarity does not replace structured hostname or origin comparison.

    URL reference evidence
    Atlas URL / query + fragment
    Structured parsing
    hostname / host / origin separate
    Consumer boundary
    No application policy
  3. Representation loss was stopped before a decision

    tags=[network, web] contains two values. Selecting the first is a different application-schema decision that ignores the second; the parser is not claimed to have collapsed them.

    URL reference evidence
    Atlas URL / query + fragment
    Structured parsing
    hostname / host / origin separate
    Consumer boundary
    Both tags retained: network,web
  4. Encoding is not authority

    Value A+B becomes q=A%2BB under form encoding; notlar ı becomes q=notlar+%C4%B1. The conversion creates neither encryption nor permission, only another representation.

    URL reference evidence
    Raw values / form serialization separate
    Structured parsing
    hostname / host / origin separate
    Consumer boundary
    Both tags retained: network,web
  5. Parser success is not policy success

    After creating a structured URL, the application separately evaluates permitted scheme/destination/port and query schema. Resource authorization does not follow from URL anatomy.

    URL reference evidence
    Raw values / form serialization separate
    Structured parsing
    Parsed URL / policy still separate
    Consumer boundary
    Both tags retained: network,web
  6. The boundary result stayed supported

    Query multiplicity and first/all-value distinctions are retained. NetworkRequestsExecuted=0 prevents adding a server-interpretation or data-exposure outcome.

    URL reference evidence
    Raw values / form serialization separate
    Structured parsing
    Parsed URL / policy still separate
    Consumer boundary
    Multiplicity preserved / server unknown

Fragment boundary

  1. The normal catalog reference was selected

    Duru selects the Atlas catalog link at books.example on port 8443. Its query contains lang=tr and two tag values; #summary is a separate fragment. The consumer retains each component’s purpose.

    URL reference evidence
    Atlas URL / query + fragment
    Structured parsing
    No parsed fields
    Consumer boundary
    No application policy
  2. Parser fields were separated

    The parser separates hostname books.example, host books.example:8443 and pathname /catalog/atlas, producing origin https://books.example:8443. Text similarity does not replace structured hostname or origin comparison.

    URL reference evidence
    Atlas URL / query + fragment
    Structured parsing
    hostname / host / origin separate
    Consumer boundary
    No application policy
  3. Representation loss was stopped before a decision

    HTTP origin-form contains only /catalog/atlas?lang=tr&tag=network&tag=web. #summary is excluded from that request target and stays client-side. The server router is not claimed to receive the fragment.

    URL reference evidence
    Atlas URL / query + fragment
    Structured parsing
    hostname / host / origin separate
    Consumer boundary
    Request target excludes #summary
  4. Encoding is not authority

    Value A+B becomes q=A%2BB under form encoding; notlar ı becomes q=notlar+%C4%B1. The conversion creates neither encryption nor permission, only another representation.

    URL reference evidence
    Raw values / form serialization separate
    Structured parsing
    hostname / host / origin separate
    Consumer boundary
    Request target excludes #summary
  5. Parser success is not policy success

    After creating a structured URL, the application separately evaluates permitted scheme/destination/port and query schema. Resource authorization does not follow from URL anatomy.

    URL reference evidence
    Raw values / form serialization separate
    Structured parsing
    Parsed URL / policy still separate
    Consumer boundary
    Request target excludes #summary
  6. The boundary result stayed supported

    The fragment stays client-side and request-target covers path/query. This separation measures neither UI scrolling nor actual HTTP delivery.

    URL reference evidence
    Raw values / form serialization separate
    Structured parsing
    Parsed URL / policy still separate
    Consumer boundary
    Fragment separated / delivery unknown

ASSUMPTION · BOUNDARY · CONTROL

Identify the operation that establishes trust

Start a security review by identifying the consumer: browser parser, server router, or application validation. An address can serve different purposes. Familiar-looking text is not a substitute for parsed components or a policy decision.

Follow Duru’s ordinary catalogue link through the artifact. Local scheme, hostname, and port candidates exist before resource authorization. Ask which structured value the next layer trusts and for what purpose.

Place the artifact’s tags array, first get result, and candidate request target side by side. network and web are separate query values; summary is not one of them. Explain why the second tag survives and where the fragment remains on the client.

Representation loss can lose a decision input

Keeping one of two tags or mistaking a fragment for the request target produces a misleading interpretation. Record the reference, parsed components, and schema result as separate observations.

The two tag query pairs and #summary fragment belong to different consumers. The URL parser separates their fields; the application schema decides which query values to use. Excluding the fragment from the request target is not a confidentiality control that prevents client code from sending it in a separate message.

Compare raw A+B with serialized q=A%2BB in the encoding branch. They are two representations of an ordinary value, not a new permission or an encrypted secret. A successful round trip verifies the selected API transformation, not an entire server input pipeline.

3. Blue · Secure development & defense

Read every scenario without motion

Encoding check

  1. Raw query values were selected

    Two ordinary values are selected for form serialization: A+B and notlar ı. These are raw inputs for URLSearchParams, not query strings. Interpret plus and percent text only after identifying the API representation that produced it.

    URL input evidence
    Raw: A+B / notlar ı
    Normalization review
    No serialization yet
    Observation scope
    No server observation
  2. Form serialization applies its own rules

    URLSearchParams represents literal + as %2B, space as +, and the UTF-8 bytes for ı as %C4%B1. This example yields q=A%2BB and q=notlar+%C4%B1. Raw input and the serialized query are different text forms.

    URL input evidence
    Raw: A+B / notlar ı
    Normalization review
    q=A%2BB / q=notlar+%C4%B1
    Observation scope
    No server observation
  3. Encoding was matched to its source value

    q=A%2BB preserves a literal plus; q=notlar+%C4%B1 represents a space and UTF-8 ı. Round-trip reconstructs the value without verifying an entire server pipeline.

    URL input evidence
    A+B ↔ q=A%2BB
    Normalization review
    q=A%2BB / q=notlar+%C4%B1
    Observation scope
    No claim scope
  4. Query multiplicity stayed in regression

    lang and two tag values are read separately; tags expects [network, web]. Fragment summary is not a query key/value and is excluded from HTTP origin-form.

    URL input evidence
    A+B ↔ q=A%2BB
    Normalization review
    Two tags / fragment excluded
    Observation scope
    No claim scope
  5. Observation retained only necessary data

    The catalog URL carries public locale/tag data. Real URLs can spread into history/log/telemetry, so scheme/host/path and needed schema fields are purpose-limited; URLs are not default persistent identity records.

    URL input evidence
    A+B ↔ q=A%2BB
    Normalization review
    Two tags / fragment excluded
    Observation scope
    Public fields / purpose-limited log
  6. Parser evidence did not replace network evidence

    Selected form round-trip and query multiplicity agree. Encoding establishes neither secrecy, input trust nor server acceptance.

    URL input evidence
    A+B ↔ q=A%2BB
    Normalization review
    Two tags / fragment excluded
    Observation scope
    Round-trip consistent / trust separate

Default port

  1. A URL with an explicit default port was selected

    The input is https://books.example:443/catalog. Its raw reference contains :443; href, hostname, port and origin getters are not yet read. Parsing is local here; there is no connection to the service.

    URL input evidence
    Raw https://books.example:443/catalog
    Normalization review
    Getter results pending
    Observation scope
    Network unmeasured
  2. The default port leaves serialization

    Because 443 is HTTPS’s default port, the native URL API returns an empty port getter and href=https://books.example/catalog. The service port has not vanished from this normalized representation; the scheme’s default still applies.

    URL input evidence
    Raw :443 retained for comparison
    Normalization review
    port=""; href=https://books.example/catalog
    Observation scope
    Network unmeasured
  3. The origin names the same default endpoint

    In this HTTP(S) example, origin is https://books.example. Path /catalog is not part of that origin. Explicit :443 and an implicit HTTPS default are different raw texts producing the same normalized origin.

    URL input evidence
    Raw :443 / normalized HTTPS URL
    Normalization review
    Origin https://books.example; default 443
    Observation scope
    Origin equality is not access permission
  4. A non-default port is a separate comparison

    The main catalogue input uses port 8443, which remains in serialization and produces origin https://books.example:8443. Comparing 443 with 8443 explains port normalization, not TLS or listener success.

    URL input evidence
    Comparison: default 443 / non-default 8443
    Normalization review
    443 empty getter / 8443 retained
    Observation scope
    No TLS/listener outcome
  5. The observation is produced by the URL API

    Href and getters are parsing outputs of the local URL API. Application scheme/port policy, DNS, TLS and HTTP outcomes come from different operations. Substituting parser output for them would report a computed address as an observed connection.

    URL input evidence
    Input and normalized output retained together
    Normalization review
    Producer: local URL API
    Observation scope
    Coverage limited to parsing
  6. An empty getter does not mean a portless service

    The default and non-default comparisons preserve their representation context. A separate relative parse without a base throws TypeError; successful default-port output is not copied into that failure. Network and permission outcomes remain unknown.

    URL input evidence
    Default/non-default/base requirement separate
    Normalization review
    Default port normalized; TypeError separate
    Observation scope
    Parser scope known; access unknown

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Use a consistent parser and explicit application policy

Use a standard parser, then evaluate application requirements such as allowed schemes, destinations, or ports against its structured output. Parsing success is not an allow decision, and query schema validation remains separate.

Keep raw input, normalized address, and policy results distinguishable in configuration and observations. Record parser acceptance and application acceptance separately; add network success only when measured.

Preserve data boundaries when logging and creating links

Avoid unnecessary secrets or personal data in queries: addresses can appear in logs, history, and telemetry. This fixture contains only public catalogue labels. Select necessary logging fields rather than treating every full URL as a persistent identity record.

Build links with URL and URLSearchParams, then verify the expected pathname, parameter multiplicity, and fragment separation using benign fixtures. Encoding should not be labeled a security control.

Keep the default-port case separate in lab observations. If a colleague mistakes the empty port getter for an absent service port, show the normalized href with its scheme. Fixing the representation used for logs or configuration helps interpret two text forms of the same destination correctly.

NOW APPLY IT TO THE CASE

Which consumer decisions involve query values, fragments and normalized ports?

Duru uses two tags in the Atlas catalog link. Fragment summary stays client-side while the server target contains path and query. URL parsing or encoding does not grant access to the destination.

Identify the case’s browser and API through URL components. Target, origin and site answer different questions; identify which decision uses each one.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

URL component and serialization ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "input": "https://books.example:8443/catalog/atlas?lang=tr&tag=network&tag=web#summary",
  "expected": {
    "protocol": "https:",
    "hostname": "books.example",
    "host": "books.example:8443",
    "port": "8443",
    "pathname": "/catalog/atlas",
    "search": "?lang=tr&tag=network&tag=web",
    "hash": "#summary",
    "origin": "https://books.example:8443",
    "tags": [
      "network",
      "web"
    ],
    "httpOriginForm": "/catalog/atlas?lang=tr&tag=network&tag=web"
  },
  "defaultPort": {
    "input": "https://books.example:443/catalog",
    "expectedPort": "",
    "expectedHref": "https://books.example/catalog"
  },
  "formEncoding": [
    {
      "value": "notlar ı",
      "expected": "q=notlar+%C4%B1"
    },
    {
      "value": "A+B",
      "expected": "q=A%2BB"
    }
  ],
  "relativeWithoutBase": {
    "input": "/catalog/atlas",
    "expectedError": "TypeError"
  },
  "networkRequestsExecuted": 0
}
input
Ordinary catalogue address parsed locally.
expected.host / expected.hostname
host includes the port; hostname excludes it.
expected.tags
getAll preserves repeated query values.
expected.httpOriginForm
Path/query candidate excluding the fragment; no actual request.
formEncoding
Form serialization and return to the raw value.

Synthetic inputs checked with the native Node URL API. No DNS, HTTP, TLS, DOM navigation, or server decoding executes.

Two reality checks

A parsed HTTPS address has a secure connection.

Parsing is local; DNS, TLS validation, and HTTP outcomes require separate evidence.

Encoding provides secrecy; fragments belong to the server-bound query.

Encoding is representation. An ordinary request target carries path/query; the fragment remains separate on the client.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

What information is lost if tag=network&tag=web is read as one value?

  1. The two distinct tag values and their order are lost.
  2. The second tag is a syntax error and must be discarded.
Read the explained answer

The two distinct tag values and their order are lost. — The fixture gives tags=[network, web]; repeating a query key is a valid data structure.

Why does the HTTP origin-form omit #summary?

Selected lesson artifact fields; teaching example

expected.host
books.example:8443
expected.hostname
books.example
expected.hash
#summary
expected.httpOriginForm
/catalog/atlas?lang=tr&tag=network&tag=web
  1. The fragment is a browser-side reference; the selected HTTP target is path+query.
  2. The fragment belongs to pathname and is sent as a server route.
Read the explained answer

The fragment is a browser-side reference; the selected HTTP target is path+query. — hash is a URL component; it is absent from this origin-form sent to the server.

Explain the form-encoding difference between A+B and notlar ı; why is percent encoding not encryption?

Read the explained answer

URLSearchParams form serialization represents space as +, literal plus as %2B, and ı as UTF-8 bytes %C4%B1. This is reversible representation syntax, providing neither a secret key nor confidentiality. A raw URL string should not be assumed to mean the same thing in different parsers/contexts.

□ I distinguished plus and space serialization.

□ I inferred no confidentiality from encoding.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

MANUAL LAB

URL Boundary Lab

Predict components, origin/site comparisons, and relative resolution before comparing native API output.

Open the prediction → observation → explanation workbook ↗Source on GitHub ↗

Sources and scope