uttrflow / uttrflow/uttrflow-swift

Words dictated into a password field are saved to history, recorded as a clip and left on the clipboard

Open
#610 0 comments 0 reactions 0 assignees View on GitHub
area:dictation bug P0 security
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

The suggestion side refuses secure fields before reading anything. `FocusedFieldReader.snapshot` checks `SecureField.isDeclaredSecure` before it fetches the value (`Sources/UttrflowContext/FocusedFieldReader+System.swift:129-134`), and `Sources/UttrflowPredict/SecureField.swift` says its contents are "never read, stored, or drawn from".

The dictation side has no such check anywhere:

```
$ git grep -n -i "secure" -- Sources/UttrflowPipeline Sources/UttrflowInput Sources/UttrflowHistory Sources/UttrflowContext/MacContextEngine+System.swift
(no output)
```

So a dictation into a password field or a PIN box goes the normal way:

- **Context.** `MacContextEngine.read` (`Sources/UttrflowContext/MacContextEngine+System.swift:45-53`) copies the focused field's `kAXValueAttribute` and selected text as context for clean-up. Most secure fields publish dots, but a custom field that does not declare itself secure publishes the real value.
- **Insertion.** If the field refuses the Accessibility write, the paste strategy writes the words to the general pasteboard as a plain string, with no concealed type (`Sources/UttrflowInput/SystemInput.swift:34-39`), and deliberately leaves them there (`PasteboardTextInsertionEngine.swift:49`).
- **History.** `AppDelegate` files the dictation as a `DictationRecord` (`Sources/Uttrflow/AppDelegate.swift:1145-1162`).
- **Clipboard history.** It also records the words as an Uttrflow clip (`AppDelegate.swift:1164`), as ordinary text.

## Why it matters

Some people do dictate a passphrase or a one-time code, especially when typing is hard for them. The result is that secret in plain text in two stores and on the clipboard, where any app can read it, when the clipboard side already goes out of its way to keep concealed items out (#371).

## How to reproduce

1. Open any app's password field (for example a login sheet).
2. Dictate a phrase.
3. The phrase appears in the main window's history, in the clipboard panel as a dictation clip, and (if the paste route was used) `pbpaste` prints it.

## Acceptance criteria

- The dictation pipeline asks the same `SecureField` question the suggestion reader asks, at the start of the recording and again just before insertion, and does so without reading the value of a field that declares itself secure.
- For a secure destination: no context is read; the text is inserted; the history row keeps only the app, time and length (or nothing, a product decision to record in the PR); no Uttrflow clip is recorded; and a clipboard write carries `org.nspasteboard.ConcealedType`.
- Tests in the pipeline and `AppDelegate`-adjacent presenter layers cover a secure destination for each of the stores above.

Contributor guide

Open the contributing guide

Research direction

Start with SecureField.isDeclaredSecure in Sources/UttrflowContext/FocusedFieldReader+System.swift and trace dictation through MacContextEngine+System.swift, SystemInput.swift, PasteboardTextInsertionEngine.swift, and AppDelegate.swift. Add pipeline and AppDelegate-adjacent presenter tests for secure destinations. Done means secure fields are not read, text is inserted, sensitive history and clips are omitted or minimized, and clipboard writes use ConcealedType.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
desktop, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.