Datasette removes untrusted text from error messages
Datasette 0.64.8 stops repeating URL path text on missing-resource pages. The same release improves parameter discovery after SQLite changed its diagnostic bytecode output.
Escaping text prevents a browser from interpreting it as HTML, but the text can still mislead a reader. Datasette 0.64.8 addresses that distinction by removing URL-derived detail from its 404 messages. A crafted path could previously make a page on a legitimate Datasette site display instructions supplied by the person who constructed the URL.
The June 21 release describes the risk as misleading information. It also backports an improved correction for discovering named SQL parameters with SQLite 3.46.0. These are separate fixes, but both concern information that crosses an interface with more authority or stability than its origin justifies.
I value SQLite as a component that keeps data access straightforward. Datasette adds a human-facing interface around that component, where the meaning readers assign to a page becomes part of correctness. The database can behave perfectly while the surrounding application gives a user's text the appearance of an official error message.
The page gives text an apparent author
The security issue explicitly says the old messages escaped their content. The report therefore does not identify cross-site scripting. Its example instead puts an instruction to visit another website into the name of a missing database. Datasette then repeats that name inside its own error page.
A reader arriving at the crafted URL sees a familiar site displaying a database-not-found message. The repeated path can contain text that resembles an operational notice. The attacker does not need the browser to execute the text as code for it to become confusing. Its position inside an application-generated message supplies the apparent credibility.
Simon Willison's investigation finds the same behavior in missing-table and missing-row messages. That breadth matters because removing one database-name interpolation would leave other routes with the same communication problem. The fix removes the reflected details, leaving the resource category as the useful explanation of failure.
There is a diagnostic tradeoff. Repeating the requested name can help a developer see which identifier failed. On a public error page, however, the request already contains that identifier, and the server has not established that the words in it are an appropriate message to another user. A short generic error preserves the failure's meaning without publishing arbitrary path text as part of the explanation.
Text safety extends beyond markup
HTML escaping remains necessary where an application renders untrusted text. This issue demonstrates a different question about what the interface should display at all. A string can be safe for the browser's parser and still be unsuitable for the role the page assigns it.
The distinction is especially relevant to links shared between people. One person controls the path, while another person supplies the trust they already have in the destination site. When the destination repeats the path inside a message, it can unintentionally combine those two inputs. The displayed instruction looks as though the destination authored it.
I prefer the release's narrow description because it preserves this mechanism. Calling every reflected-string issue XSS would imply browser behavior that the report explicitly rules out. The actual correction is still useful. It reduces an opportunity to confuse readers without claiming an exploit the evidence does not show.
Parameter discovery depended on diagnostic output
The other fix begins with a canned query containing a named parameter. In issue 2353, the query uses :table to select metadata from SQLite's schema table. Datasette needs to identify the parameter before it can present the corresponding input to a user.
The earlier discovery code examined EXPLAIN output, selected Variable instructions, and read the parameter name from the instruction's p4 field. With SQLite 3.46.0, the reported output contains None in that field. Calling .lstrip() on it raises an AttributeError before the query interface can complete its work.
The query itself is not necessarily invalid. The application has inferred a public-facing input contract from diagnostic details of SQLite's execution program. That dependency can fail even while SQLite still accepts the parameterized statement. The issue discussion acknowledges that opcodes are not a stable interface for this purpose.
The report also notes that the code already had a fallback, but did not catch this particular exception. A fallback only helps when execution actually reaches it. Assuming a diagnostic field has a string value prevented that recovery route from doing its job.
A maintenance release repairs two different assumptions
Version 0.64.8 calls its parameter change a better backported fix, following the earlier maintenance work discussed in the issue. The release source shows the replacement mechanism. It removes SQL comments and quoted strings before extracting named parameters from the remaining text with a regular expression. Discovery no longer depends on the parameter name appearing in an execution opcode. The important application behavior is successful parameter extraction against SQLite 3.46.0. Treating the failure as a reason to alter the user's SQL would address the wrong contract.
The security correction similarly leaves valid resource lookup separate from error presentation. A missing name should remain a missing resource, but its arbitrary contents need not become part of the site's explanation. In each case the correction belongs at the point where the application interprets information supplied by another component.
For me, these are worthwhile maintenance changes because neither requires a large new feature to affect users. One restores a query interface after an engine upgrade. The other changes what a reader can reasonably attribute to the site when a request fails. The release preserves useful failure information while removing request text that the site has no reason to endorse.