typst / typst/typst

Restrict import paths to static string literals

Open
#8,377 5 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

change request scripting
Dominant language
Rust
Stars
56.1k
Forks
1.7k
Avg merge
3d 10h
Merged PRs (30d)
22

Description

Typst currently allows code like this:

#let source = "@preview/northern-suite:0.1.0"
#import source: *

If the import path can be any runtime expression, evaluated during compilation, it can encode data based on the document contents, and a sequence of network requests becomes a covert exfiltration channel. Users shouldn't have to unconditionally trust a package registry for this not to be a problem, yet that trust assumption grows more fraught as the ecosystem expands. Both #1982 (multiple/alternative package repositories) and #4040 (Git-hosted packages) would expand the network attack surface significantly. On top of that, this theoretically requires no registry compromise at all, as package request URLs could be visible to any passive observer on the same network.

I'd like to suggest addressing this by requiring all import paths be string literals, resolvable at parse time before compilation begins. This enables a clean preflight stage where all dependencies are known and resolved under the host's control, before the compiler touches the document.

This is the standard model in modern compiled languages. For security, Rust, Go, and others require dependencies to be declared statically and resolved by tooling before the compiler runs.

Typst already parses documents into a syntax tree before evaluation. This is the natural stage at which imports should be resolved, as all dependencies are visible and enumerable before a single line executes.

Implementation-wise, perhaps this would belong in the World interface. Since World is already the boundary between the compiler and the host environment, import resolution is conceptually its responsibility. And if advanced users specifically need dynamic imports for some reason, a host could theoretically provide a World implementation that permits it. The default and canonical behavior, however, should be static-only.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the World interface and trace how the syntax tree moves from parsing into evaluation, focusing on where imports are currently resolved. Check how the preflight stage could enumerate dependencies before compilation and how a runtime expression reaches import resolution. Done means import paths are restricted to static string literals and dependencies are known before evaluation begins.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.