You are not logged in.

#1 2017-08-28 17:23:09

Neven
Member
Registered: 2014-05-02
Posts: 74

Chrome independent temporary sessions w/o Incognito, & bookmark manage

Everything written in simple Unix sh.

For some time I had been using this simple wrapper (named 'b') so I could access Chromium without typing the whole executable name and so it would always start in Incognito mode. Because in Incognito mode you can start independent (regarding cookies, etc.) browsing sessions when you try executing chromium again and because it doesn't keep that annoying and unnecessary history data wink

#! /bin/sh

# Incognito mode pros: dark, non-eyesearing default background; only keeps bookmarks and files explicitly "saved" between sessions.
# Cons: Easily detectable in Javascript

exec chromium --incognito "$@"

But then a site I accessed refused me service and I found out that in Javascript it is easy to tell if Chrome's Incognito mode is being used! Sites being able to tell if it is on makes it basically useless.

So I made this little tool (named 'tb') that I feel has gotten complicated and useful enough to share. It makes temporary copies of your configuration to give to Chromium, basically replicating (and improving on) Incognito mode. It also takes care of command-line flags. See for yourself:

#! /bin/sh

# Runs Chromium with a temporary copy of a selected subset of the user's data without writing to the default Chromium configuration data. Copies data for Chrome to a directory in /tmp (or wherever you configure), and that's about the only place on the file system the executed Chrome instance should read or write from while it's running.
# No jails/containers/namespaces, just copying directories to /tmp and setting some environment variables.
#
# Use it if you want independent browser sessions running simultaneously, don't want your browser to store unnecessary information to disk, if you need a nice way to manage argv switches for Chromium, if you simply want more control or want to learn about Chromium, if you want to test something without ruining your configuration, etc. Also, tmpfs I/O is faster than permanent storage, so this might provide performance benefits.
#
# Why not just use Chrome Incognito mode? Most importantly, Incognito mode is trivially detectable from Javascript. Also, this script enables ensuring that *no* data is written to disk or preserved (just be sure to delete the directory the script tells you about). From a less privacy minded perspective, this provides a bit more power than Incognito mode.
#
# This is meant to be used for general purpose browsing, run chromium (or the wrapper bkm) for making lasting settings changes or managing your bookmarks.
#
# Configuration: You might want to edit the shell variables here at the beginning of the script.
#
# Usage: 'tb [flags] [URLs]'
#
# All command-line arguments are passed through to Chromium.

# Example directory tree during usage:
#
# /tmp
# └── TChromb9e[...]08d                      # We make one of these for every invocation of this program, so multiple Chrome sessions could run simultaneously. Set as HOME for Chrome.
#     ├── cache                              # Passed as XDG_CACHE_HOME to Chrome.
#     ├── .config
#     │   └── chromium
#     ├── data                               # Passed to Chrome in argv with --user-data-dir
#     │   ├── BrowserMetrics-active.pma
#     │   ├── BrowserMetrics-spare.pma
#     │   ├── Certificate Revocation Lists
#     │   ├── CertificateTransparency
#     │   ├── Default                        # The default "profile" data location. This is where we put data for Chrome.
#     │   ├── EVWhitelist
#     │   ├── FileTypePolicies
#     │   ├── Local State
#     │   ├── OriginTrials
#     │   ├── ShaderCache
#     │   ├── SingletonCookie
#     │   ├── SingletonLock
#     │   ├── SingletonSocket
#     │   └── SSLErrorAssistant
#     └── .pki
#         └── nssdb

# The following may need editing.
chromExecutable=chromium
chromConf="$HOME/.config/chromium"
chromProfile=Default

targetDirTemplate=/tmp/TChrom

# Chrome non-long-term-supported options. Kept in 'Local State' if set on chrome://flags, but we don't copy that file for Chromium, instead passing the settings as command arguments.
# See https://peter.sh/experiments/chromium-command-line-switches/ for more switches and explanations.
#
# Some other useful switches; for privacy, etc.:
# --disable-reading-from-canvas --no-referrers
# --use-fake-device-for-media-stream --use-file-for-fake-audio-capture --use-file-for-fake-video-capture
# --use-mobile-user-agent --user-agent
flagSwitches='--enable-dom-distiller --no-first-run --no-pings --enable-scripts-require-action --reduced-referrer-granularity'

# Files from the Chrome profile directory "$chromConf/$chromProfile" that will be used for the "session" of the Chrome instance we'll execute.
# Includes bookmarks, Chrome extension data, web auth data, Chrome preferences, and settings for non-default "search engines". In short, the aim is to preserve only the useful stuff.
# For example, removing Login Data from this list should prevent your passwords from being copied for the chromium instance we'll execute to use.
filesForChrome='Bookmarks,Extension Cookies,Extension Rules,Extension State,Extensions,Local Extension Settings,Local Storage,Login Data,Preferences,Web Data'

######################################################################

set -e -u

# Get a random string for naming the temporary directory.
r='s_\([^ ]*\).*_\1_'
id=`dd 'if=/dev/urandom' 'count=1' 'bs=256' 2>/dev/null | sha256sum | sed "$r"`\
`date -u | sha256sum | sed "$r"`

d="$targetDirTemplate$id"

