The line  does not embed an image. It creates an image node whose destination still has to be resolved, fetched, allowed, and rendered by another system.
That distinction explains why a document can parse perfectly and still show broken images—or make network requests its author did not account for.
Parsing and URL resolution are separate stages
I fixed the experiment to Node 25.3.0 and Marked 18.0.7 with GFM enabled:
const html = marked.parse('');
// <p><img src="../assets/flow.png" alt="diagram" title="Flow"></p>
Marked preserves the destination. A browser or publisher later resolves it against a base URL:
new URL("../assets/flow.png", "https://docs.example.test/guides/setup/").href
// https://docs.example.test/guides/assets/flow.png
new URL("../assets/flow.png", "https://docs.example.test/guides/setup.html").href
// https://docs.example.test/assets/flow.png
Same Markdown, different request. The parser did its job in both cases.
Six cases that need different policies
| Input | Parser output | What the host must decide |
|---|---|---|
../assets/flow.png |
relative src
|
base URL and asset copy rules |
/assets/logo.svg |
root-relative src
|
which origin owns the root |
https://.../pixel.png?doc=42 |
absolute src
|
remote trust and request privacy |
data:image/... |
data URL | sanitizer and CSP policy |
| empty alt | alt="" |
decorative or accessibility defect |
| empty destination | src="" |
reject, rewrite, or host behavior |
CommonMark defines image syntax and maps the description to alt text. It does not upload files or promise that a URL exists.
Remote images are third-party dependencies
When HTML contains a remote <img src>, the browser requests that resource. The remote server observes the request; the page's Referrer Policy controls how much referring-page information is sent. Query parameters can also encode a document or campaign identifier.
Treat remote images like any other external dependency:
- allow only reviewed schemes and hosts;
- proxy or self-host assets when appropriate;
- set a deliberate Referrer Policy;
- restrict image sources with CSP
img-src; - sanitize final HTML after AST transformations;
- never put sensitive identifiers in image URLs.
Parser configuration cannot replace those controls.
Relative paths need a publishing contract
A stable workflow defines:
- where the Markdown file lives;
- what base URL the final page uses;
- how referenced assets are copied;
- whether root-relative paths are allowed;
- what happens when an image is missing.
If you are debugging a real document, this Markdown image path guide provides a concrete path checklist. The important step is to test the published URL, not just the editor preview.
Data URLs trade path stability for other costs
Data URLs avoid a separate file lookup, but they make source files larger and harder to review, prevent independent caching, and may be blocked by a sanitizer or CSP. They are reasonable for small controlled assets, not a universal fix for image portability.
Validate the final request graph
My recommended pipeline is:
- parse Markdown to an AST;
- inspect image destinations;
- resolve them against the declared publication base;
- validate scheme, host, path, and query;
- copy or rewrite managed assets;
- sanitize rendered HTML and apply CSP/referrer policy;
- open the public page and verify actual responses and layout.
The AST tells you what the author referenced. URL resolution tells you where it points. A browser test tells you what really happened.
Should Markdown hosts block cross-origin images by default, or preserve compatibility and require each application to opt into a stricter policy?
Top comments (0)