<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Checklist on Tarragon</title><link>https://tarrragon.github.io/blog/tags/checklist/</link><description>Recent content in Checklist on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Fri, 19 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/checklist/index.xml" rel="self" type="application/rss+xml"/><item><title>安全敏感輸入框的 IME 控制 checklist</title><link>https://tarrragon.github.io/blog/ux-design/03-input-mechanism/ime-security-checklist/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/ux-design/03-input-mechanism/ime-security-checklist/</guid><description>&lt;p>IME（Input Method Editor）的個人化學習功能會從使用者輸入中學習新詞彙，存入 IME 詞庫，跨 app 適用。在處理 secret 的輸入框中，這個功能把密碼、API key、伺服器路徑等敏感資訊存入了 IME 的持久化儲存 — 其他 app 的使用者在輸入時可能在建議列表中看到這些內容。&lt;/p>
&lt;h2 id="為什麼是安全問題">為什麼是安全問題&lt;/h2>
&lt;p>&lt;code>enableIMEPersonalizedLearning&lt;/code> 控制的是 IME 是否從當前輸入框的內容學習新詞彙。預設值是 &lt;code>true&lt;/code> — IME 會學習使用者輸入的所有內容。&lt;/p>
&lt;p>在一般文字輸入場景中（聊天、筆記、email），IME 學習使用者的常用詞彙是合理的 — 提高打字效率，減少重複輸入。&lt;/p>
&lt;p>在 CLI 場景中（&lt;a href="https://tarrragon.github.io/blog/ux-design/cases/terminal-input-mechanism-absent/" data-link-title="U.C3 終端機文字輸入機制未設計、事後 hotfix 補 TextField" data-link-desc="Flutter 終端機 app 的鍵盤輸入完全未設計 — 沒有 TextField、沒有 keyboard type 選擇、沒有 IME 控制。W2 修復時才補上 TextField &amp;#43; 6 個參數（enableSuggestions/autocorrect/enableIMEPersonalizedLearning/keyboardType/textInputAction/onSubmitted），全是散落 hotfix">U.C3&lt;/a>），使用者可能輸入：&lt;/p>
&lt;ul>
&lt;li>資料庫密碼：&lt;code>mysql -p'MySecret123'&lt;/code>&lt;/li>
&lt;li>API key：&lt;code>curl -H 'Authorization: Bearer sk-abc123...'&lt;/code>&lt;/li>
&lt;li>伺服器路徑：&lt;code>ssh admin@192.168.1.100&lt;/code>&lt;/li>
&lt;li>環境變數：&lt;code>export DB_PASSWORD=secret&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>IME 學習這些輸入後，使用者在其他 app 打字時，IME 可能在建議列表中顯示 &lt;code>MySecret123&lt;/code> 或 &lt;code>sk-abc123&lt;/code> — 任何看到螢幕的人都能看到。&lt;/p>
&lt;p>這個風險和密碼外洩的傳統路徑不同。傳統密碼外洩通常是資料庫被入侵或傳輸被攔截；IME 學習造成的洩漏是使用者在日常打字時被動暴露，使用者不會意識到 IME 記住了他們在另一個 app 輸入的密碼。&lt;/p>
&lt;h2 id="checklist">Checklist&lt;/h2>
&lt;p>處理以下任何一類內容的輸入框，應全部通過此 checklist：&lt;/p>
&lt;ul>
&lt;li>密碼、PIN 碼&lt;/li>
&lt;li>API key、token、secret&lt;/li>
&lt;li>伺服器位址、連線字串&lt;/li>
&lt;li>CLI 指令（可能包含上述任何一類）&lt;/li>
&lt;li>信用卡號碼&lt;/li>
&lt;li>任何標示為 confidential 的欄位&lt;/li>
&lt;/ul>
&lt;h3 id="必須關閉的-ime-控制">必須關閉的 IME 控制&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>控制項&lt;/th>
 &lt;th>參數&lt;/th>
 &lt;th>理由&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>個人化學習&lt;/td>
 &lt;td>&lt;code>enableIMEPersonalizedLearning: false&lt;/code>&lt;/td>
 &lt;td>防止 secret 進入 IME 詞庫&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>自動校正&lt;/td>
 &lt;td>&lt;code>autocorrect: false&lt;/code>&lt;/td>
 &lt;td>防止 secret 被替換成字典詞&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>輸入建議&lt;/td>
 &lt;td>&lt;code>enableSuggestions: false&lt;/code>&lt;/td>
 &lt;td>防止 secret 出現在建議列表&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="建議的-keyboard-type">建議的 keyboard type&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>場景&lt;/th>
 &lt;th>Keyboard type&lt;/th>
 &lt;th>理由&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>密碼&lt;/td>
 &lt;td>visiblePassword&lt;/td>
 &lt;td>關閉自動校正，可選顯示/隱藏&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CLI 指令&lt;/td>
 &lt;td>visiblePassword&lt;/td>
 &lt;td>需要精確輸入，不要自動校正&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>信用卡號碼&lt;/td>
 &lt;td>number&lt;/td>
 &lt;td>只需要數字鍵盤&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>連線字串&lt;/td>
 &lt;td>url&lt;/td>
 &lt;td>有 &lt;code>.&lt;/code>、&lt;code>/&lt;/code>、&lt;code>:&lt;/code> 快捷鍵&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="code-review-檢查點">Code review 檢查點&lt;/h3>
