Skip to content

Instantly share code, notes, and snippets.

@tarneaux
Last active May 21, 2023 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarneaux/08b6abdda02a921ed9282660926cb3a5 to your computer and use it in GitHub Desktop.
Save tarneaux/08b6abdda02a921ed9282660926cb3a5 to your computer and use it in GitHub Desktop.
Convert bitwarden CSV to GNU passwordstore
#!/usr/bin/env/python3
# Convert Bitwarden CSV export to pass format
import pandas
import os
import sys
import subprocess
# Check for correct number of arguments
if len(sys.argv) != 2:
print("Usage: bitwarden_to_pass.py <bitwarden_export.csv>")
sys.exit(1)
# Read CSV file
with open(sys.argv[1], newline='') as csvfile:
df = pandas.read_csv(csvfile)
# For each row, run pass add
def get_formatted_info_from_row(row):
# Example from pass:
# aAtkJ12K
# URL: *.amazon.com/*
# Username: AmazonianChicken@example.com
# Secret Question 1: What is your childhood best friend's most bizarre superhero fantasy? Oh god, Amazon, it's too awful to say...
# Phone Support PIN #: 84719
# We will also name the file {folder}/{name} or just {name} if there is no folder
# bitwarden CSV columns:
# folder,favorite,type,name,notes,fields,reprompt,login_uri,login_username,login_password,login_totp
# NAME
if not pandas.isnull(row.loc['folder']):
# Get the folder name
name = row['folder'] + "/"
else:
name = ""
name += row['name']
contents = f"{row['login_password']}\n"
contents += f"URL: {row['login_uri']}\n"
contents += f"Username: {row['login_username']}\n"
contents += f"Notes: {row['notes']}\n"
contents += f"TOTP: {row['login_totp']}\n"
contents += f"Fields: {row['fields']}\n"
return name, contents
for index, row in df.iterrows():
name, contents = get_formatted_info_from_row(row)
print(f"Adding {name}...")
# Run pass add
subprocess.run(["pass", "insert", "-m", name], input=contents, encoding='ascii', check=True, stdout=subprocess.DEVNULL)
print("Done!")
print(f"Now, you DO NOT want to run 'rm {sys.argv[1]}'.")
print(f"Before removing a sensitive file like this, you should always run 'shred {sys.argv[1]}'.")
print("This will overwrite the file with random data before deleting it.")
print("This is important because otherwise, the data will still be on your hard drive and is recoverable with tools like TestDisk.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment