Closed julianfairfax closed 4 months ago
Could you please create an entry both in Secrets and another app (e.g. keepassxc) with the same fields and same values and dump the contents of said entry (in xml format) of both?
Here: Tests.zip
I can already tell you what the problem is though: Secrets sets ProtectInMemory
to True
for all fields.
How Secrets looks:
<String>
<Key>Notes</Key>
<Value ProtectInMemory="True">test</Value>
</String>
<String>
<Key>Password</Key>
<Value ProtectInMemory="True">test</Value>
</String>
<String>
<Key>Title</Key>
<Value ProtectInMemory="True">Test</Value>
</String>
<String>
<Key>URL</Key>
<Value ProtectInMemory="True">https://example.com</Value>
</String>
<String>
<Key>UserName</Key>
<Value ProtectInMemory="True">test@example.com</Value>
</String>
How it's supposed to look:
<String>
<Key>Notes</Key>
<Value>test</Value>
</String>
<String>
<Key>Password</Key>
<Value ProtectInMemory="True">test</Value>
</String>
<String>
<Key>Title</Key>
<Value>Test</Value>
</String>
<String>
<Key>URL</Key>
<Value>https://example.com</Value>
</String>
<String>
<Key>UserName</Key>
<Value>test@example.com</Value>
</String>
What suggests it should look like that? I couldn't find the docs for this protectmemory attribute.
Should this be moved to the Secrets issues? ProtectInMemory
in not something that is set in PyKeePass.
Its not something I set either afaik, how would I even begin doing it?
I mean, if that's the case then sure.
What suggests it should look like that? I couldn't find the docs for this protectmemory attribute.
The fact that this attribute determines if a field is hidden or not, and only the password field should be hidden.
What suggests it should look like that? I couldn't find the docs for this protectmemory attribute.
The fact that this attribute determines if a field is hidden or not, and only the password field should be hidden.
Where does it say that it should be hidden? Without extra information , this might be a stylistic choice made on the other apps.
What suggests it should look like that? I couldn't find the docs for this protectmemory attribute.
The fact that this attribute determines if a field is hidden or not, and only the password field should be hidden.
Where does it say that it should be hidden? Without extra information , this might be a stylistic choice made on the other apps.
OFC it's a stylistic choice, but these other apps (at least KeePassVault) uses this attribute to determine which fields to hide. GNOME Secrets seems to make the technical choice of adding it to all fields for some reason. cc @aivanovski
We dont use any internals of pykeepass, @Evidlo is there any public api to set this?
There's no API for this attribute. I haven't seen ProtectInMemory
before, only Protected
.
Here's what a newly created entry looks like.
>>> from pykeepass import PyKeePass; kp = PyKeePass('test4.kdbx', 'password', 'test4.key')
>>> g = kp.groups[3]
>>> kp.add_entry(g, 'banana_entry', 'user', 'pass')
Entry: "foobar_group/subgroup/subgroup2/banana_entry (user)"
>>> kp.dump_xml('/tmp/dump.xml')
<Entry>
<UUID>KjVPGNbWEe6C170xALbYkw==</UUID>
<Times>
<CreationTime>hSxy3Q4AAAA=</CreationTime>
<LastModificationTime>hSxy3Q4AAAA=</LastModificationTime>
<LastAccessTime>hSxy3Q4AAAA=</LastAccessTime>
<ExpiryTime>hSxy3Q4AAAA=</ExpiryTime>
<Expires>False</Expires>
<UsageCount>0</UsageCount>
<LocationChanged>hSxy3Q4AAAA=</LocationChanged>
</Times>
<String>
<Key>Title</Key>
<Value>banana_entry</Value>
</String>
<String>
<Key>UserName</Key>
<Value>user</Value>
</String>
<String>
<Key>Password</Key>
<Value Protected="True">pass</Value>
</String>
<AutoType>
<Enabled>True</Enabled>
<DataTransferObfuscation>0</DataTransferObfuscation>
<DefaultSequence></DefaultSequence>
<Association>
<Window></Window>
<KeystrokeSequence></KeystrokeSequence>
</Association>
</AutoType>
</Entry>
Thanks for the info.
I will take a look later and test it locally. I mean, we don't use any internal API (they would error out in CI) so I seriously cannot even begin to image how this is being set on our side. At least grep
ing for it does not reveal any results.
I dumped the xml of my testing db. Then I created a new db with a single entry, saved it and dumped it. ProtectInMemory
is not in any of the two dumps. Bellow is the dump of the newly created DB. Both were dumped using the xml()
function from pykeepass.
<?xml version='1.0' encoding='' standalone='yes'?>
<KeePassFile>
<Meta>
<Generator>KeePassXC</Generator>
<DatabaseName/>
<DatabaseNameChanged>jV0X0w4AAAA=</DatabaseNameChanged>
<DatabaseDescription/>
<DatabaseDescriptionChanged>jV0X0w4AAAA=</DatabaseDescriptionChanged>
<DefaultUserName/>
<DefaultUserNameChanged>jV0X0w4AAAA=</DefaultUserNameChanged>
<MaintenanceHistoryDays>365</MaintenanceHistoryDays>
<Color/>
<MasterKeyChanged>PeBy3Q4AAAA=</MasterKeyChanged>
<MasterKeyChangeRec>-1</MasterKeyChangeRec>
<MasterKeyChangeForce>-1</MasterKeyChangeForce>
<MemoryProtection>
<ProtectTitle>False</ProtectTitle>
<ProtectUserName>False</ProtectUserName>
<ProtectPassword>True</ProtectPassword>
<ProtectURL>False</ProtectURL>
<ProtectNotes>False</ProtectNotes>
</MemoryProtection>
<CustomIcons/>
<RecycleBinEnabled>True</RecycleBinEnabled>
<RecycleBinUUID>AAAAAAAAAAAAAAAAAAAAAA==</RecycleBinUUID>
<RecycleBinChanged>jV0X0w4AAAA=</RecycleBinChanged>
<EntryTemplatesGroup>AAAAAAAAAAAAAAAAAAAAAA==</EntryTemplatesGroup>
<EntryTemplatesGroupChanged>jV0X0w4AAAA=</EntryTemplatesGroupChanged>
<LastSelectedGroup>AAAAAAAAAAAAAAAAAAAAAA==</LastSelectedGroup>
<LastTopVisibleGroup>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleGroup>
<HistoryMaxItems>10</HistoryMaxItems>
<HistoryMaxSize>6291456</HistoryMaxSize>
<SettingsChanged>LV4X0w4AAAA=</SettingsChanged>
</Meta>
<Root>
<Group>
<UUID>14J2CaBO8I7R8zfVcxq3cw==</UUID>
<Name>Root</Name>
<Notes/>
<IconID>48</IconID>
<Times>
<LastModificationTime>S+By3Q4AAAA=</LastModificationTime>
<CreationTime>jV0X0w4AAAA=</CreationTime>
<LastAccessTime>S+By3Q4AAAA=</LastAccessTime>
<ExpiryTime>jV0X0w4AAAA=</ExpiryTime>
<Expires>False</Expires>
<UsageCount>0</UsageCount>
<LocationChanged>jV0X0w4AAAA=</LocationChanged>
</Times>
<IsExpanded>True</IsExpanded>
<DefaultAutoTypeSequence/>
<EnableAutoType>null</EnableAutoType>
<EnableSearching>null</EnableSearching>
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
<Entry>
<UUID>UVPBZ9dBEe6UDeOkO1CbvQ==</UUID>
<IconID>0</IconID>
<Times>
<CreationTime>S+By3Q4AAAA=</CreationTime>
<LastModificationTime>T+By3Q4AAAA=</LastModificationTime>
<LastAccessTime>T+By3Q4AAAA=</LastAccessTime>
<ExpiryTime>S+By3Q4AAAA=</ExpiryTime>
<Expires>False</Expires>
<UsageCount>0</UsageCount>
<LocationChanged>S+By3Q4AAAA=</LocationChanged>
</Times>
<String>
<Key>UserName</Key>
<Value></Value>
</String>
<String>
<Key>Password</Key>
<Value Protected="True"></Value>
</String>
<AutoType>
<Enabled>True</Enabled>
<DataTransferObfuscation>0</DataTransferObfuscation>
<DefaultSequence></DefaultSequence>
<Association>
<Window></Window>
<KeystrokeSequence></KeystrokeSequence>
</Association>
</AutoType>
<String>
<Key>Title</Key>
<Value Protected="True">asdf</Value>
</String>
<String>
<Key>URL</Key>
<Value Protected="True">test</Value>
</String>
</Entry>
</Group>
<DeletedObjects/>
</Root>
</KeePassFile>
EDIT: This was done with the nightly build of Secrets. But I don't think the result will change much if using an older stable release.
By this point I am quite certain the issue does not lie in pykeepass. If you think the issue lies in Secrets open the issue there with steps to reproduce.
(Maybe the real question is:) @aivanovski why do you hide all fields with that attribute set to true?
I've created new database in keepassxc, it also uses ProtectInMemory
attribute and sets it by default only to password and any custom attribute that user marks as protected.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<KeePassFile>
<Meta>
<Generator>KeePassXC</Generator>
<DatabaseName>test-protected</DatabaseName>
<DatabaseNameChanged>WJlz3Q4AAAA=</DatabaseNameChanged>
<DatabaseDescription/>
<DatabaseDescriptionChanged>P5lz3Q4AAAA=</DatabaseDescriptionChanged>
<DefaultUserName/>
<DefaultUserNameChanged>P5lz3Q4AAAA=</DefaultUserNameChanged>
<MaintenanceHistoryDays>365</MaintenanceHistoryDays>
<Color/>
<MasterKeyChanged>Z5lz3Q4AAAA=</MasterKeyChanged>
<MasterKeyChangeRec>-1</MasterKeyChangeRec>
<MasterKeyChangeForce>-1</MasterKeyChangeForce>
<MemoryProtection>
<ProtectTitle>False</ProtectTitle>
<ProtectUserName>False</ProtectUserName>
<ProtectPassword>True</ProtectPassword>
<ProtectURL>False</ProtectURL>
<ProtectNotes>False</ProtectNotes>
</MemoryProtection>
<CustomIcons/>
<RecycleBinEnabled>True</RecycleBinEnabled>
<RecycleBinUUID>AAAAAAAAAAAAAAAAAAAAAA==</RecycleBinUUID>
<RecycleBinChanged>P5lz3Q4AAAA=</RecycleBinChanged>
<EntryTemplatesGroup>AAAAAAAAAAAAAAAAAAAAAA==</EntryTemplatesGroup>
<EntryTemplatesGroupChanged>P5lz3Q4AAAA=</EntryTemplatesGroupChanged>
<LastSelectedGroup>AAAAAAAAAAAAAAAAAAAAAA==</LastSelectedGroup>
<LastTopVisibleGroup>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleGroup>
<HistoryMaxItems>10</HistoryMaxItems>
<HistoryMaxSize>6291456</HistoryMaxSize>
<SettingsChanged>P5lz3Q4AAAA=</SettingsChanged>
<CustomData>
<Item>
<Key>KPXC_DECRYPTION_TIME_PREFERENCE</Key>
<Value>100</Value>
</Item>
<Item>
<Key>_LAST_MODIFIED</Key>
<Value>Fri Mar 1 09:39:41 2024 GMT</Value>
</Item>
</CustomData>
</Meta>
<Root>
<Group>
<UUID>pACcbU9uRCunpFzwQbJiBA==</UUID>
<Name>Root</Name>
<Notes/>
<IconID>48</IconID>
<Times>
<LastModificationTime>uplz3Q4AAAA=</LastModificationTime>
<CreationTime>P5lz3Q4AAAA=</CreationTime>
<LastAccessTime>uplz3Q4AAAA=</LastAccessTime>
<ExpiryTime>P5lz3Q4AAAA=</ExpiryTime>
<Expires>False</Expires>
<UsageCount>0</UsageCount>
<LocationChanged>P5lz3Q4AAAA=</LocationChanged>
</Times>
<IsExpanded>True</IsExpanded>
<DefaultAutoTypeSequence/>
<EnableAutoType>null</EnableAutoType>
<EnableSearching>null</EnableSearching>
<LastTopVisibleEntry>AAAAAAAAAAAAAAAAAAAAAA==</LastTopVisibleEntry>
<Entry>
<UUID>r4puvraFQ/G1R9MD+t8V0Q==</UUID>
<IconID>0</IconID>
<ForegroundColor/>
<BackgroundColor/>
<OverrideURL/>
<Tags/>
<Times>
<LastModificationTime>uplz3Q4AAAA=</LastModificationTime>
<CreationTime>cplz3Q4AAAA=</CreationTime>
<LastAccessTime>uplz3Q4AAAA=</LastAccessTime>
<ExpiryTime>cplz3Q4AAAA=</ExpiryTime>
<Expires>False</Expires>
<UsageCount>0</UsageCount>
<LocationChanged>uplz3Q4AAAA=</LocationChanged>
</Times>
<String>
<Key>Notes</Key>
<Value>Apple is evil</Value>
</String>
<String>
<Key>Password</Key>
<Value ProtectInMemory="True">abc123</Value>
</String>
<String>
<Key>Title</Key>
<Value>Apple credentials</Value>
</String>
<String>
<Key>URL</Key>
<Value>https://apple.com</Value>
</String>
<String>
<Key>UserName</Key>
<Value>john.doe@example.com</Value>
</String>
<String>
<Key>custom</Key>
<Value ProtectInMemory="True">protected value</Value>
</String>
<AutoType>
<Enabled>True</Enabled>
<DataTransferObfuscation>0</DataTransferObfuscation>
<DefaultSequence/>
</AutoType>
<History/>
</Entry>
</Group>
<DeletedObjects/>
</Root>
</KeePassFile>
I don't understand the different between Protected
and ProtectInMemory
(which was introduced here).
Anyway, it seems clear that pykeepass isn't marking anything as protected by default except the password
field. Open another issue if ProtectInMemory
is a problem in other ways.
See https://github.com/aivanovski/keepassvault/issues/208. All fields of items created in GNOME Secrets are shown as hidden in apps such as KeePassVault. Here is a test file: Test.zip. cc @aivanovski @A6GibKm