&lt;p>Review 安全敏感輸入框的 TextField 實作時，逐項確認：&lt;/p>
&lt;ol>
&lt;li>&lt;code>enableIMEPersonalizedLearning&lt;/code> 是否明確設為 &lt;code>false&lt;/code>（不依賴預設值）&lt;/li>
&lt;li>&lt;code>autocorrect&lt;/code> 是否設為 &lt;code>false&lt;/code>&lt;/li>
&lt;li>&lt;code>enableSuggestions&lt;/code> 是否設為 &lt;code>false&lt;/code>&lt;/li>
&lt;li>&lt;code>keyboardType&lt;/code> 是否選擇了不會觸發自動行為的類型&lt;/li>
&lt;li>如果是密碼欄位，&lt;code>obscureText&lt;/code> 是否按需求設定&lt;/li>
&lt;/ol>
&lt;h2 id="平台差異">平台差異&lt;/h2>
&lt;p>&lt;code>enableIMEPersonalizedLearning&lt;/code> 是 Flutter 的 API，對應到不同平台的不同機制：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>iOS&lt;/strong>：對應 &lt;code>UITextField.spellCheckingType = .no&lt;/code> 和相關 attribute。iOS 的 QuickType 學習機制由系統控制，app 只能建議不強制。&lt;/li>
&lt;li>&lt;strong>Android&lt;/strong>：對應 &lt;code>InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS&lt;/code> 等 flag。不同 IME app（Gboard、Samsung Keyboard、搜狗）對 flag 的遵守程度不一。&lt;/li>
&lt;/ul>
&lt;p>平台差異意味著 app 端的控制是「盡力而為」— 設定正確的 flag 是必要條件，但不保證所有 IME 都會遵守。安全敏感場景中，除了 IME 控制外，還應考慮 secure text entry（&lt;code>obscureText: true&lt;/code>）讓畫面上不顯示明文。&lt;/p></description><content:encoded><![CDATA[<p>IME（Input Method Editor）的個人化學習功能會從使用者輸入中學習新詞彙，存入 IME 詞庫，跨 app 適用。在處理 secret 的輸入框中，這個功能把密碼、API key、伺服器路徑等敏感資訊存入了 IME 的持久化儲存 — 其他 app 的使用者在輸入時可能在建議列表中看到這些內容。</p>
<h2 id="為什麼是安全問題">為什麼是安全問題</h2>
<p><code>enableIMEPersonalizedLearning</code> 控制的是 IME 是否從當前輸入框的內容學習新詞彙。預設值是 <code>true</code> — IME 會學習使用者輸入的所有內容。</p>
<p>在一般文字輸入場景中（聊天、筆記、email），IME 學習使用者的常用詞彙是合理的 — 提高打字效率，減少重複輸入。</p>
<p>在 CLI 場景中（<a href="/blog/ux-design/cases/terminal-input-mechanism-absent/" data-link-title="U.C3 終端機文字輸入機制未設計、事後 hotfix 補 TextField" data-link-desc="Flutter 終端機 app 的鍵盤輸入完全未設計 — 沒有 TextField、沒有 keyboard type 選擇、沒有 IME 控制。W2 修復時才補上 TextField &#43; 6 個參數（enableSuggestions/autocorrect/enableIMEPersonalizedLearning/keyboardType/textInputAction/onSubmitted），全是散落 hotfix">U.C3</a>），使用者可能輸入：</p>
<ul>
<li>資料庫密碼：<code>mysql -p'MySecret123'</code></li>
<li>API key：<code>curl -H 'Authorization: Bearer sk-abc123...'</code></li>
<li>伺服器路徑：<code>ssh admin@192.168.1.100</code></li>
<li>環境變數：<code>export DB_PASSWORD=secret</code></li>
</ul>
<p>IME 學習這些輸入後，使用者在其他 app 打字時，IME 可能在建議列表中顯示 <code>MySecret123</code> 或 <code>sk-abc123</code> — 任何看到螢幕的人都能看到。</p>
<p>這個風險和密碼外洩的傳統路徑不同。傳統密碼外洩通常是資料庫被入侵或傳輸被攔截；IME 學習造成的洩漏是使用者在日常打字時被動暴露，使用者不會意識到 IME 記住了他們在另一個 app 輸入的密碼。</p>
<h2 id="checklist">Checklist</h2>
<p>處理以下任何一類內容的輸入框，應全部通過此 checklist：</p>
<ul>
<li>密碼、PIN 碼</li>
<li>API key、token、secret</li>
<li>伺服器位址、連線字串</li>
<li>CLI 指令（可能包含上述任何一類）</li>
<li>信用卡號碼</li>
<li>任何標示為 confidential 的欄位</li>
</ul>
<h3 id="必須關閉的-ime-控制">必須關閉的 IME 控制</h3>
<table>
  <thead>
      <tr>
          <th>控制項</th>
          <th>參數</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>個人化學習</td>
          <td><code>enableIMEPersonalizedLearning: false</code></td>
          <td>防止 secret 進入 IME 詞庫</td>
      </tr>
      <tr>
          <td>自動校正</td>
          <td><code>autocorrect: false</code></td>
          <td>防止 secret 被替換成字典詞</td>
      </tr>
      <tr>
          <td>輸入建議</td>
          <td><code>enableSuggestions: false</code></td>
          <td>防止 secret 出現在建議列表</td>
      </tr>
  </tbody>
</table>
<h3 id="建議的-keyboard-type">建議的 keyboard type</h3>
<table>
  <thead>
      <tr>
          <th>場景</th>
          <th>Keyboard type</th>
          <th>理由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>密碼</td>
          <td>visiblePassword</td>
          <td>關閉自動校正，可選顯示/隱藏</td>
      </tr>
      <tr>
          <td>CLI 指令</td>
          <td>visiblePassword</td>
          <td>需要精確輸入，不要自動校正</td>
      </tr>
      <tr>
          <td>信用卡號碼</td>
          <td>number</td>
          <td>只需要數字鍵盤</td>
      </tr>
      <tr>
          <td>連線字串</td>
          <td>url</td>
          <td>有 <code>.</code>、<code>/</code>、<code>:</code> 快捷鍵</td>
      </tr>
  </tbody>
</table>
<h3 id="code-review-檢查點">Code review 檢查點</h3>
<p>Review 安全敏感輸入框的 TextField 實作時，逐項確認：</p>
<ol>
<li><code>enableIMEPersonalizedLearning</code> 是否明確設為 <code>false</code>（不依賴預設值）</li>
<li><code>autocorrect</code> 是否設為 <code>false</code></li>
<li><code>enableSuggestions</code> 是否設為 <code>false</code></li>
<li><code>keyboardType</code> 是否選擇了不會觸發自動行為的類型</li>
<li>如果是密碼欄位，<code>obscureText</code> 是否按需求設定</li>
</ol>
<h2 id="平台差異">平台差異</h2>
<p><code>enableIMEPersonalizedLearning</code> 是 Flutter 的 API，對應到不同平台的不同機制：</p>
<ul>
<li><strong>iOS</strong>：對應 <code>UITextField.spellCheckingType = .no</code> 和相關 attribute。iOS 的 QuickType 學習機制由系統控制，app 只能建議不強制。</li>
<li><strong>Android</strong>：對應 <code>InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS</code> 等 flag。不同 IME app（Gboard、Samsung Keyboard、搜狗）對 flag 的遵守程度不一。</li>
</ul>
<p>平台差異意味著 app 端的控制是「盡力而為」— 設定正確的 flag 是必要條件，但不保證所有 IME 都會遵守。安全敏感場景中，除了 IME 控制外，還應考慮 secure text entry（<code>obscureText: true</code>）讓畫面上不顯示明文。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>四維度決策表總覽 → <a href="/blog/ux-design/03-input-mechanism/four-dimension-decision/" data-link-title="輸入機制決策表" data-link-desc="Keyboard type / submit model / IME policy / special keys 四個維度的決策框架 — 每個維度都是設計決策，影響 UI layout 和 protocol">輸入機制決策表</a></li>
<li>IME 個人化學習在 monitoring 中的安全考量 → <a href="/blog/monitoring/07-security-privacy/" data-link-title="模組七：資安與隱私" data-link-desc="SDK redaction / transport 加密 / collector access control / 去識別化 — 蒐集的資料本身就是風險資產">monitoring 模組七 資安</a></li>
<li>Terminal 場景的完整輸入設計 → <a href="/blog/ux-design/03-input-mechanism/terminal-input-design/" data-link-title="Terminal app 輸入設計" data-link-desc="CLI 場景在手機上的特殊需求 — 非自然語言輸入、特殊按鍵需求、整行 vs 逐字元送出對 protocol 的影響">Terminal app 輸入設計</a></li>
</ul>
]]></content:encoded></item></channel></rss>