Skip to content

Instantly share code, notes, and snippets.

@jonarchist
Last active April 13, 2023 20:00
Show Gist options
  • Save jonarchist/fa8bb9f1513af54baa95aecfa2e569eb to your computer and use it in GitHub Desktop.
Save jonarchist/fa8bb9f1513af54baa95aecfa2e569eb to your computer and use it in GitHub Desktop.
Exporting Safari website passwords to a CSV file (1Password-compatible)

I'm a new 1Password user and recently tried to export all my passwords saved in iCloud Keychain to import them in 1Password. Unfortunately, none of the existing recipes worked for me, because moving the saved passwords from iCloud Keychain to a local keychain seems to be broken as of today (28 Aug 2018). So I came up with a different method.

This method works entirely using AppleScript, and only for website passwords (not for other kinds of logins such as file servers, etc.). Basically, the script toggles back and forth between Safari's Preferences window and TextEdit, copying each username and password combination via the clipboard.

Full instructions:

  1. If you have iCloud Keychain enabled, you might want to disable it temporarily, so that on the off chance that your passwords get corrupted, the changes won't propagate to the cloud.
  2. Make sure you have an up-to-date backup of your computer, including the keychain.
  3. Ensure that automatic backups are turned off, so that the plain text file we're going to create containing your passwords won't end up being backuped.
  4. Open Script Editor, and create a new file.
  5. Paste the contents attached below.
  6. Go to System Preferences -> Security & Privacy -> Privacy -> Accessibility, and make sure that Script Editor is allowed to control the computer.
  7. Open TextEdit and create a new file.
  8. Select Format -> Make Plain Text.
  9. Save the file as "Passwords.csv" (or any other name, the .csv extension is what is important).
  10. Make sure that file is the only open file in TextEdit.
  11. Open Safari, and make sure all its windows are closed.
  12. Open Safari -> Preferences, navigate to the Passwords tab, and enter your password to unlock the list.
  13. Select the first item in the list. This will be the first item imported to the text file, and the script will work its way down.
  14. Go back to Script Editor and press the play button.

This should import the first 5 passwords. When it's done, go to TextEdit and verify the contents. They should be in the format that 1Password expects for CSV files: name, URL, username, password. (Since there are no names for password items in Safari, this script just uses the URL as the name, so the first two fields will be identical.)

If you are confident the passwords got exported correctly, do the following to export the next batch of passwords:

  1. In TextEdit, ensure the caret in the text file is at the end of the file, on a line of its own.
  2. Go to Script Editor, adjust the command "repeat 5 times" to however many passwords you want to process at a time (say, 100, depending on how many you have). If you don't have that many passwords in Safari, it will keep exporting the last list entry, so no harm will be done except for a few duplicate lines in the text file, which you can delete manually after you're done. Be careful with selecting a very high number of repetitions though, because it's hard to stop the script once it's running.
  3. Save the script.
  4. Go to Safari, and make sure the passwords are still unlocked (Safari tends to auto-lock them after a few seconds), and that the next list item you want to export is selected. Be sure not to change the sort order of the list while going through this procedure, or you may end up with some passwords lost and some duplicate.
  5. Go back to Script Editor and press the play button.

This should export the next batch of passwords into the file. Repeat this as often as necessary.

After you've imported the file into 1Password, don't forget to turn backups back on, re-enable iCloud Keychain, and/or un-allow Script Editor to control your computer.

Script contents to paste into Script Editor:

repeat 5 times
  tell application "Safari"
    activate
    delay 0.4
    tell application "System Events" to keystroke "\t"
    tell application "System Events" to keystroke "c" using command down
  end tell
  tell application "TextEdit"
    activate
    delay 0.4
    tell application "System Events" to keystroke "\""
    tell application "System Events" to keystroke "v" using command down
    tell application "System Events" to keystroke "\",\""
    tell application "System Events" to keystroke "v" using command down
    tell application "System Events" to keystroke "\",\""
  end tell
  tell application "Safari"
    activate
    delay 0.4
    tell application "System Events" to keystroke "\t"
    tell application "System Events" to keystroke "c" using command down
  end tell
  tell application "TextEdit"
    activate
    delay 0.4
    tell application "System Events" to keystroke "v" using command down
    tell application "System Events" to keystroke "\",\""
  end tell
  tell application "Safari"
    activate
    delay 0.4
    tell application "System Events" to keystroke "\t"
    tell application "System Events" to keystroke "c" using command down
    tell application "System Events" to keystroke "\t"
    tell application "System Events" to key code 125
  end tell
  tell application "TextEdit"
    activate
    delay 0.4
    tell application "System Events" to keystroke "v" using command down
    tell application "System Events" to keystroke "\""
    tell application "System Events" to keystroke return
  end tell