# Create the temporary directory tree for Chromium, copying over existing data.
mask=`umask`
umask 077
mkdir "$d" "$d/data" "$d/data/Default" "$d/cache"
#cp -r "$chromConf/$chromProfile" "$d/data/Default"
cd "$chromConf/$chromProfile"
IFS=,
cp -r $filesForChrome "$d/data/Default"
umask "$mask"

export HOME XDG_CACHE_HOME
XDG_CACHE_HOME="$d/cache"
HOME="$d"
cd "$d"

echo "Chrome dir $d"

# Chromium's Incognito mode is trivially detectable from Javascript, so we don't use it here.
IFS=' '
exec "$chromExecutable" "--user-data-dir=$d/data" $flagSwitches "$@"

# If you wanted to delete the data after Chrome exits:
#sleep 1 && rm -r "$d"

# Issues:
# The user should be warned somehow that bookmarks changes don't get applied to the source bookmarks file.

# General notes about Chromium
#
# Suggestions for configuring Chromium: set chrome://newtab as the start page.
#
# Some Chrome extensions:
# https://github.com/gorhill/uMatrix
# https://github.com/jswanner/DontFuckWithPaste
# https://github.com/andryou/scriptsafe
# https://github.com/maximelebreton/quick-javascript-switcher
# https://www.eff.org/privacybadger
#
# A patchset. Use it, e.g., for removing WebRTC
# https://github.com/gcarq/inox-patchset

# Check how identifiable your web browser is making you.
#
# https://panopticlick.eff.org
# https://amiunique.org

But then a bookmark manager wrapper ('bkm', for short) was made necessary for the workflow by 'tb', so I made one. Because of intentional restrictions to Chrome, xdotool had to be used:

#! /bin/sh

# Opens Chrome/Chromium's bookmark manager. For X Windows.
#
# Configuration: You might want to edit the shell variables here at the beginning of the script.
#
# The Chrome bookmarks manager is accessible through the chrome://bookmarks page, but Chrome sadly doesn't let chrome:// URLs be opened from the command-line. Here we use xdotool to find Chrome's WID and type in the URI.
#
# Usage: 'bkm [flags]'
#
# All command-line arguments are passed through to Chromium.

chromExecutable=chromium

stringToType='chrome://bookmarks
'

# How long to wait for Chromium to start a window.
sleepSeconds=1.5

######################################################################

set -u

# Returns true if there is just one argument.
notOne () {
	false=1
	true=0

	case "$#" in
	1)
		return "$false"
		;;
	*)
		return "$true"
		;;
	esac
}

"$chromExecutable" "$@" &
sleep "$sleepSeconds"

# Find X Windows window ID.
IFS='
'
set -- `xdotool search --onlyvisible --pid "$!"`

if notOne "$@"; then
	error="We got less or more than one window IDs :(
Here are they: $@"
	echo "$error" 1>&2
	exit 13
fi

# Type the URI.
xdotool windowactivate --sync "$1" type "$stringToType"

Comments and suggestions are welcome.


Edit: added some comments and a flag to enable dom distiller with tb

Last edited by Neven (2017-09-09 19:31:14)

Offline

#2 2017-08-30 00:10:45

Neven
Member
Registered: 2014-05-02
Posts: 74

Re: Chrome independent temporary sessions w/o Incognito, & bookmark manage

... And for killing Chromium processes safely:

#! /bin/sh

# Sends a signal to every root of a chromium process tree, or a tree made of processes whose names match "$target"*. So this might not do what you want if your shell's name also matches chrom*.
#
# Note: if your goal is just to kill Chromium safely, killing chrome-sandbox's parent could work, too.

command='kill -s TERM'
target='chrom'

######################################################################

set -u

# Are the 'x's necessary to guard from empty variables? TODO

strEq () {
	true=0
	false=1

	case "$#" in
	1)
		return "$false"
		;;
	esac

	case "x$2" in
	"x$1"*)
		return "$true"
		;;
	esac
	return "$false"
}

# Returns the PID of the root of the tree of processes with same argv0 as $1, whose argv0 is assumed to be $target.
rootOf () {
	tmpPID="$1"
	ppid=`ps -p "$tmpPID" -o 'ppid='`
	IFS=' '
	while strEq "$target" `ps -p $ppid -o 'comm='`; do
		tmpPID=$ppid
		ppid=`ps -p $ppid -o 'ppid='`
	done
	echo "$tmpPID"
}

# Returns true if $1 is not in rest of $@.
piuztfvbnk () {
	true=0
	false=1

	t="$1"
	shift

	for v in "$@"; do
		case "x$v" in
		"x$t")
			return "$false"
			;;
		esac
	done

	return "$true"
}

targetList=

IFS=' 	
'
for pid in `ps -A -o 'pid='`; do
	if strEq "$target" `ps -p "$pid" -o 'comm='`; then
		root=`rootOf "$pid"`
		if piuztfvbnk "$root" $targetList; then
			targetList="$targetList $root"
		fi
	fi
done



case "x$targetList" in
x)
	echo 'No processes found.' 1>&2
	exit 15
	;;
esac

IFS=' '
$command $targetList

Last edited by Neven (2017-08-30 02:34:59)

Offline

Board footer

Powered by FluxBB