selenium_tor 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +15 -1
- data/lib/tor/driver.rb +4 -0
- data/lib/tor/libxul_checksums.yml +13 -0
- data/lib/tor/libxul_patchable.rb +98 -0
- data/lib/tor/options.rb +2 -0
- data/lib/tor/torrc.rb +8 -2
- data/lib/tor/version.rb +1 -1
- data/tmp/.placeholder +0 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c45649309a0d50821238c2dc502b8e1d5e9f2137a24229cd09c4493aa45ea7d
|
4
|
+
data.tar.gz: 56177ff95c346118c5497bc0cfa44a1de83d3705be663596d7aefe8ab475e72e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d8ed9f5b35b852ea189f755d33af91676cbfb3b5750506b9955653220ec5bda98303dfe89dbf2ff850bdbc538d37d26169e5a5b74ff3f10cb3bfeff04b511e9
|
7
|
+
data.tar.gz: 4628ebe827ab1ef4004c7c5c09d1126a2aecb5ce53f52c652221ec76da36890f5ab9bb8df46b44da331a00d6a8a5eb8b94750ef8bdf84df6849d31cc1782f56f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
## master (unreleased)
|
2
2
|
|
3
|
+
## [1.5.1] - 2024-09-02
|
4
|
+
|
5
|
+
Fix load path error in LibxulPatchable module
|
6
|
+
|
7
|
+
## [1.5.0] - 2024-08-31
|
8
|
+
|
9
|
+
### Bug fixes
|
10
|
+
|
11
|
+
* [#15](https://gitlab.com/matzfan/selenium-tor/-/issues/15)
|
12
|
+
* [#16](https://gitlab.com/matzfan/selenium-tor/-/issues/16)
|
13
|
+
* [#17](https://gitlab.com/matzfan/selenium-tor/-/issues/17)
|
14
|
+
|
15
|
+
### New features
|
16
|
+
|
17
|
+
* add ability to patch libxul.so to avoid webdriver fingerprint detection
|
18
|
+
|
3
19
|
## [1.4.0] - 2024-08-07
|
4
20
|
|
5
21
|
### Breaking changes
|
data/README.md
CHANGED
@@ -49,6 +49,19 @@ The location of the TBB is not expected to change during code execution.
|
|
49
49
|
|
50
50
|
Tor Selenium is tested on **Linux only** right now.
|
51
51
|
|
52
|
+
### Patching libxul.so
|
53
|
+
|
54
|
+
A configuration option to patch the libxul.so packaged with Tor Browser is provided. This has the effect of preventing websites from fingerprinting Selenium-driven Tor Browser via a JS call to `navigator.webdriver`:
|
55
|
+
```ruby
|
56
|
+
Tor::Driver.libxul_patched? # is Tor Browser's libxul.so patched?
|
57
|
+
# => false
|
58
|
+
Tor::Driver.patch_libxul # patch libxul.so
|
59
|
+
Tor::Driver.libxul_patched?
|
60
|
+
# => true
|
61
|
+
Tor::Driver.unpatch_libxul # revert the patch and restore the libxul.so packaged with Tor Browser
|
62
|
+
```
|
63
|
+
The patcher uses the `[bsdiff](https://www.daemonology.net/bsdiff)` package, which must be installed on your system.
|
64
|
+
|
52
65
|
## Usage
|
53
66
|
```ruby
|
54
67
|
require 'selenium_tor'
|
@@ -63,7 +76,7 @@ A separate tor process is used for each driver. Failure to call `Driver#quit` af
|
|
63
76
|
|
64
77
|
In addition to the regular Firefox options, a :tor_opts key may be passed to an instance of `Tor::Options` with a hash of tor options. All valid tor options are recognized - see `man tor`. For convenience, "SocksPort" and "ControlPort" options may be set using snake_case symbols - i.e. :socks_port and :control_port. Additionally, a :tor_opts timeout value may be set with the :timeout key. This overrides the default time allowed for the tor process to bootstrap (10 seconds).
|
65
78
|
|
66
|
-
### Multiple driver instances
|
79
|
+
### Multiple driver instances
|
67
80
|
|
68
81
|
Running multiple tor processes requires that each uses different ports for SocksPort (and ControlPort, if used). These must be passed using the `:tor_opts` key. An example using the [Parallel gem](https://rubygems.org/gems/parallel):
|
69
82
|
```ruby
|
@@ -121,6 +134,7 @@ A number of constants are set during driver initialization based upon values fou
|
|
121
134
|
Tor::TBB_DIR # path to the TBB root directory
|
122
135
|
Tor::TBB_BROWSER_DIR # path to the 'Browser' directory in the above
|
123
136
|
Tor::TBB_BINARY_PATH # path to the firefox binary
|
137
|
+
Tor::TBB_TOR_BINARY_PATH # path to the bundled tor binary
|
124
138
|
Tor::TBB_PROFILE_DIR # path to the default profile directory
|
125
139
|
Tor::TBB_EXTENSIONS_DIR # path to the 'extensions' directory in the above
|
126
140
|
Tor::TBB_VERSION # the version installed, e.g. "13.0.1", note: driver.capabilities.browser_version returns the Firefox version Tor Browser is based on
|
data/lib/tor/driver.rb
CHANGED
@@ -4,6 +4,7 @@ require 'open-uri'
|
|
4
4
|
require_relative '../service'
|
5
5
|
require_relative '../options'
|
6
6
|
require_relative '../firefox_prefs'
|
7
|
+
require_relative 'libxul_patchable'
|
7
8
|
require_relative 'profile'
|
8
9
|
require_relative 'tor_process'
|
9
10
|
|
@@ -15,6 +16,8 @@ module Selenium
|
|
15
16
|
|
16
17
|
# tor driver
|
17
18
|
class Driver < DelegateClass(DriverDelegate)
|
19
|
+
extend LibxulPatchable
|
20
|
+
|
18
21
|
TORRC_PATH_PREF = 'extensions.torlauncher.torrc_path'
|
19
22
|
TORRC = 'torrc'
|
20
23
|
BROWSER_SECURITY_LEVEL_PREF = 'browser.security_level.security_slider'
|
@@ -73,6 +76,7 @@ module Selenium
|
|
73
76
|
@tor_process = tor_process(opts)
|
74
77
|
@tor_process.start_tor(timeout: timeout)
|
75
78
|
rescue Tor::TorProcess::TorProcessError => e
|
79
|
+
instance_variable_get(:@instance)&.quit # avoids hanging firefox.real process
|
76
80
|
raise Error::WebDriverError, e
|
77
81
|
end
|
78
82
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
13.5.2:
|
3
|
+
unpatched_libxul: b2f8b3fd25466bd3ffa12fb34b422767b28e09577d5714d6d0c97f695dac15dc
|
4
|
+
patched_libxul: 7f761479c2d0307b97023455cfd7811b5749690302f54508b247720105dd0a3b
|
5
|
+
patch_checksum: 695f7534586c757781bd33a6dbc627cfe62d010edce20e5754fa5efff7aa80d0
|
6
|
+
14.0a2:
|
7
|
+
unpatched_libxul: e0eda8db975fe315e9be32b3bf95ee62767c60ee34deac97a7163f8ab0480dc9
|
8
|
+
patched_libxul: ed05f9c383f4ecbce69d978aefc0625c44874193707ebe11166e714b3e2b4f64
|
9
|
+
patch_checksum: 0cf817f97bdbe51fba5ad61d566934c9ebdda8fce5540bc803aeca23e0ac3e8b
|
10
|
+
14.0a3:
|
11
|
+
unpatched_libxul: f448fc180b547d622b969fe170028408f75493cf95be5e4c1180594daec2226b
|
12
|
+
patched_libxul: 337a4ef0e723069695294b37a4843126529c44e2bc4f90b1533b547100355db3
|
13
|
+
patch_checksum: 08dd8cab30c4416adf7ab6411e1346dce4a8b6f42e4c410adcd5bc63a71506e5
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'json'
|
5
|
+
require 'open-uri'
|
6
|
+
require_relative 'options' # module needs access to consts therein defined
|
7
|
+
|
8
|
+
module Selenium
|
9
|
+
module WebDriver
|
10
|
+
module Tor
|
11
|
+
# methods to patch/unpatch libxul.so
|
12
|
+
module LibxulPatchable
|
13
|
+
class LibxulPatchableError < StandardError; end
|
14
|
+
|
15
|
+
# PATCH_REPO = 'https://gitlab.com/matzfan/keymaster/-/releases' # TODO
|
16
|
+
LIBXUL_CHECKSUMS = YAML.load_file(File.join(__dir__, 'libxul_checksums.yml'))[Tor::TBB_VERSION]
|
17
|
+
PATCH_REPO = 'https://gitlab.com/matzfan/keymaster/-/raw/main/patches/tor-browser'
|
18
|
+
ISSUES_URL = 'https://gitlab.com/matzfan/keymaster/-/issues'
|
19
|
+
|
20
|
+
def libxul_patched?
|
21
|
+
libxul_checksum = checksum_for Tor::TBB_LIBXUL
|
22
|
+
return true if patched_libxul_checksum_for_version == libxul_checksum
|
23
|
+
return false if unpatched_libxul_checksum_for_version == libxul_checksum
|
24
|
+
|
25
|
+
raise LibxulPatchableError, 'Unrecognized libxul.so'
|
26
|
+
end
|
27
|
+
|
28
|
+
def patch_libxul
|
29
|
+
return if libxul_patched?
|
30
|
+
|
31
|
+
patchfile = fetch_patchfile
|
32
|
+
valid? patchfile
|
33
|
+
FileUtils.mv Tor::TBB_LIBXUL, libxul_original # rename libxul.so
|
34
|
+
execute_patch patchfile
|
35
|
+
FileUtils.cp libxul_patched, Tor::TBB_LIBXUL
|
36
|
+
rescue OpenURI::HTTPError
|
37
|
+
raise LibxulPatchableError, "No patch for #{Tor::TBB_VERSION}, please raise an issue at #{ISSUES_URL}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def unpatch_libxul
|
41
|
+
return unless libxul_patched?
|
42
|
+
|
43
|
+
FileUtils.mv libxul_original, Tor::TBB_LIBXUL
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def libxul_original
|
49
|
+
"#{Tor::TBB_LIBXUL}.ORIGINAL"
|
50
|
+
end
|
51
|
+
|
52
|
+
def libxul_patched
|
53
|
+
"#{Tor::TBB_LIBXUL}.PATCHED"
|
54
|
+
end
|
55
|
+
|
56
|
+
def valid?(patchfile)
|
57
|
+
msg = "Invalid patch for #{Tor::TBB_VERSION}, please raise an issue at #{ISSUES_URL}"
|
58
|
+
raise LibxulPatchableError, msg unless patch_checksum_for_version == checksum_for(patchfile)
|
59
|
+
end
|
60
|
+
|
61
|
+
def execute_patch(patchfile)
|
62
|
+
raise LibxulPatchableError, 'bspatch not found, please install bsdiff' if `which bspatch`.empty?
|
63
|
+
|
64
|
+
`bspatch #{libxul_original} #{libxul_patched} #{patchfile}`
|
65
|
+
end
|
66
|
+
|
67
|
+
def unpatched_libxul_checksum_for_version
|
68
|
+
LIBXUL_CHECKSUMS['unpatched_libxul']
|
69
|
+
end
|
70
|
+
|
71
|
+
def patched_libxul_checksum_for_version
|
72
|
+
LIBXUL_CHECKSUMS['patched_libxul']
|
73
|
+
end
|
74
|
+
|
75
|
+
def patch_checksum_for_version
|
76
|
+
LIBXUL_CHECKSUMS['patch_checksum']
|
77
|
+
end
|
78
|
+
|
79
|
+
def checksum_for(file)
|
80
|
+
Digest::SHA256.file(file).hexdigest
|
81
|
+
end
|
82
|
+
|
83
|
+
def fetch_patchfile
|
84
|
+
tmp = Tempfile.new.tap(&:binmode)
|
85
|
+
URI.parse(patch_url).open('rb') do |f|
|
86
|
+
tmp.write(f.read)
|
87
|
+
tmp.tap(&:flush)
|
88
|
+
end
|
89
|
+
tmp.path
|
90
|
+
end
|
91
|
+
|
92
|
+
def patch_url
|
93
|
+
File.join PATCH_REPO, "#{Tor::TBB_VERSION}.patch"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/tor/options.rb
CHANGED
@@ -15,8 +15,10 @@ module Selenium
|
|
15
15
|
|
16
16
|
Tor::TBB_DIR = ENV.fetch('TOR_BROWSER_ROOT_DIR', nil) || DEFAULT_TBB_DIR
|
17
17
|
Tor::TBB_BROWSER_DIR = File.join Tor::TBB_DIR, 'Browser'
|
18
|
+
Tor::TBB_LIBXUL = File.join Tor::TBB_BROWSER_DIR, 'libxul.so'
|
18
19
|
Tor::TBB_BINARY_PATH = File.join Tor::TBB_BROWSER_DIR, 'firefox'
|
19
20
|
Tor::TBB_TOR_BINARY_PATH = File.join Tor::TBB_BROWSER_DIR, *%w[TorBrowser Tor tor]
|
21
|
+
Tor::TBB_TOR_DATA_DIR = File.join Tor::TBB_BROWSER_DIR, *%w[TorBrowser Data Tor]
|
20
22
|
Tor::TBB_PROFILE_DIR = File.join Tor::TBB_BROWSER_DIR, *%w[TorBrowser Data Browser profile.default]
|
21
23
|
Tor::TBB_EXTENSIONS_DIR = File.join Tor::TBB_PROFILE_DIR, 'extensions'
|
22
24
|
Tor::TBB_VERSION = JSON.parse(File.read(File.join(Tor::TBB_BROWSER_DIR, 'tbb_version.json')))['version']
|
data/lib/tor/torrc.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'options'
|
3
|
+
require_relative 'options'
|
4
4
|
|
5
5
|
module Selenium
|
6
6
|
module WebDriver
|
@@ -36,7 +36,13 @@ module Selenium
|
|
36
36
|
private
|
37
37
|
|
38
38
|
def write_default_config
|
39
|
-
write_to_config DEFAULT_PORTS.merge(
|
39
|
+
write_to_config DEFAULT_PORTS.merge(default_config)
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_config
|
43
|
+
{ 'DataDirectory' => @data_dir,
|
44
|
+
'GeoIPFile' => File.join(TBB_TOR_DATA_DIR, 'geoip'),
|
45
|
+
'GeoIPv6File' => File.join(TBB_TOR_DATA_DIR, 'geoip6') }
|
40
46
|
end
|
41
47
|
|
42
48
|
def validate_torrc_options(hash)
|
data/lib/tor/version.rb
CHANGED
data/tmp/.placeholder
ADDED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: selenium_tor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MatzFan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: selenium-webdriver
|
@@ -47,6 +47,8 @@ files:
|
|
47
47
|
- lib/selenium_tor.rb
|
48
48
|
- lib/service.rb
|
49
49
|
- lib/tor/driver.rb
|
50
|
+
- lib/tor/libxul_checksums.yml
|
51
|
+
- lib/tor/libxul_patchable.rb
|
50
52
|
- lib/tor/options.rb
|
51
53
|
- lib/tor/profile.rb
|
52
54
|
- lib/tor/system_tor.rb
|
@@ -56,6 +58,7 @@ files:
|
|
56
58
|
- lib/tor/version.rb
|
57
59
|
- selenium_tor.gemspec
|
58
60
|
- sig/tor.rbs
|
61
|
+
- tmp/.placeholder
|
59
62
|
homepage: https://gitlab.com/matzfan/selenium-tor
|
60
63
|
licenses:
|
61
64
|
- MIT
|