Complete the privacy notice, and stop user text reaching logs - #36
Merged
Conversation
Two things the DPIA needs before it can be submitted honestly. The privacy notice was missing four Article 13 essentials: it never identified the controller, gave no lawful basis, listed only access and erasure among the rights, and offered no route to the ICO. The transparency answer in the assessment rests entirely on that page, and it is the first thing an assessor opens. It now names the University of Edinburgh as controller with its ICO registration; states Article 6(1)(e) public task, grounded in the Universities (Scotland) Acts 1858 to 1966 and the Further and Higher Education (Scotland) Act 2005, with consent for an optionally attached transcript; gives the full rights list and how to use the response identifier; and gives the ICO complaint route. Article 6(3) attaches to the task rather than to the individual processing activity, so no statutory power naming this service is needed. Legitimate interests was considered and is not available: Article 6(1) provides that points (ea) and (f) do not apply to processing carried out by a public authority in the performance of its tasks, and the IP address held for abuse prevention exists solely to keep a public-task service available. The notice also now says the service reads from PubMed and bioRxiv and what is sent to them. Not an Article 13 disclosure, since no personal data goes, but the page describes how answers are built and should not leave it out. Then three places user-derived text was reaching somewhere it should not, all found by re-reading the code rather than the documentation. Blocked hostnames were kept by NAME for 26 months. They are extracted from a user's question by regex, so a fragment of what someone wrote sat in the long-retention tier. Now a count. The names remain in the 30-day security and blocked-search logs, which is where an abuse investigation would look. A failing tool logged its arguments by shape and the upstream error verbatim beside them. get_reviewed_page takes a URL whose path is unconstrained - only the host is allow-listed - and the fetcher throws it back in the message, so the redaction was defeated by the value next to it. Errors now go through safeText at all five sites. The argument value test was "contains no whitespace", which a URL and a 70-character lab identifier both pass. It is now identifier-shaped: 40 characters, no path separators. Real VFB vocabulary still prints, so the diagnostic keeps its value. The leak guard caught none of these: it planted its canary only in the question and the term name, and its tool-failure case threw an error containing no user text. Two new cases close both paths. Also: pass NCBI_EMAIL through docker-compose, which was set on the server but never reached the container because Compose forwards only what is listed; and name personal data in the chat's opening guidance, which said only confidential or sensitive.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things the DPIA needs before it can be submitted honestly. Both were found
by re-reading the code rather than the documentation.
The privacy notice
It was missing four Article 13 essentials: it never identified the controller,
gave no lawful basis, listed only access and erasure among the rights, and
offered no route to the ICO. The transparency answer in the assessment rests
entirely on that page, and it is the first thing an assessor opens.
It now names the University of Edinburgh as controller with its ICO registration;
states Article 6(1)(e) public task, grounded in the Universities (Scotland) Acts
1858 to 1966 and the Further and Higher Education (Scotland) Act 2005, with
consent for an optionally attached transcript; gives the full rights list and how
to use the response identifier; and gives the ICO complaint route.
Article 6(3) attaches to the task rather than to the individual processing
activity, so no statutory power naming this service is needed. Legitimate
interests was considered and is not available: Article 6(1) provides that points
(ea) and (f) do not apply to processing carried out by a public authority in the
performance of its tasks, and the IP address held for abuse prevention exists
solely to keep a public-task service available.
The notice also now says the service reads from PubMed and bioRxiv and what is
sent to them — not an Article 13 disclosure, since no personal data goes, but the
page describes how answers are built and should not leave it out.
Three places user-derived text was going somewhere it should not
Blocked hostnames were kept by name for 26 months. They are extracted from a
user's question by regex, so a fragment of what someone wrote sat in the
long-retention tier. Now a count. The names remain in the 30-day security and
blocked-search logs, which is where an abuse investigation would look.
A failing tool logged its arguments by shape and the upstream error verbatim
beside them.
get_reviewed_pagetakes a URL whose path is unconstrained — onlythe host is allow-listed — and the fetcher throws it back in the message, so the
redaction was defeated by the value next to it. Errors now go through
safeTextat all five sites.
The argument value test was "contains no whitespace", which a URL and a
70-character lab identifier both pass. It is now identifier-shaped: 40
characters, no path separators. Real VFB vocabulary still prints, so the
diagnostic keeps its value.
The leak guard caught none of these — it planted its canary only in the question
and the term name, and its tool-failure case threw an error containing no user
text. Two new cases close both paths.
Also
NCBI_EMAILis passed throughdocker-compose.yml; it was set on the server butnever reached the container, because Compose forwards only what is listed. And
the chat's opening guidance now names personal data, where it said only
"confidential or sensitive".
Note on the branch
This replaces an earlier branch cut before #34 and #35 merged. That branch had
picked up two CI-generated task-battery result files, and its
app/page.jswas apre-#34 snapshot — merging it would have reverted #34's two contrast fixes. This
is one clean commit on top of
783c1fb, with only the single welcome-messageline applied to
app/page.js.Verification
node --test tests/unit/*.test.mjs— 1279 pass, 0 failnode scripts/a11y-audit.mjs— 0 violations across all five targets, includingthe answered state
next buildclean