CVE-2013-4509: Credentials Management Errors (CWE-255)
value: The default configuration of IBUS 1.5.4, and possibly 1.5.2 and earlier, when IBus.InputPurpose.PASSWORD is not set and used with GNOME 3, does not obscure the entered password characters, which allows physically proximate attackers to obtain a user password by reading the lockscreen.
CWE description: Weaknesses in this category are related to the management of credentials.
Published: 2013-11-23T19:55Z
Repository: https://github.com/ibus/ibus-anthy
Language: Python
Files changed: engine/engine.py
Commit date: 2013-08-30 11:13:31 +0900
Commit message: Added to check the input purpose for gnome-shell password dialog.

Diff: diff --git a/engine/engine.py b/engine/engine.py
index a42f642..be66738 100644
--- a/engine/engine.py
+++ b/engine/engine.py
@@ -124,10 +124,14 @@ class Engine(IBus.EngineSimple):
         self.__context.set_encoding(Anthy.UTF8_ENCODING)
 
         # init state
         self.__idle_id = 0
         self.__prop_dict = {}
+        self.__input_purpose = 0
+        self.__has_input_purpose = False
+        if hasattr(IBus, 'InputPurpose'):
+            self.__has_input_purpose = True
         try:
             self.__is_utf8 = (getpreferredencoding().lower() == 'utf-8')
         except:
             self.__is_utf8 = False
         self.__ibus_version = 0.0
@@ -961,15 +965,21 @@ class Engine(IBus.EngineSimple):
         size = self.__prefs.get_value('common', 'page_size')
         if size != self.__lookup_table.get_page_size():
             self.__lookup_table.set_page_size(size)
 
     def do_focus_out(self):
+        if self.__has_input_purpose:
+            self.__input_purpose = 0
         mode = self.__prefs.get_value('common', 'behavior_on_focus_out')
         if mode == 0 or mode == 1:
             self.__reset()
             self.__invalidate()
 
+    def do_set_content_type(self, purpose, hints):
+        if self.__has_input_purpose:
+            self.__input_purpose = purpose
+
     def do_disable(self):
         self.__reset()
         self.__invalidate()
 
     def do_reset(self):
@@ -1805,10 +1815,14 @@ class Engine(IBus.EngineSimple):
                         return True
                     return False
         return True
 
     def __process_key_event_internal2(self, keyval, keycode, state):
+        if self.__has_input_purpose and \
+           self.__input_purpose == IBus.InputPurpose.PASSWORD:
+            return False
+
         if Engine.__typing_mode == jastring.TYPING_MODE_THUMB_SHIFT and \
            Engine.__input_mode not in [INPUT_MODE_LATIN, INPUT_MODE_WIDE_LATIN]:
             return self.process_key_event_thumb(keyval, keycode, state)
 
         is_press = (state & IBus.ModifierType.RELEASE_MASK) == 0

Fixed code:         self.__input_purpose = 0
        self.__has_input_purpose = False
        if hasattr(IBus, 'InputPurpose'):
            self.__has_input_purpose = True
        if self.__has_input_purpose:
            self.__input_purpose = 0
    def do_set_content_type(self, purpose, hints):
        if self.__has_input_purpose:
            self.__input_purpose = purpose

        if self.__has_input_purpose and \
           self.__input_purpose == IBus.InputPurpose.PASSWORD:
            return False