end repeat
@fkoliveira
Copy link

The script worked well for me thanks so much! :)
1password asked me 4 columns on the import file layout so I modified the script to add that column.
Also made small changes for those with non EN-US keyboard layout.
thanks for sharing!

repeat 1 times
	tell application "Safari" --open Safari window
		activate
		delay 0.4
		tell application "System Events" --invoke context menu on active element
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy Website" --select righ-click menu item in the list
			keystroke return --'click' on selected menu item
		end tell
	end tell
	tell application "TextEdit" --open TextEdit and paste the quoted result and a comma
		activate
		delay 0.4
		tell application "System Events" to keystroke "\""
		tell application "System Events" to keystroke space
		tell application "System Events" to keystroke "v" using command down -- title
		tell application "System Events" to keystroke "\",\""
		tell application "System Events" to keystroke space -- for non EN-US keyboards
		tell application "System Events" to keystroke "v" using command down -- website
		tell application "System Events" to keystroke "\",\""
		tell application "System Events" to keystroke space -- for non EN-US keyboards
	end tell
	tell application "Safari"
		activate
		delay 0.4
		tell application "System Events"
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy User Name"
			delay 0.4
			keystroke return
			delay 0.4
		end tell
	end tell
	tell application "TextEdit"
		activate
		delay 0.4
		tell application "System Events" to keystroke "v" using command down
		tell application "System Events" to keystroke "\",\""
		tell application "System Events" to keystroke space -- for non EN-US keyboards
	end tell
	tell application "Safari"
		activate
		delay 0.4
		tell application "System Events"
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy Password"
			keystroke return
		end tell
		tell application "System Events" to key code 125 --move to the next item in Safari list
	end tell
	tell application "TextEdit"
		activate
		delay 0.4
		tell application "System Events" to keystroke "v" using command down
		tell application "System Events" to keystroke "\""
		tell application "System Events" to keystroke return --move to the new line in textedit file
	end tell
end repeat

@T3CH1035
Copy link

Super noob, so please don't be too hard on me.... the script is working great, but I have 1 problem. I have a couple re-used passwords (whole reason I want to get everything into a CSV, to organize and update). A popup appears when this is the case, see below or attached. Any ideas??

Screen Shot 2021-04-30 at 3 44 40 PM

@amitjethani
Copy link

@T3CH1035 If you only have a few of these passwords with warnings, I recommend copying them and moving them over manually. Then delete the entries in your keychain and run the script. It is manual work, but presumably just a one-time thing.

@T3CH1035
Copy link

@T3CH1035 If you only have a few of these passwords with warnings, I recommend copying them and moving them over manually. Then delete the entries in your keychain and run the script. It is manual work, but presumably just a one-time thing.

I was hoping to avoid that. I brought in all of my passwords from Lastpass, IE, Chrome, and Edge into keychain. Therefore, there may be many. If this is my only option, I will go through them manually. Thanks!!

@grossmusic1
Copy link

A year later & this Mojave fix WORKED! Thank you so much, macpwd.
https://gist.github.com/jonycgn/fa8bb9f1513af54baa95aecfa2e569eb#gistcomment-3577452

@grantjanssen
Copy link

this was so helpful in my password migration from Mojave -> Monteray - but none of the scripts here were exactly right for me.
on my Monteray system I exported some passwords so I could get the csv format correct
EXAMPLE:

grant@grants-EFILM-MacBookPro-M1:~/Downloads[20220205-9:12][#391585]% gpg -d 202202050904.grants-EFILM-MacBookPro-M1.passwords.csv.gpg | grep -e Title -e 10.1.132.166
gpg: encrypted with 4096-bit RSA key, ID D30BB0166A5F0F2F, created 2013-09-07
      "Grant Janssen (gmail) <[email protected]>"
Title,Url,Username,Password,OTPAuth
10.1.132.166 (manage),http://10.1.132.166/,manage,!manage,
grant@grants-EFILM-MacBookPro-M1:~/Downloads[20220205-9:13][#392585]%

so I needed the parentheses added, and the username pasted in two places
I tweeked the script a bit:

tell application "TextEdit"
	activate
	tell application "System Events" to keystroke "Title,Url,Username,Password,OTPAuth"
	tell application "System Events" to keystroke return
end tell
repeat 16 times
	tell application "Safari" --open Safari window
		activate
		delay 0.8
		tell application "System Events" --invoke context menu on active element
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy Website" --select right-click menu item in the list
			keystroke return --'click' on selected menu item
		end tell
	end tell
	tell application "TextEdit" --open TextEdit and paste the result and a comma
		activate
		delay 0.8
		tell application "System Events" to keystroke "v" using command down -- title
	end tell
	tell application "Safari"
		activate
		delay 0.8
		tell application "System Events"
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy User Name"
			delay 0.8
			keystroke return
			delay 0.8
		end tell
	end tell
	tell application "TextEdit"
		activate
		delay 0.8
		tell application "System Events" to keystroke space
		tell application "System Events" to keystroke "(" -- add before user
		tell application "System Events" to keystroke "v" using command down
		tell application "System Events" to keystroke ")," -- after user
	end tell
	
	tell application "Safari" --open Safari window
		activate
		delay 0.8
		tell application "System Events" --invoke context menu on active element
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy Website" --select right-click menu item in the list
			keystroke return --'click' on selected menu item
		end tell
	end tell
	
	tell application "TextEdit" -- copy website path
		activate
		delay 0.8
		tell application "System Events" to keystroke "http://" -- prepend the URL
		tell application "System Events" to keystroke "v" using command down
		tell application "System Events" to keystroke "/," -- URL
	end tell
	
	tell application "Safari"
		activate
		delay 0.8
		tell application "System Events"
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy User Name"
			delay 0.8
			keystroke return
			delay 0.8
		end tell
	end tell
	
	tell application "TextEdit" -- copy username
		activate
		delay 0.8
		tell application "System Events" to keystroke "v" using command down
		tell application "System Events" to keystroke "," -- URL
	end tell
	
	tell application "Safari"
		activate
		delay 0.8
		tell application "System Events"
			tell process "Safari"
				set _selection to value of attribute "AXFocusedUIElement"
				tell _selection to perform action "AXShowMenu"
			end tell
			keystroke "Copy Password"
			keystroke return
		end tell
		tell application "System Events" to key code 125 --move to the next item in Safari list
	end tell
	tell application "TextEdit"
		activate
		delay 0.8
		tell application "System Events" to keystroke "v" using command down
		tell application "System Events" to keystroke "," -- comma here last OTPAuth field is blank
		tell application "System Events" to keystroke return --move to the new line in textedit file
	end tell
end repeat

brought in 400+ passwords - ran perfectly

@xldan
Copy link

xldan commented May 26, 2022

my old mac no longer supports many app updates, so it was time to migrate.
jonycgn's OP was a big help to find a way to get Passwords etc out of safari.
Wanted to learn a bit about apple scripts and get more flexibility for code re-use.
Added option for Tab Separated Variables, Though not relevant for the passwords,
I've found it useful for moving databases where fields contained commas and/or quotes.

# This captures passwords stored in Safari (mine is 11.1.2) and writes them to a text file.
# Open Safari select show preferences/passwords (tick show & use login password); 
# make sure all other safari windows are closed.
# open TextEdit, set as text and save empty file as *.csv or *.tsv
# run this script after modifying to suit your needs
# save the text file to a safe place (consider encrypting)
# Based on github post: jonycgn / Export Safari passwords.md (thanks Johannes)


set delimcsv to ","        #  for file.csv
set delimtsv to "	" #  for file.tsv  - entered as "\t", converted to tab on script save
set sloth to 0.3           # to give time for GUI process to complete

#  unrem delimiter type to be used for output file
set delim to delimcsv
# set delim to delimtsv

#  makes data file less susceptible to discovery by key words
set txt1 to "forest"      # url
set txt2 to "wood"      # user name
set txt3 to "leaves"     # password
set fields to 3             # number of fields per record containing data
set txtlast to ""

# load with headers for first write
set txtrow to txt1 & delim & txt2 & delim & txt3 & return

repeat while txtrow is not txtlast
	tell application "TextEdit"
		activate
		delay sloth
		tell application "System Events" to keystroke txtrow
	end tell
	set txtlast to txtrow
	set txtrow to ""
	tell application "Safari"
		activate
		set n to fields
		repeat n times                                                      # once for each field to capture
			set the clipboard to ""
			tell application "System Events" to keystroke tab               # set focus on next field
			delay sloth
			tell application "System Events" to keystroke "c" using command down        # copy
			if n > 1 then
				set txtrow to txtrow & (the clipboard) & delim
			else
				set txtrow to txtrow & (the clipboard) & return
			end if
			set n to n - 1       #  loop terminates when n < 1
		end repeat
		
		# got the data, set focus for read on next row
		delay sloth
		tell application "System Events" to key code 53         # escape, to de-select text
		delay sloth
		tell application "System Events" to key code 125       # down arrow, focus to next row	
	end tell
end repeat

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment