This commit is contained in:
Alex Gibson 2025-01-28 09:38:56 +00:00 коммит произвёл GitHub
Родитель 6f1d4cf9ad
Коммит 90b4109085
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
59 изменённых файлов: 10 добавлений и 5464 удалений

Просмотреть файл

@ -298,13 +298,13 @@
sidemenu_lists() takes an array of lists and makes nav menus
The list has the link, a body_id, and a the text to display
{% set navigation_bar_client_bounty = [
(url('security.client-bug-bounty'),'client-bug-bounty', 'Client Bug Bounty'),
(url('security.bug-bounty.faq'), 'faq', 'Frequently Asked Questions'),
('https://www.mozilla.org/en-US/security/bug-bounty/','client-bug-bounty', 'Client Bug Bounty'),
('https://www.mozilla.org/en-US/security/bug-bounty/faq/', 'faq', 'Frequently Asked Questions'),
] %}
{% set navigation_bar_web_bounty = [
(url('security.web-bug-bounty'), 'web-bug-bounty', 'Web Bug Bounty'),
(url('security.bug-bounty.web-eligible-sites'), 'web-eligible-sites', 'Eligible Websites'),
('https://www.mozilla.org/en-US/security/bug-bounty/', 'web-bug-bounty', 'Web Bug Bounty'),
('https://www.mozilla.org/en-US/security/bug-bounty/web-eligible-sites/', 'web-eligible-sites', 'Eligible Websites'),
] %}
{{ sidemenu_lists([navigation_bar_client_bounty, navigation_bar_web_bounty]) }}

Просмотреть файл

@ -7,13 +7,13 @@
{# side_nav_lists() takes a list of lists and makes nav menus
The list has the link, a body_id, and a the text to display
{% set navigation_bar_client_bounty = [
(url('security.client-bug-bounty'),'client-bug-bounty', 'Client Bug Bounty'),
(url('security.bug-bounty.faq'), 'faq', 'Frequently Asked Questions'),
('https://www.mozilla.org/en-US/security/bug-bounty/','client-bug-bounty', 'Client Bug Bounty'),
('https://www.mozilla.org/en-US/security/bug-bounty/faq/', 'faq', 'Frequently Asked Questions'),
] %}
{% set navigation_bar_web_bounty = [
(url('security.web-bug-bounty'), 'web-bug-bounty', 'Web Bug Bounty'),
(url('security.bug-bounty.web-eligible-sites'), 'web-eligible-sites', 'Eligible Websites'),
('https://www.mozilla.org/en-US/security/bug-bounty/', 'web-bug-bounty', 'Web Bug Bounty'),
('https://www.mozilla.org/en-US/security/bug-bounty/web-eligible-sites/', 'web-eligible-sites', 'Eligible Websites'),
] %}
{{ side_nav_lists([navigation_bar_client_bounty, navigation_bar_web_bounty]) }}

Просмотреть файл

@ -14,7 +14,7 @@
<p> Version 1.1</p>
<p><strong>
{% with bounty=url('security.bug-bounty') %}
{% with bounty='https://www.mozilla.org/en-US/security/bug-bounty/' %}
IMPORTANT: Anyone who believes they have found a Mozilla-related security vulnerability should visit
our <a href="{{ bounty }}">bug bounty program</a> for information on how to submit them.
{% endwith %}
@ -127,7 +127,7 @@
<li>to establish, for each bug, the amount of information a distributor can reveal immediately (before a fix is available) without putting other distributors and their customers at risk.</li>
</ul>
<p>{% with known=url('security.known-vulnerabilities') %}
<p>{% with known='https://www.mozilla.org/en-US/security/known-vulnerabilities/' %}
A typical warning will mention the application or module affected, the affected versions, and a workaround (e.g. disabling JavaScript). If the group decides to publish a warning, the module owner, a peer, or some other person they may designate will post this message to the <a href="{{ known }}"> Known Vulnerabilities</a> page (which will be the authoritative source for this information) and will also send a copy of this message to an appropriate moderated mailing list and/or newsgroup (e.g., netscape.public.mozilla.announce and/or some other newsgroup/list established specifically for this purpose). Mozilla distributors who wish to inform their users of the existence of a vulnerability may repost any information from the Known Vulnerabilities page to their own websites, mailing lists, release notes, etc., but should not disclose any additional information about the bug.
{% endwith %}</p>

Просмотреть файл

@ -1,3 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,3 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,3 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,305 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import glob
import os
import re
import sys
from django.conf import settings
from django.core.management.base import CommandError
from django.db.models import Count
from dateutil.parser import parse as parsedate
from bedrock.security.models import HallOfFamer, MitreCVE, Product, SecurityAdvisory
from bedrock.security.utils import (
FILENAME_RE,
check_hof_data,
mfsa_id_from_filename,
parse_md_file,
parse_yml_file,
parse_yml_file_base,
update_advisory_bugs,
)
from bedrock.utils.git import GitRepo
from bedrock.utils.management.cron_command import CronCommand
from bedrock.utils.management.decorators import alert_sentry_on_exception
ADVISORIES_REPO = settings.MOFO_SECURITY_ADVISORIES_REPO
ADVISORIES_PATH = settings.MOFO_SECURITY_ADVISORIES_PATH
ADVISORIES_BRANCH = settings.MOFO_SECURITY_ADVISORIES_BRANCH
SM_RE = re.compile(r"seamonkey", flags=re.IGNORECASE)
FNULL = open(os.devnull, "w")
HOF_FILES = ["client.yml", "web.yml"]
HOF_DIRECTORY = "bug-bounty-hof"
def fix_product_name(name):
if "seamonkey" in name.lower():
name = SM_RE.sub("SeaMonkey", name, 1)
if name.endswith(".0"):
name = name[:-2]
return name
def filter_advisory_filenames(filenames):
return [os.path.join(ADVISORIES_PATH, fn) for fn in filenames if FILENAME_RE.search(fn)]
def delete_files(filenames):
ids = get_ids_from_files(filenames)
SecurityAdvisory.objects.filter(id__in=ids).delete()
def add_or_update_advisory(data, html):
"""
Add or update an advisory in the database.
:param data: dict of metadata about the advisory
:param html: HTML content of the advisory
:return: SecurityAdvisory
"""
mfsa_id = data.pop("mfsa_id")
year, order = (int(x) for x in mfsa_id.split("-"))
kwargs = {
"id": mfsa_id,
"title": data.pop("title"),
"impact": data.pop("impact", None) or "",
"reporter": data.pop("reporter", None) or "",
"year": year,
"order": order,
"html": html,
}
datestr = data.pop("announced", None)
if datestr:
dateobj = parsedate(datestr).date()
kwargs["announced"] = dateobj
prodver_objs = []
fixed_in = data.pop("fixed_in")
if isinstance(fixed_in, str):
fixed_in = [fixed_in]
for productname in fixed_in:
productname = fix_product_name(productname)
productobj, created = Product.objects.get_or_create(name=productname)
prodver_objs.append(productobj)
# discard products. we rely on fixed_in.
data.pop("products", None)
if data:
kwargs["extra_data"] = data
advisory = SecurityAdvisory(**kwargs)
advisory.save()
advisory.fixed_in.clear()
advisory.fixed_in.add(*prodver_objs)
return advisory
def add_hofers(filename, data):
check_hof_data(data)
program = os.path.basename(filename)[:-4]
HallOfFamer.objects.filter(program=program).delete()
for hofer in data["names"]:
HallOfFamer.objects.create(
program=program,
name=hofer["name"],
date=hofer["date"],
url=hofer.get("url", ""),
)
def parse_cve_id(cve_id):
cve_year, cve_order = cve_id.split("-")[1:]
return int(cve_year), int(cve_order)
def add_or_update_cve(data):
for cve_id, advisory in data["advisories"].items():
if not cve_id.startswith("CVE-"):
# skip advisories that are not CVE
continue
if not advisory.get("feed", True):
# skip advisories with `feed: false`
continue
cve_year, cve_order = parse_cve_id(cve_id)
update_advisory_bugs(advisory)
cve_title = advisory.get("cve_problemtype", advisory.get("title")) or ""
cve_data = {
"id": cve_id,
"year": cve_year,
"order": cve_order,
"title": cve_title,
"impact": advisory["impact"] or "",
"reporter": advisory["reporter"] or "",
"description": advisory["description"] or "",
"bugs": advisory["bugs"],
}
try:
cve = MitreCVE.objects.get(id=cve_id)
except MitreCVE.DoesNotExist:
cve = MitreCVE(**cve_data)
cve.products = data["fixed_in"]
cve.mfsa_ids.append(data["mfsa_id"])
else:
cve.products = list(set(cve.products).union(data["fixed_in"]))
cve.mfsa_ids = list(set(cve.mfsa_ids).union([data["mfsa_id"]]))
for prop, value in cve_data.items():
if value:
setattr(cve, prop, value)
cve.save()
def update_db_from_file(filename):
"""
Parse file for YAML and Markdown and update database.
:raises: KeyError or ValueError
:param filename: path to markdown file.
:return: SecurityAdvisory instance
"""
if HOF_DIRECTORY in filename:
return add_hofers(filename, parse_yml_file_base(filename))
if filename.endswith(".md"):
parser = parse_md_file
elif filename.endswith(".yml"):
parser = parse_yml_file
else:
raise RuntimeError(f"Unknown file type {filename}")
data, html = parser(filename)
if "advisories" in data:
add_or_update_cve(data)
return add_or_update_advisory(data, html)
def get_all_mfsa_files():
return glob.glob(os.path.join(ADVISORIES_PATH, "announce", "*", "mfsa*.*"))
def get_all_hof_files():
return [os.path.join(ADVISORIES_PATH, HOF_DIRECTORY, fn) for fn in HOF_FILES]
def get_all_file_names():
"""Return every file to process"""
return get_all_mfsa_files() + get_all_hof_files()
def get_ids_from_files(filenames):
ids = [mfsa_id_from_filename(fn) for fn in filenames]
# filter any Nones
return [mfsa_id for mfsa_id in ids if mfsa_id]
def get_files_to_delete_from_db(filenames):
"""Delete any advisories in the DB that have no file in the repo."""
file_ids = set(get_ids_from_files(filenames))
db_ids = set(SecurityAdvisory.objects.values_list("id", flat=True))
to_delete = db_ids - file_ids
return [f"mfsa{fid}.md" for fid in to_delete]
def delete_orphaned_products():
"""Delete any products with no advisories"""
products = Product.objects.annotate(num_advisories=Count("advisories")).filter(num_advisories=0)
num_products = products.count()
products.delete()
return num_products
@alert_sentry_on_exception
class Command(CronCommand):
help = "Refresh database of MoFo Security Advisories."
lock_key = "update_security_advisories"
def add_arguments(self, parser):
parser.add_argument(
"--quiet",
action="store_true",
dest="quiet",
default=False,
help="Do not print output to stdout.",
)
parser.add_argument(
"--skip-git",
action="store_true",
dest="no_git",
default=False,
help="No update, just import all files",
)
parser.add_argument(
"--clear-db",
action="store_true",
dest="clear_db",
default=False,
help="Clear all security advisory data and load all files",
)
def handle_safe(self, quiet, no_git, clear_db, **options):
force = no_git or clear_db
repo = GitRepo(
ADVISORIES_PATH,
ADVISORIES_REPO,
branch_name=ADVISORIES_BRANCH,
name="Security Advisories",
)
def printout(msg, ending=None):
if not quiet:
self.stdout.write(msg, ending=ending)
if clear_db:
printout("Clearing all security advisories.")
SecurityAdvisory.objects.all().delete()
Product.objects.all().delete()
MitreCVE.objects.all().delete()
if not no_git:
printout("Updating repository.")
repo.update()
if not (force or repo.has_changes()):
printout("Nothing to update.")
return
errors = []
updates = 0
all_files = get_all_file_names()
for mf in all_files:
try:
update_db_from_file(mf)
except Exception as e:
errors.append(f"ERROR parsing {mf}: {e}")
if not quiet:
sys.stdout.write("E")
sys.stdout.flush()
continue
if not quiet:
sys.stdout.write(".")
sys.stdout.flush()
updates += 1
printout(f"\nUpdated {updates} files.")
if not clear_db:
deleted_files = get_files_to_delete_from_db(all_files)
delete_files(deleted_files)
printout(f"Deleted {len(deleted_files)} files.")
num_products = delete_orphaned_products()
if num_products:
printout(f"Deleted {num_products} orphaned products.")
if errors:
raise CommandError(f"Encountered {len(errors)} errors:\n\n" + "\n==========\n".join(errors))
repo.set_db_latest()

Просмотреть файл

@ -1,54 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import django.utils.timezone
from django.db import migrations, models
import django_extensions.db.fields
import django_extensions.db.fields.json
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.CreateModel(
name="Product",
fields=[
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
("name", models.CharField(unique=True, max_length=50)),
("slug", models.CharField(max_length=50, db_index=True)),
("product", models.CharField(max_length=50)),
("product_slug", models.SlugField()),
],
options={
"ordering": ("slug",),
},
bases=(models.Model,),
),
migrations.CreateModel(
name="SecurityAdvisory",
fields=[
("id", models.CharField(max_length=8, serialize=False, primary_key=True, db_index=True)),
("title", models.CharField(max_length=200)),
("impact", models.CharField(max_length=100)),
("reporter", models.CharField(max_length=100, null=True)),
("announced", models.DateField(null=True)),
("year", models.SmallIntegerField()),
("order", models.SmallIntegerField()),
("extra_data", django_extensions.db.fields.json.JSONField()),
("html", models.TextField()),
(
"last_modified",
django_extensions.db.fields.ModificationDateTimeField(default=django.utils.timezone.now, editable=False, blank=True),
),
("fixed_in", models.ManyToManyField(related_name="advisories", to="security.Product")),
],
options={
"ordering": ("-year", "-order"),
"get_latest_by": "last_modified",
},
bases=(models.Model,),
),
]

Просмотреть файл

@ -1,25 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("security", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="securityadvisory",
name="impact",
field=models.CharField(max_length=100, blank=True),
),
migrations.AlterField(
model_name="securityadvisory",
name="reporter",
field=models.CharField(default="", max_length=100, blank=True),
preserve_default=False,
),
]

Просмотреть файл

@ -1,27 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("security", "0002_auto_20161013_0642"),
]
operations = [
migrations.CreateModel(
name="HallOfFamer",
fields=[
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
("program", models.CharField(max_length=10, choices=[(b"web", b"Web"), (b"client", b"Client")])),
("name", models.CharField(max_length=200)),
("date", models.DateField()),
("url", models.CharField(max_length=200, blank=True)),
],
options={
"ordering": ("-date", "id"),
},
),
]

Просмотреть файл

@ -1,33 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from django.db import migrations, models
import django_extensions.db.fields.json
class Migration(migrations.Migration):
dependencies = [
("security", "0003_halloffamer"),
]
operations = [
migrations.CreateModel(
name="MitreCVE",
fields=[
("id", models.CharField(max_length=15, serialize=False, primary_key=True, db_index=True)),
("year", models.SmallIntegerField()),
("order", models.SmallIntegerField()),
("title", models.CharField(max_length=200, blank=True)),
("impact", models.CharField(max_length=100, blank=True)),
("reporter", models.CharField(max_length=100, blank=True)),
("description", models.TextField()),
("products", django_extensions.db.fields.json.JSONField(default="[]")),
("bugs", django_extensions.db.fields.json.JSONField(default="[]")),
],
options={
"ordering": ("-year", "-order"),
},
),
]

Просмотреть файл

@ -1,21 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from django.db import migrations
import django_extensions.db.fields.json
class Migration(migrations.Migration):
dependencies = [
("security", "0004_mitrecve"),
]
operations = [
migrations.AddField(
model_name="mitrecve",
name="mfsa_ids",
field=django_extensions.db.fields.json.JSONField(default="[]"),
),
]

Просмотреть файл

@ -1,28 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# Generated by Django 2.2.8 on 2020-01-22 17:57
from django.db import migrations, models
import django_extensions.db.fields
class Migration(migrations.Migration):
dependencies = [
("security", "0005_mitrecve_mfsa_ids"),
]
operations = [
migrations.AlterField(
model_name="halloffamer",
name="program",
field=models.CharField(choices=[("web", "Web"), ("client", "Client")], max_length=10),
),
migrations.AlterField(
model_name="securityadvisory",
name="last_modified",
field=django_extensions.db.fields.ModificationDateTimeField(auto_now=True),
),
]

Просмотреть файл

@ -1,36 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# Generated by Django 4.2.11 on 2024-05-07 20:29
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("security", "0006_auto_20200122_0957"),
]
operations = [
migrations.AlterField(
model_name="mitrecve",
name="order",
field=models.IntegerField(),
),
migrations.AlterField(
model_name="mitrecve",
name="year",
field=models.IntegerField(),
),
migrations.AlterField(
model_name="securityadvisory",
name="order",
field=models.IntegerField(),
),
migrations.AlterField(
model_name="securityadvisory",
name="year",
field=models.IntegerField(),
),
]

Просмотреть файл

@ -1,36 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
# Generated by Django 4.2.11 on 2024-05-08 20:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("security", "0007_alter_mitrecve_order_alter_mitrecve_year_and_more"),
]
operations = [
migrations.AlterField(
model_name="mitrecve",
name="reporter",
field=models.CharField(blank=True, max_length=500),
),
migrations.AlterField(
model_name="product",
name="name",
field=models.CharField(max_length=100, unique=True),
),
migrations.AlterField(
model_name="product",
name="slug",
field=models.CharField(db_index=True, max_length=100),
),
migrations.AlterField(
model_name="securityadvisory",
name="reporter",
field=models.CharField(blank=True, max_length=500),
),
]

Просмотреть файл

@ -1,3 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,260 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from functools import total_ordering
from django.db import models
from django.template.defaultfilters import slugify
from django_extensions.db.fields import ModificationDateTimeField
from django_extensions.db.fields.json import JSONField
from product_details.version_compare import Version
from bedrock.base.urlresolvers import reverse
@total_ordering
class Product(models.Model):
name = models.CharField(max_length=100, unique=True)
slug = models.CharField(max_length=100, db_index=True)
product = models.CharField(max_length=50)
product_slug = models.SlugField()
class Meta:
ordering = ("slug",)
def __str__(self):
return self.name
def __lt__(self, other):
return self.name_tuple < other.name_tuple
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
# do not use self.name_tuple because don't want ".0" on versions.
product, vers = self.name_and_version
self.product = product
self.product_slug = slugify(product)
self.slug = f"{self.product_slug}-{vers}"
super().save(force_insert, force_update, using, update_fields)
def get_absolute_url(self):
product, vers = self.name_and_version
return reverse("security.product-version-advisories", kwargs={"product": product, "version": vers})
@property
def name_and_version(self):
return self.name.rsplit(None, 1)
@property
def name_tuple(self):
product, vers = self.name_and_version
if "." not in vers:
vers += ".0"
return product, Version(vers)
@property
def html_id(self):
"""Conform to the IDs from the old page so old URL anchors work."""
return self.slug.replace("-", "")
@property
def version(self):
return self.name_tuple[1]
class SecurityAdvisory(models.Model):
id = models.CharField(max_length=8, primary_key=True, db_index=True)
title = models.CharField(max_length=200)
impact = models.CharField(max_length=100, blank=True)
reporter = models.CharField(max_length=500, blank=True)
announced = models.DateField(null=True)
year = models.IntegerField()
order = models.IntegerField()
fixed_in = models.ManyToManyField(Product, related_name="advisories")
extra_data = JSONField()
html = models.TextField()
last_modified = ModificationDateTimeField()
class Meta:
ordering = ("-year", "-order")
get_latest_by = "last_modified"
def __str__(self):
return f"MFSA {self.id}"
def get_absolute_url(self):
return reverse("security.advisory", kwargs={"pk": self.id})
@property
def impact_class(self):
if self.impact:
return self.impact.lower().split(None, 1)[0]
else:
return "none"
@property
def products(self):
prods_set = {v.product for v in self.fixed_in.all()}
return sorted(prods_set)
class HallOfFamer(models.Model):
ORDINALS = {
1: "1st",
2: "2nd",
3: "3rd",
4: "4th",
}
PROGRAM_CHOICES = (
("web", "Web"),
("client", "Client"),
)
program = models.CharField(max_length=10, choices=PROGRAM_CHOICES)
name = models.CharField(max_length=200)
date = models.DateField()
url = models.CharField(max_length=200, blank=True)
class Meta:
ordering = ("-date", "id")
def __str__(self):
return f"{self.program}/{self.name}"
@property
def year_quarter(self):
"""Return the year and quarter based on the date field.
@return tuple: (int year, int quarter)
"""
quarter = ((self.date.month - 1) // 3) + 1
return self.date.year, quarter
@property
def quarter_string(self):
year, quarter = self.year_quarter
return f"{self.ORDINALS[quarter]} Quarter {year}"
class MitreCVE(models.Model):
id = models.CharField(max_length=15, primary_key=True, db_index=True)
year = models.IntegerField()
order = models.IntegerField()
title = models.CharField(max_length=200, blank=True)
impact = models.CharField(max_length=100, blank=True)
reporter = models.CharField(max_length=500, blank=True)
description = models.TextField()
products = JSONField(default="[]")
mfsa_ids = JSONField(default="[]")
bugs = JSONField(default="[]")
class Meta:
ordering = ("-year", "-order")
def __str__(self):
return self.id
def product_versions(self):
"""Return a list of version numbers per product"""
prod_vers = {}
for prod in self.products:
prod_name, version = prod.rsplit(None, 1)
if prod_name in prod_vers:
prod_vers[prod_name].append(version)
else:
prod_vers[prod_name] = [version]
return prod_vers
def get_description(self):
versions = []
for prod_name, prod_versions in self.product_versions().items():
versions.extend(f"{prod_name} < {v}" for v in prod_versions)
description = self.description.strip()
if versions:
if len(versions) == 1:
vers_str = versions[0]
elif len(versions) == 2:
vers_str = " and ".join(versions)
else:
vers_str = ", ".join(versions[:-1]) + ", and " + versions[-1]
if description:
if description.endswith("."):
description += " "
else:
description += ". "
description += f"This vulnerability affects {vers_str}."
return description
def get_product_data(self):
product_data = []
for prod_name, versions in self.product_versions().items():
product_data.append(
{
"product_name": prod_name,
"version": {
"version_data": [{"version_value": vers, "version_affected": "<"} for vers in versions],
},
}
)
return product_data
def get_reference_data(self):
reference_data = [{"url": f"https://www.mozilla.org/security/advisories/mfsa{mfsa_id}/"} for mfsa_id in set(self.mfsa_ids)]
reference_data.extend([{"url": bug["url"]} for bug in self.bugs])
return reference_data
def feed_entry(self):
"""Return a MITRE format data structure for the CVE
See https://github.com/CVEProject/automation-working-group/blob/master/cve_json_schema/DRAFT-JSON-file-format-v4.md
"""
return {
"data_type": "CVE",
"data_format": "MITRE",
"data_version": "4.0",
"CVE_data_meta": {
"ID": self.id,
"ASSIGNER": "security@mozilla.org",
},
"affects": {
"vendor": {
"vendor_data": [
{
"vendor_name": "Mozilla",
"product": {
"product_data": self.get_product_data(),
},
}
]
}
},
"problemtype": {
"problemtype_data": [
{
"description": [
{
"lang": "eng",
"value": self.title,
}
]
}
]
},
"references": {
"reference_data": self.get_reference_data(),
},
"description": {
"description_data": [
{
"lang": "eng",
"value": self.get_description(),
}
]
},
}

Просмотреть файл

@ -1,19 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from bedrock.redirects.util import redirect
redirectpatterns = (
# bug 818323
redirect(r"^projects/security/known-vulnerabilities\.html$", "security.known-vulnerabilities"),
redirect(r"^projects/security/older-vulnerabilities\.html$", "security.older-vulnerabilities"),
# bug 1090468
redirect(
r"^security/(?P<page>older-alerts|security-announcement|phishing-test(-results)?)\.html$",
"http://website-archive.mozilla.org/www.mozilla.org/security/security/{page}.html",
),
redirect(
r"^security/iSECPartners_Phishing\.pdf$", "http://website-archive.mozilla.org/www.mozilla.org/security/security/iSECPartners_Phishing.pdf"
),
)

Просмотреть файл

@ -1,27 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Mozilla Foundation Security Advisories{% endblock %}
{% set body_id = "advisories" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Mozilla Foundation Security Advisories</h1>
</header>
{% include "security/partials/impact_key.html" %}
{% for group in advisories|groupby('announced')|reverse %}
<h2>{{ group.grouper|datetime }}</h2>
<ul>
{% for advisory in group.list %}
<li class="level-item">
<a href="{{ advisory.get_absolute_url() }}"><span class="level {{ advisory.impact_class }}">MFSA {{ advisory.id }}</span> {{ advisory.title|safe }}</a></li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}

Просмотреть файл

@ -1,61 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}{{ advisory.title|striptags }}{% endblock %}
{% block article %}
<div class="advisory">
<header>
<h1 class="mzp-c-article-title">Mozilla Foundation Security Advisory {{ advisory.id }}</h1>
</header>
<h2>{{ advisory.title|safe }}</h2>
<dl class="summary">
{% if advisory.announced %}
<dt>Announced</dt>
<dd>{{ advisory.announced|datetime }}</dd>
{% endif %}
{% if advisory.reporter %}
<dt>Reporter</dt>
<dd>{{ advisory.reporter|safe }}</dd>
{% endif %}
{% if 'risk' in advisory.extra_data %}
<dt>Risk</dt>
<dd>{{ advisory.extra_data.risk }}</dd>
{% endif %}
{% if advisory.impact %}
<dt>Impact</dt>
<dd><span class="level {{ advisory.impact_class }}">{{ advisory.impact }}</span></dd>
{% endif %}
<dt>Products</dt>
<dd>{{ ', '.join(advisory.products) }}</dd>
<dt>Fixed in</dt>
<dd>
<ul>
{% for prodver in advisory.fixed_in.all() %}
<li>{{ prodver.name }}</li>
{% endfor %}
</ul>
</dd>
{% if 'vulnerable' in advisory.extra_data %}
<dt>Vulnerable</dt>
<dd>
<ul>
{% for prod in advisory.extra_data.vulnerable %}
<li>{{ prod }}</li>
{% endfor %}
</ul>
</dd>
{% endif %}
</dl>
{{ advisory.html|safe }}
</div>
{% endblock %}

Просмотреть файл

@ -1,41 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "base-article.html" %}
{% block page_css %}
{{ css_bundle('security') }}
{% endblock %}
{% set navigation_bar_security = [
(url('security.index'), 'security-index', 'Mozilla Security'),
(url('security.advisories'), 'advisories', 'Advisories'),
(url('security.known-vulnerabilities'), 'known-vulnerabilities', 'Known Vulnerabilities'),
('https://blog.mozilla.com/security/', 'blog', 'Mozilla Security Blog'),
(url('security.bug-bounty'), 'bug-bounty', 'Security Bug Bounty'),
(url('security.third-party-injection-policy'), 'third-party-software-injection', 'Third-party Injection Policy'),
] %}
{% set navigation_bar_client_bounty = [
(url('security.client-bug-bounty'),'client-bug-bounty', 'Client Bug Bounty'),
(url('security.bug-bounty.faq'), 'faq', 'Frequently Asked Questions'),
(url('security.bug-bounty.hall-of-fame'), 'hall-of-fame', 'Hall of Fame'),
] %}
{% set navigation_bar_web_bounty = [
(url('security.web-bug-bounty'), 'web-bug-bounty', 'Web Bug Bounty'),
(url('security.bug-bounty.web-eligible-sites'), 'web-eligible-sites', 'Eligible Websites'),
(url('security.bug-bounty.faq-webapp'), 'faq-webapp', 'Frequently Asked Questions'),
(url('security.bug-bounty.web-hall-of-fame'), 'web-hall-of-fame', 'Hall of Fame'),
] %}
{% block body_class %}mzp-t-mozilla {% endblock %}
{% block side_nav %}
{{ sidemenu_lists([navigation_bar_security, navigation_bar_client_bounty, navigation_bar_web_bounty], body_id) }}
{% endblock %}
{% block newsletter %}{% endblock %}

Просмотреть файл

@ -1,73 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Security Bug Bounty Program{% endblock %}
{% set body_id = "bug-bounty" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Security Bug Bounty Program</h1>
</header>
<h2 id="intro">Introduction</h2>
<p>The Mozilla Security Bug Bounty Program is designed to encourage security research in Mozilla software and to reward those who help us make the internet a safer place.</p>
<h2 id="general-eligibility">General Eligibility</h2>
<p>To be eligible for a reward under this program: </p>
<ul class="mzp-u-list-styled">
<li>The security bug must be original and previously unreported. Duplicate submissions within 72 hours will split the bounty between reporters. If duplicate submissions are of unequal quality, the split will be at the level of the lesser report, and the greater report will receive a pro-rated additional bounty on top of the split.</li>
<li>For issues in client applications, there is a seven-day grace period that begins when the vulnerability is checked into the primary source repository. If the issue is identified internally within those seven days, it is ineligible for a bounty, even if the issue is not recognized as a security vulnerability at time of first identification. If it lasts undiscovered for more than seven days, it becomes eligible for a bounty.</li>
<li>The security bug must be a part of Mozillas code, not the code of a third party. We will pay bounties for vulnerabilities in third-party libraries incorporated into shipped client code or third-party websites utilized by Mozilla.</li>
<li>You must not have written the buggy code or otherwise been involved in contributing the buggy code to the Mozilla project.</li>
<li>You must be old enough to be eligible participate in and receive payment from this program in your jurisdiction, or otherwise qualify to receive payment, whether through consent from your parent or guardian or some other way.</li>
<li>You must not be an employee, contractor, or otherwise have a business relationship with the Mozilla Foundation or any of its subsidiaries.</li>
<li>You should use your best effort not to access, modify, delete, or store user data or Mozillas data. Instead, use your own accounts or test accounts for security research purposes.</li>
<li>If you inadvertently access, modify, delete, or store user data, we ask that you notify Mozilla immediately at <a href="mailto:security@mozilla.org">security@mozilla.org</a> and delete any stored data after notifying us.</li>
<li>You should also use your best effort not to harm the availability or stability of our services, for example, by running aggressive scanning of those services. Instead, use a local development instance of the service that you want to test. </li>
<li>Whenever it is explicitly stated in our program scope, you are expected to test on the provided instances (e.g. staging) instead of production.</li>
<li>You must not be on a US sanctions list or in a country (e.g. Cuba, Iran, North Korea, Crimea region of Ukraine, Sudan, and Syria) on the US sanctions list.</li>
<li>You must not exploit the security vulnerability for your own gain.</li>
<li>Before sharing any part of the security issue with a third party, you must give us a reasonable amount of time to address the security issue.</li>
<li>All submissions will be covered under <a href="https://www.mozilla.org/about/legal/terms/mozilla/">Mozilla's Website & Communications Terms of Use</a>, granting us permission to make use of all submissions.</li>
<li>All questions regarding the status of bug bounties should be directed to <a href="mailto:security@mozilla.org">security@mozilla.org</a> and not added as comments on Bugzilla.</li>
<li>All submissions must also abide by <a href="https://bugzilla.mozilla.org/page.cgi?id=etiquette.html">Bugzilla's Etiquette Policy</a>. Bugzilla may automatically disable accounts if too many bugs are submitted that get marked Invalid; if this happens you can contact <a href="mailto:security@mozilla.org">security@mozilla.org</a>; however, please be aware that too many invalid submissions may cause any valid bugs reported to receive reduced payouts. Please ask us for suggestions of how to improve your submission quality.</a>
</ul>
<p>Bounties can be donated to charity, please indicate this in the bug when filing or by contacting <a href="mailto:security@mozilla.org">security@mozilla.org</a>.</p>
<p>Do not threaten or attempt to extort Mozilla. We will not award a bounty if you threaten to withhold the security issue from us or if you threaten to release the vulnerability or any exposed data to the public.</p>
<h2>Safe Harbor</h2>
<p>Mozilla strongly supports security research into our products and wants to encourage that research.</p>
<p>As a result, we will not threaten or bring any legal action against anyone who makes a good faith effort to comply with this Bug Bounty Program, or for any accidental or good faith violation of this policy. This includes any claim under the DMCA for circumventing technological measures to protect the services and applications eligible under this policy.</p>
<p>As long as you comply with this policy:</p>
<ul class="mzp-u-list-styled">
<li>We consider your security research to be "authorized" under the Computer Fraud and Abuse Act,</li>
<li>We waive any restrictions in our applicable Terms of Service and <a href="https://www.mozilla.org/about/legal/acceptable-use/">Acceptable Use Policy</a> that would prohibit your participation in this policy, for the limited purpose of your security research under this policy.</li>
</ul>
<p>We understand that many Mozilla systems and services are interconnected with third-party systems and services. While we can authorize your research on Mozillas systems and services, and promise that Mozilla will not bring or threaten litigation against you for your efforts under this policy, we cannot authorize efforts on third-party products or guarantee they wont pursue legal action against you. However, if a third party threatens or brings any legal action against you for your efforts under this policy, we are willing to make clear&mdash;to the Court, the public, or otherwise--that we authorized your efforts to test and research the security of Mozillas eligible systems and services.</p>
<p><strong>If youre not sure whether your conduct complies with this policy, please contact us first at <a href="mailto:security@mozilla.org">security@mozilla.org</a> and we will do our best to clarify.</strong></p>
<h2>Web and Client</h2>
<p>Mozilla manages two different bug bounty programs. One focuses on Firefox and other Mozilla applications and the other covers our websites and services.</p>
<ul class="mzp-u-list-styled">
<li><a href="{{ url('security.client-bug-bounty') }}">Client Bug Bounty Guidelines</a></li>
<li><a href="{{ url('security.web-bug-bounty') }}">Web Bug Bounty Guidelines</a></li>
</ul>
{% endblock %}

Просмотреть файл

@ -1,223 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Mozilla Web Application Security Bug Bounty FAQ{% endblock %}
{% set body_id = "faq-webapp" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Web Bug Bounty FAQ</h1>
</header>
<h3>General questions</h3>
<ul class="mzp-u-list-styled">
<li><a href="#why">Why do we include web applications as part
of our bug bounty program?</a></li>
<li><a href="#howto">How can I find potential vulnerabilities
and are there things I shouldn't do in trying to discover them?</a></li>
<li><a href="{{ url('security.web-bug-bounty') }}#payouts-section">What are the bounty payouts?</a></li>
</ul>
<h3>Eligible bugs</h3>
<ul class="mzp-u-list-styled">
<li><a href="#eligible-bugs">Which domains and web applications will be
considered to be part of the bug bounty?</a></li>
<li><a href="{{ url('security.web-bug-bounty') }}#payouts-section">
What types of issues will be considered as part of the bounty program?</a></li>
<li><a href="#dos-bugs">Why don't you provide a reward for denial of service
bugs?</a></li>
</ul>
<h3>Bug reporting</h3>
<ul class="mzp-u-list-styled">
<li><a href="#what-next">Once I have found a vulnerability,
what next?</a></li>
<li><a href="#nondisclosure">If I report the bug directly to you,
do I have to keep the bug confidential in order to receive a bouncy?</a></li>
<li><a href="#cooperation">If I dont have the time to assist you further, can I still receive a
bug bounty?</a></li>
<li><a href="#attack-scenario">What does a valid attack scenario look like?</a></li>
<li><a href="#step-by-step-exploit">What does a valid step-by-step exploit process look like?</a></li>
<li><a href="#xss-reporting">How should I report an XSS vulnerability?</a></li>
</ul>
<h2 id="general-questions">General questions</h2>
<dl class="mzp-u-list-styled">
<dt id="why">Why do we include web applications as part of our bug bounty program?</dt>
<dd>
<p>Mozilla client software relies heavily on web services, and Mozillas
community uses our websites and services to communicate and coordinate activity.
Our goal is to make these products and services as safe and secure as possible.
</p>
</dd>
<dt id="howto">How can I find potential vulnerabilities and are there things I shouldnt do in trying to discover them?</dt>
<dd>
<p>We have received many questions around how to discover web application
security issues, largely revolving around use of automated attack tools
such as ZAP and Burp.</p>
<p>We request that people refrain from using automated tools against our production web
services, as it is important to maintain our services' availability and minimize
unintentional vandalism. Since our code is open source, you are encouraged to run
it on your own server instance or examine the it directly for potential issues.</p>
</dd>
</dl>
<h2 id="eligible-bugs">Eligible bugs</h2>
<dl class="mzp-u-list-styled">
<dt id="eligible-bugs">Which domains and web applications will be considered to be part of the bug bounty?</dt>
<dd>
<p>Only a limited subset of our websites are eligible for monetary
payouts. Please see our HackerOne Mozilla <a href="https://hackerone.com/mozilla/policy_scopes">policy page</a>
for additional information. Note that some low severity
issues are not eligible for monetary awards based on their impact. We
will recognize the reporter by thanking them on the <a href="https://hackerone.com/mozilla/thanks">Thanks
page</a>.</p>
</dd>
<dt id="dos-bugs">Why dont you provide a reward for denial-of-service bugs?</dt>
<dd>
<p>Denial-of-services bugs are generally less serious than other web application
security bugs and in many cases don't require a technical vulnerability
within the web application.</p>
</dd>
</dl>
<h2 id="bug-reporting">Bug reporting</h2>
<dl class="mzp-u-list-styled">
<dt id="what-next">Once I have found a vulnerability, what next?</dt>
<dd>
<p>The sooner we can reproduce the bug, the sooner we can fix it
and send you your bounty. Please submit all bugs to our HackerOne program <a href="https://hackerone.com/mozilla">Mozilla</a>.
<strong>Do not send vulnerabilities via email and please avoid using video.</strong></p>
<p>There are three main things you can provide which will help us
to evaluate your submission quickly and pay a bounty sooner:</p>
<ol>
<li><a href="#attack-scenario">What is the attack scenario?</a></li>
<li><a href="#step-by-step-exploit">What is the step-by-step exploit process?</a></li>
<li>What is the security impact?</li>
</ol>
<p>Once you have <em>written</em> your step-by-step instructions,
repeat the attack by following them exactly. This helps prevent
errors and omissions in your submission.</p>
<p>We prefer to receive bug reports in English. If English is not
your native language and you are not fluent, please submit bugs
in your native language. Please note that this may delay our
response time.</p>
</dd>
<dt id="nondisclosure">If I report the bug directly to you, do I have to keep the bug confidential to receive a bounty?</dt>
<dd>
<p>Were rewarding you for finding a bug, not trying to buy
your silence. However, if you report the bug through the standard
Mozilla process and havent already published information about it then
we do ask that you keep the bug private for a limited period of time to
give us a chance to fix the bug before the bug is made public.</p>
<p>Bug reporters may open the bug to public view earlier whenever circumstances
warrant it (e.g., if you feel your bug report is being completely ignored).
However, in the interests of protecting our users, we would appreciate a
reasonable amount of time to address the issue before the information is
publicly disclosed.</p>
</dd>
<dt id="cooperation">If I dont have the time to assist you further, can I still receive a bug bounty?</dt>
<dd>
<p>Were rewarding you for finding a bug, not trying to buy your cooperation.</p>
<p>However, we do invite you to work together with us, and we hope that youll
accept that offer in the spirit in which it was intended. In return, youll get
the opportunity to work as a full member of the team and see exactly how Mozilla
security bugs are resolved.</p>
</dd>
<dt id="attack-scenario">What does a valid attack scenario look like?</dt>
<dd>
<p>Please describe how an attacker would use the bug you
are submitting, any necessary conditions for it to work, and what the attacker
would gain through a successful attack.</p>
<p>Please answer the following questions to the best of your ability:</p>
<ol class="mzp-u-list-styled">
<li>What is the necessary position of the attacker?
<ul>
<li>Do you need to be logged in or unauthenticated?</li>
<li>Do certain cookies need to be set?</li>
<li>Do you need to connect from a specific system?</li>
</ul>
</li>
<li>Are there any other assumptions that must be made about the victim?
<ul>
<li>Do they need to be running a specific web browser?</li>
<li>Does the victim need to be tricked into clicking on a specific link?</li>
<li>Does the user need to be a member of a specific group?</li>
</ul>
</li>
<li>How might a malicious actor use this attack?
<ul class="mzp-u-list-styled">
<li>Stealing a victim's session information</li>
<li>Redirect users to malicious websites</li>
<li>Read files on server outside the web root</li>
<li>Executing remote OS commands</li>
<li>XSSing users</li>
</ul>
</li>
</ol>
</dd>
<dt id="step-by-step-exploit">What does a valid step-by-step exploit process look like?</dt>
<dd>
<p>Please describe the process required, step-by-step, in the proper order.
If there are multiple parties involved, please describe them all clearly. For example:</p>
<ol class="mzp-u-list-styled">
<li>Visit <code>https://shop.firefox.com/order?name=value&amp;name2=value2</code></li>
<li>Click the "Log in" link and login</li>
<li>Click the "Order" button</li>
<li>Place order for "Firefox Plush"
<li>Continue navigation to the Shipping Address page</li>
<li>Add the following payload <code>"&gt;&lt;img src=x onerror=alert(document.domain);// &gt;</code> into the "City" field, then click Submit</li>
<li>The XSS payload ends up in the <code>POST</code> parameter named <code>city_order</code></li>
<li>Visitors to the page <code>/past_orders_by_city</code> are affected by stored XSS</li>
</ol>
<p>Include the HTTP request(s), any necessary header values and/or
<code>POST</code> parameters along with your bug submission.</p>
<p>Once you have <em>written</em> your step-by-step instructions,
repeat the attack by following them exactly. This helps prevent errors
and omissions in your submission.</p>
</dd>
<dt id="xss-reporting">How should I report an XSS vulnerability?</dt>
<dd>
<p>For a reflected XSS vulnerabilities, the affected URL along with
a working payload is usually sufficient. For stored XSS attacks, please
describe the step-by-step exploit process, as above.</p>
<p>Please use <code>alert(document.domain)</code> and not
<code>alert(1)</code> in your proof-of-concept.</p>
<p>Self-XSSes &mdash; where the attacker tricks users into copying
and pasting malicious script content &mdash; are not eligible for
bounties.</p>
</dd>
</dl>
{% endblock %}

Просмотреть файл

@ -1,278 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Bug Bounty Program FAQ{% endblock %}
{% set body_id = "faq" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Bug Bounty Program FAQ</h1>
</header>
<p>This FAQ attempts to answer various questions about the Mozilla
security bug bounty program sponsored by the Mozilla Foundation. For
more information see the
<a href="{{ url('security.bug-bounty') }}">official guidelines</a>
governing the program.</p>
<h3>General questions</h3>
<ul class="mzp-u-list-styled">
<li><a href="#why">Why is the Mozilla Foundation doing this?</a></li>
<li><a href="#eligibility">Are Mozilla developers eligible for the bug bounty
reward?</a></li>
</ul>
<h3>Eligible software</h3>
<ul class="mzp-u-list-styled">
<li><a href="#other-products">What applications are in scope?</a></li>
<li><a href="#bugzilla-etc">Does the bug bounty cover bugs found in
Bugzilla, Rust, Rhino, and other software created and distributed
as part of the Mozilla project?</a></li>
<li><a href="#most-recent">What do you mean by the "most recent version"
of Firefox, and/or Firefox for Android?</a></li>
<li><a href="#older-releases">Can I get the bug bounty reward if I
discover a bug in an older release of Firefox, and/or Firefox for Android?
</a></li>
<li><a href="#third-party-releases">Can I get the bug bounty reward
if I discover a bug that occurs in a third-party release of Firefox, and/or
Firefox for Android,(e.g., a localized build, optimized
build, or third-party Firefox, or Firefox for Android distribution)?</a></li>
<li><a href="#platform-specific">Can I get the bug bounty reward if I
discover a bug that occurs only on a particular operating system?</a></li>
<li><a href="#nondefault-pref">Can I get the bug bounty reward for a
vulnerability that is only triggerable with non-default preferences?</a></li>
</ul>
<h3>Eligible bugs</h3>
<ul class="mzp-u-list-styled">
<li><a href="#eligible-bugs">What types of security bugs are eligible?</a></li>
<li><a href="#dos-bugs">Why won't you provide a reward for denial of
service bugs?</a></li>
</ul>
<h3>Bug reporting, etc.</h3>
<ul class="mzp-u-list-styled">
<li><a href="#already-published">I've already published information
about the bug, and didn't go through the Mozilla bug process; can I
still get a reward?</a></li>
<li><a href="#someone-elses-bug">Can I receive a bounty for a vulnerability
I didn't find?</a></li>
<li><a href="#nondisclosure">If I report the bug directly to you, do
I have to keep the bug confidential and not publish information about
it in order to receive a reward?</a></li>
<li><a href="#cooperation">I don't have the time or desire to work
with you further in investigating and fixing the bug; can I still get a
bug bounty reward?</a></li>
</ul>
<h2>General questions</h2>
<dl class="mzp-u-list-styled">
<dt id="why">Why is the Mozilla Foundation doing this?</dt>
<dd>
<p>Because we want to encourage more people to find and report
security bugs in our products, so that we can make our products even
more secure than they already are. It's as simple as that. For a historical note,
you can see the
<a href="https://blog.mozilla.org/press/2004/08/mozilla-foundation-announces-security-bug-bounty-program/">original announcement</a> from 2004.</p>
</dd>
<dt id="eligibility">Are Mozilla developers eligible for the bug bounty reward?</dt>
<dd class="answer">
<p>If you don't work for Mozilla Foundation or its subsidiaries, and
are not among the creators or reviewers of the code in which the bug
was found - Yes. However, if you found this bug as part of your job (in
other words, while being paid to work on Mozilla software) then we'd
appreciate it if you would not apply for the bounty in order to preserve our
limited funds for rewarding volunteer contributors.</p>
</dd>
</dl>
<h2>Eligible software</h2>
<dl class="mzp-u-list-styled">
<dt id="other-products">What applications are in scope?</dt>
<dd>
<p>The primary applications we offer bounties for are the most recent
version of Firefox or Firefox ESR; Firefox for Android, and Firefox
for iOS. Bounties may be awarded for other non-Beta non-End-of-Life products offered by Mozilla which are included in the <a href="https://www.mozilla.org/en-US/security/web-bug-bounty/">Web bug bounty program</a>; however, whether
a bounty is awarded and the amount will be subject to the committee.</p>
</dd>
<dt id="bugzilla-etc">Does the bug bounty cover
bugs found in Bugzilla, Rust, Rhino, and other software created
and distributed as part of the Mozilla project?</dt>
<dd>
<p>No. We have decided to use our limited resources to focus on our
end-user products, as opposed to the other software produced and used
by the Mozilla project. However, we do offer a
<a href="https://www.mozilla.org/en-US/security/web-bug-bounty/">Web
Bug Bounty</a> for the Mozilla web sites and services we run for
Firefox for our users.</p>
</dd>
<dt id="most-recent">What do you mean by the "most recent version" of
Firefox, and/or Firefox for Android?</dt>
<dd>
<p>In general we mean the nightly release available for download on
the <a href="https://ftp.mozilla.org/pub/firefox/nightly/">Mozilla
ftp site</a> at the time the bug was reported. However we will also
consider paying rewards for security bugs as discussed in the questions
and answers below.</p>
</dd>
<dt id="older-releases">Can I get the bug
bounty reward if I discover a bug in an older release of Firefox and/or
Firefox for Android?</dt>
<dd>
<p>In general bugs found in earlier releases are eligible for a
reward only if we can reproduce the problem using the most recent
version.</p>
<p>However as an exception we will typically also pay a reward for
bugs found in the latest versions of our other channels (Release,
Beta, and Extended Support Release channels) if the bugs are not
present in their most recent version but were never recognized
and fixed as security bugs. (For example, the bug might be in
code associated with a feature that was removed and/or heavily
modified in the most recent version, and might have been "fixed"
solely as a byproduct of other unrelated changes.)</p>
</dd>
<dt id="third-party-releases">Can I get the bug
bounty reward if I discover a bug that occurs in a third-party release
of Firefox, Firefox and/or Firefox for Android (e.g., a localized
build, optimized build, or third-party Firefox or Firefox for Android)?</dt>
<dd>
<p>Yes, if the bug can be reproduced in an official Mozilla
Foundation release and otherwise meets the published guidelines.</p>
</dd>
<dt id="platform-specific">Can I get the bug
bounty reward if I discover a bug that occurs only on a particular
operating system?</dt>
<dd>
<p>Yes, if the operating system is officially supported by the most
recent version of the product for which you're reporting the bug. (For
a list of supported operating systems and hardware configurations see
the system requirements for <a href="{{ url('firefox.sysreq') }}">Firefox</a> or
<a href="{{ firefox_url('android', 'sysreq') }}">
Firefox for Android</a>)</p>
</dd>
<dt id="nondefault-pref">Can I get the bug bounty reward for a vulnerability
that is only triggerable with non-default preferences?</dt>
<dd>
<p>If the preference is exposed via our Preferences Page; we consider
that to be a supported configuration for Firefox. If the preference
is enabled by default in a current Firefox channel (e.g. Nightly or
Beta) it is also considered supported. If the preference must be
configured via about:config or requires other non-standard Operating
System configuration, that is typically not considered a supported
configuration. While we may rate these issues as sec-high for our own
purposes, they represent an exception to the standard bounty amounts
for these ratings, and typically will not receive a bounty or, at most,
a reduced bounty.</p>
</dd>
</dl>
<h2>Eligible bugs</h2>
<dl class="mzp-u-list-styled">
<dt id="eligible-bugs">What types of security bugs are eligible?</dt>
<dd>
<p>Reproducible security bugs that are determined to be rated
<a href="https://wiki.mozilla.org/Security_Severity_Ratings/Client">
sec-high</a> or above are eligible. In general we consider high
severity security bugs to be those that allow execution of arbitrary
code on users' systems or allow access to users' confidential
information. In the latter case we consider bugs to be sec-high only
if they potentially expose high-value personal information (e.g.,
passwords, credit card numbers, and the like); in the context of the
bug bounty program we do not consider bugs to be sec-high if they
potentially expose only lower-value information (e.g., browsing history)
or information that would be useful primarily for other exploits
(e.g., the names of files or directories on the user's system).</p>
<p>Finally, in general we do not consider bugs that permit only denial of
service attacks to be eligible in the sense described above.</p>
</dd>
<dt id="dos-bugs">Why won't you provide a reward for denial of service (DoS) bugs?</dt>
<dd>
<p>Because DoS bugs are generally less serious than other security
bugs (e.g., they typically do not lead to corruption or destruction of
user data, much less theft of data), and in many cases a DoS attack
does not involve an actual bug but simply misuse of standard product
features (e.g., putting up a web site with an excessive number of
graphics, sending excessively long mail messages, etc.). We have
decided to concentrate our limited resources on rewarding people who
find what we consider to be more serious security problems.</p>
</dd>
</dl>
<h2>Bug reporting, etc.</h2>
<dl class="mzp-u-list-styled">
<dt id="already-published">I've already published information about the bug,
and didn't go through the Mozilla bug process; can I still get a reward?</dt>
<dd>
<p>Depending on the manner in which it was published, and the details that
were disclosed, it may be possible; however typically we do not pay
bounties in situations where developers need to drop existing work to
respond to an urgent fix needed due to a public disclosure.</p>
<p>We encourage people to <a
href="https://bugzilla.mozilla.org/form.client.bounty">
report bugs directly</a> to the Mozilla project, in order to ensure that the
bug is made known as soon as possible to the people who can fix it.</p>
</dd>
<dt id="someone-elses-bug">Can I receive a bounty for a vulnerability I didn't
find?</dt>
<dd>
<p>Sometimes, yes. For example, if you find a Firefox exploit in the wild
that uses a previously unknown vulnerability and report it, you can be
eligible for a bounty for that vulnerability even though you didn't
discover the vulnerability itself.</p>
</dd>
<dt id="nondisclosure">If I report the bug
directly to you, do I have to keep the bug confidential and not publish
information about it in order to receive a reward?</dt>
<dd>
<p>No. We're rewarding you for finding a bug, not trying to buy
your silence. However if you report the bug through the standard
Mozilla process and haven't already published information about it then
we do ask that you follow the guidelines set forth in the official
policy on <a href="{{ url('mozorg.about.governance.policies.security.bugs') }}">handling
Mozilla security bugs</a>. Under this policy security-sensitive bug
reports in our Bugzilla system may be kept private for a limited period
of time to give us a chance to fix the bug before the bug is made
public, with an option for the bug reporter (or others) to open the bug
to public view earlier whenever circumstances warrant it (e.g., if your
bug report is being completely ignored).</p>
</dd>
<dt id="cooperation">I don't have the time or
desire to work with you further in investigating and fixing the bug;
can I still get a bug bounty reward?</dt>
<dd>
<p>Yes. Again, we're rewarding you for finding a vulnerability, not
trying to buy your cooperation. However we invite you to work together
with us to resolve the issue; and doing so can increase the reward that
is ultimately paid. You'll also get the opportunity to work as a full
member of the team fixing your bug and see "from the inside" exactly
how Mozilla security bugs get resolved.</p>
</dd>
</dl>
{% endblock %}

Просмотреть файл

@ -1,26 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Mozilla Security Bug Bounty Program Hall of Fame{% endblock %}
{% set body_id = "hall-of-fame" %}
{% block page_css %}
{{ super() }}
{{ css_bundle('security-bug-bounty-hall-of-fame') }}
{% endblock %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Firefox Bug Bounty Rewards</h1>
</header>
<p>On behalf of the Mozilla and the millions of people who visit our sites, use Firefox and our other products we would like to thank them for their hard work in helping to make us more secure.</p>
<p>As of this date, we have paid over <b>$4,000,000</b> across all of our bounties. Congratulations to everybody who has participated!</p>
{% include "security/partials/hall-of-famers-list.html" %}
<p>If your name is on the list incorrectly or you feel you should be on the list please feel free to mail us at <a href="mailto:security@mozilla.org">security@mozilla.org</a>.</p>
{% endblock %}

Просмотреть файл

@ -1,19 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Mozilla Web Application Security Bug Bounty FAQ{% endblock %}
{% set body_id = "web-eligible-sites" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Eligible Websites &amp; Services</h1>
</header>
<p>All eligible websites and services can be found in the scope tab of the <a href="https://hackerone.com/mozilla/policy_scopes">HackerOne Mozilla policy page</a>.</p>
{% endblock %}

Просмотреть файл

@ -1,27 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Mozilla Security Web and Services Bug Bounty Program Hall of Fame{% endblock %}
{% set body_id = "web-hall-of-fame" %}
{% block page_css %}
{{ super() }}
{{ css_bundle('security-bug-bounty-hall-of-fame') }}
{% endblock %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Web And Services Bug Bounty Hall of Fame</h1>
</header>
<p>On behalf of the Mozilla and the millions of people who visit our sites, use Firefox and our other products we would like to thank them for their hard work in helping to make us more secure.</p>
<p>As of this date, we have paid out over <b>$4,000,000</b> across all of our bounties. Congratulations to everybody who has participated!</p>
<p>If your name is on the list incorrectly or you feel you should be on the list please feel free to mail us at <a href="mailto:security@mozilla.org">security@mozilla.org</a>.</p>
<p><strong>Our Web bug bounty program has been migrated to HackerOne.</strong> Therefore, we will discontinue adding researchers on this page. Starting from May 2023, researchers will be recognized on our <a href="https://hackerone.com/mozilla/thanks">HackerOne Thanks</a> page.</p>
{% include "security/partials/hall-of-famers-list.html" %}
{% endblock %}

Просмотреть файл

@ -1,274 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Client Bug Bounty Program{% endblock %}
{% set body_id = "client-bug-bounty" %}
{% block page_css %}
{{ super() }}
{{ css_bundle('client-bug-bounty') }}
{% endblock %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Client Bug Bounty Program</h1>
</header>
<h2 id="intro">Introduction</h2>
<p>The Mozilla Client Security Bug Bounty Program is designed to encourage security research in Mozilla software and to reward those who help us create the safest Internet software in existence.</p>
<p><strong>Guidelines:</strong> In addition to our <a href="{{ url('security.bug-bounty') }}">general eligibility requirements</a>, submissions must be either an <a href="#static-analysis-bounty">static analysis submission</a>, <a href="#exploit-mitigation-bounty">exploit mitigation bypass</a> or a <a href="#security-vulnerability-bounty">security bug</a> demonstrating the ability to perform an unauthorized action or obtain access to otherwise-restricted information.</p>
<h2 id="security-vulnerability-bounty">Security Vulnerability Bounty</h2>
<p>Mozilla will pay a bounty for client security bugs as detailed below. All security bugs must follow the following general criteria to be eligible:</p>
<ul class="mzp-u-list-styled">
<li>Eligible security bugs may be present in any of the main development or released versions of Firefox, Firefox for Android, or Firefox for iOS as released by Mozilla Corporation (e.g. Nightly mozilla-central or Beta test versions, as well as the final release product versions). End-of-life products are not eligible for a security bug bounty and non-default configurations are <a href="{{ url('security.bug-bounty.faq') }}#nondefault-pref">only sometimes eligible</a>.</li>
<li>Submissions should be made following <a href="#claiming-a-bounty">our instructions below</a>.</li>
<li>We reserve the right not to pay bounties for security bugs in or caused by additional third party software (e.g. binary plugins, extensions) not bundled by Mozilla in a release.</li>
</ul>
<p>All bounties paid will be at the discretion of the Mozilla Bounty Committee. The committee will evaluate the severity of reported issues with the help of engineers who work on the affected code. Security researchers are invited to participate in the assignment of ratings, but final decisions on the rating are at the discretion of the Bounty Committee.</p>
<p>Typically, the security rating given by the Bounty Committee for a bug must be rated a "sec-high" or "sec-critical" in order for it to be eligible for a bounty. In some circumstances, bounties may be paid for lower-rated bugs as well. (See <a href="https://wiki.mozilla.org/Security_Severity_Ratings/Client">Security Ratings</a> for details of the rating qualifications.) </li>
<h4 id="security-vulnerability-amounts">Rewards Amount</h4>
<p>The bounty for valid potentially exploitable critical and high security rated client security vulnerabilities will be between $20,000 and $3,000 (USD) cash reward, depending on the impact of the vulnerability and the quality of the report, as detailed below.</p>
<p>The bounty program encourages the <u>earliest possible reporting</u> of potentially exploitable bugs. A bounty <u>is not determined based on the <i>initial</i> submission</u>, but rather on the outcome of the discussion with developers. Improving test cases post-submission, figuring out if an engineer's speculation is founded or not, or other assistance that helps resolve the issue <i>will</i> increase your bounty payout.</p>
<p><b>Baseline Report</b></p>
<ul class="mzp-u-list-styled">
<li>Sufficient information to diagnose the vulnerability and produce a fix. Examples:</li>
<ul class="mzp-u-list-styled">
<li>ASAN Stacktrace or Crash Dump (typically for Memory Trespassing/Corruption)</li>
<li>Trigger point (for UXSS)</li>
<li>ASAN Nightly bug reports</li>
</ul>
<li>Notes:</li>
<ul class="mzp-u-list-styled">
<li>Typically bounties are not paid for issues which cannot be identified/fixed from the report.</li>
<li>While we do adhere to a first reporter-rule (with a 72-hour collision window), exceptions are made for reports that are not actionable and require additional information provided by another party.</li>
</ul>
</ul>
<p><b>High Quality Report</b></p>
<ul class="mzp-u-list-styled">
<li>Includes at least two of the following:</li>
<ul class="mzp-u-list-styled">
<li>(for memory corruption) demonstrated control over the PC or memory read/write location, with documentation for how it is achieved</li>
<li>a root cause analysis of where the bug is located</li>
<li>a proof of concept that reproduces the vulnerability, easily integrated into our test suite</li>
</ul>
<li>Submissions that include some aspects of a high quality report will qualify for a bounty between the minimum and maximum.</li>
<li>Notes:</li>
<ul class="mzp-u-list-styled">
<li>A bug that is limited in capability may meet all the criteria for a High Quality report, but will merit a lower payout because of its limited capability. An example would be a sandbox escape that does not allow arbitrary code execution, but does allow arbitrary files to be read from the filesystem.</li>
<li>Developing a full exploit is not required for a High Quality Report.</li>
<li>The intent of the proof of concept is to enable us to create a test that we can integrate into our test coverage. We encourage you to submit the bug immediately, and if you wish to meet this criteria, ask what will qualify. For assertion/crash-based tests it is usually sufficient to provide a minimal reproducing html or js file. For more complicated bugs, we would ask you to develop the POC into an actual test (e.g. gtest, xpcshell, mochitest) which we can provide some mentorship for.</li>
</ul>
</ul>
<table class="mzp-u-data-table">
<thead>
<tr>
<th></th>
<th>High Quality Report</th>
<th>Baseline</th>
</tr>
</thead>
<tbody>
<!-- ========================================================= -->
<tr>
<td>Highest Impact
</td>
<td>$20,000</td>
<td>$18,000</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled multiple-item-list">
<li>Sandbox Escape<sup>0</sup></li>
</ul>
</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled">
<li>Bypassing WebExtension install prompts<sup>1</sup></li>
</ul>
</td>
</tr>
<!-- ========================================================= -->
<tr>
<td>Higher Impact</td>
<td>$10,000</td>
<td>$8,000</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled">
<li>UXSS<sup>2</sup></li>
</ul>
</td>
</tr>
<!-- ========================================================= -->
<tr>
<td>High Impact - Vulnerabilities not fitting 'Higher' or 'Highest Impact', but still receiving a <a href="https://wiki.mozilla.org/Security_Severity_Ratings/Client">sec-high rating</a>
</td>
<td>$5,000</td>
<td>$3,000</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled">
<li>sec-high rated address bar spoofs</li>
</ul>
</td>
<td class="two-col-cell" colspan="2">
<span>Typically $3000</span>
</td>
</tr>
<!-- ========================================================= -->
<tr>
<td>Moderate Impact, at the discretion of the committee
</td>
<td class="two-col-cell first-of-section" colspan="2">
<span>$2,500 - $500</span>
</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled multiple-item-list">
<li>sec-moderate rated address bar spoofs</li>
</ul>
</td>
<td class="two-col-cell" colspan="2">
<span>$2,000 - $500</span>
</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled multiple-item-list">
<li>Memory Corruption triggered by an OOM condition<sup>3</sup></li>
</ul>
</td>
<td class="two-col-cell" colspan="2">
<span>Typically $1,500</span>
</td>
</tr>
<tr>
<td>
<ul class="mzp-u-list-styled">
<li>Persistent-DOS of browser across restarts or a DOS requiring reboot of users computer<sup>4</sup></li>
</ul>
</td>
<td class="two-col-cell" colspan="2">
<span>Typically $1,000</span>
</td>
</tr>
</tbody>
</table>
<p><sup>0</sup>A sandbox escape is defined as a method to run arbitrary attacker code with full user privileges in the parent process or natively on the user's computer. This can be achieved either through memory corruption or Javascript-based vulnerabilities. Vulnerabilities that assume arbitrary code execution in the content process - such as invoking an IPC method with attacker-controlled parameters - do qualify for Highest Impact.</p>
<p><sup>1</sup> For Highest Impact, bypassing WebExtension Install Prompts excludes local attacks.</p>
<p><sup>2</sup>UXSS is defined as the ability to execute JavaScript in an arbitrary cross-origin context. As mentioned above, complex user interaction or limited capabilities of the vulnerability (such as only being able to inject into a cross-origin domain, but not an arbitrary cross-origin domain) may decrease the bounty award.</p>
<p><sup>3</sup> If precise control of the OOM condition can be demonstrated, this will be considered High Impact.</p>
<p><sup>4</sup> Denial of Service issues that merely crash the browser are not eligible for a bounty.</p>
<h2 id="exploit-mitigation-bounty">Exploit Mitigation Bug Bounty</h2>
<p>Within Firefox, we have introduced vital security features, exploit mitigations, and defense in depth measures. If you are able to bypass one of these measures, even if you are operating from privileged access within the browser, you are eligible for a bounty.</p>
<p>Privileged access means bypassing the mitigation in a testing scenario; such as <a href="https://blog.mozilla.org/security/2019/12/02/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs/">directly testing the HTML Sanitizer</a>. However do note that as explained above in footnote <sup>1</sup>, direct calls to an IPC method from a compromised content process is an expected attack vector and not considered a testing scenario; these are eligible for a Highest Impact bounty as well as the Bounty Bonus described below.</p>
<p>The mitigations we consider in scope for this bounty are:</p>
<ul class="mzp-u-list-styled">
<li>We compile <a href="https://searchfox.org/mozilla-central/source/toolkit/moz.configure#2108-2113">certain libraries</a><sup>5</sup> from C/C++ to wasm, isolating them in a memory-safe sandbox. To bypass the mitigation, you are allowed to introduce a memory corruption flaw into the library; after which point you would need to exploit the flaw to either achieve arbitrary code execution within the content process (or convince us it is possible via e.g. RIP control) <em>or</em> manipulate the library to provide output crossing the taint boundary (<a href="https://searchfox.org/mozilla-central/rev/2c991232499e826e46f9d976eb653817340ba389/third_party/rlbox/include/rlbox.hpp#63-78">example</a>) which causes Firefox to make an incorrect security-relevant decision.</li>
<li>We separate strings and ArrayBuffers into separate memory arenas from DOM Nodes. A bypass would be arbitrary control of memory layout in the same <a href="https://searchfox.org/mozilla-central/rev/31d8600b73dc85b4cdbabf45ac3f1a9c11700d8e/memory/build/malloc_decls.h#108">jemalloc arena</a> as DOM nodes (i.e. full vtable overlayment). </li>
<li>We <a href="https://blog.mozilla.org/attack-and-defense/2019/09/29/remote-code-execution-in-firefox-beyond-memory-corruptions/">sanitize HTML fragments before using them in privileged contexts</a>. A bypass would be (i) finding a location we should be sanitizing (because it has attacker-controlled data) but arent or (ii) bypassing the HTML sanitizer with something that could execute JS<sup>3</sup> in Firefox.</li>
<li>We disallow eval() from being used in the System Principal context or the Parent Process. A bypass would be identifying a location where we still use eval that <a href="https://searchfox.org/mozilla-release/rev/42c9e6b219d64360e005268ed1471d7d603b8fa8/dom/security/nsContentSecurityUtils.cpp#279">isnt explicitly being allowed</a><sup>4</sup>, or how to abuse a location that is allowed.</li>
<li>We apply a strong Content Security Policy to all internal about: pages, e.g. <a href="https://searchfox.org/mozilla-central/rev/7ec7ee4a9bde171ba195ab46ed6077e4baaef34d/toolkit/mozapps/extensions/content/aboutaddons.html#11">about:addons</a> (and <a href="https://searchfox.org/mozilla-central/rev/31d8600b73dc85b4cdbabf45ac3f1a9c11700d8e/dom/security/nsContentSecurityUtils.cpp#797">double-check we don't forget</a>). A bypass would be identifying a way to run scripts or inject meaningful content bypassing the CSP of any about: page, excluding already-filed issues.</li>
<li>We prevent anything except chrome://, resource:// and about: pages <a href="https://searchfox.org/mozilla-central/rev/31d8600b73dc85b4cdbabf45ac3f1a9c11700d8e/docshell/base/nsDocShell.cpp#8862-8905">from loading in the parent process</a>. A bypass would be showing a way an attacker-controlled page could be loaded, either by bypassing the checks in that function, or <a href="https://searchfox.org/mozilla-central/search?q=symbol:_ZN10nsDocShell22CanLoadInParentProcessEP6nsIURI&redirect=false">finding a place it is not correctly checked</a>. We have an analogous check for <a href="https://searchfox.org/mozilla-central/rev/31d8600b73dc85b4cdbabf45ac3f1a9c11700d8e/dom/security/nsContentSecurityManager.cpp#763">preventing loads in the System Principal Context</a> as well. (Note that Fission has recently caused refactoring to this function, but this mitigation is still in-scope with Fission disabled or enabled with (only) the fission.autostart pref.)</li>
<li>We do not allow attacker-controlled JavaScript to run in the Parent Process - whether delivered from the internet or provided from a compromised content process. A bypass would be finding a way to execute javascript of your control in the parent process through any mechanism except PAC scripts.</li>
<li>In Bugs <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1479960">1479960</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1550900">1550900</a>, and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1550037">1550037</a> we added support for sharing memory from the parent to child processes where the child process cannot modify the memory, but the parent can. A bypass would be finding a way to modify the memory from the child process.</li>
<li>The Firefox UI is written in HTML/JavaScript, which means Firefox runs certain scripts with elevated privileges beyond what is ordinarily available to web content. To prevent privilege escalation attacks, Gecko implements a capability-based <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Gecko/Script_security">script security architecture</a> (primarily implemented <a href="https://searchfox.org/mozilla-central/source/js/xpconnect/wrappers">in js/xpconnect/wrappers</a>), including special Xray Wrappers which prevent lesser-privileged JavaScript from confusing higher-privileged or differently-privileged Javascript when scripts interact across privilege boundaries. A bypass would be identifying a plausible exploitation scenario that occurs due to missing or incomplete sanitizing across compartments. A scenario is more likely to be considered “plausible” if it was the source of a past bug or is a code pattern we do elsewhere in-tree (the dependencies of bug <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=929539">929539</a> show some examples which we previously worked to eliminate).</li>
<li>We have a <a href="https://searchfox.org/mozilla-central/search?q=ReadOnlyPage&path=">ReadOnlyPage</a> <a href="https://searchfox.org/mozilla-central/rev/3fa5cc437a4937c621ea068ba5dc246f75831633/js/xpconnect/src/nsXPConnect.cpp#1018">implementation</a> which is intended to prevent Data-Only attacks. A bypass would be reliably exploiting a race condition when the memory region is unprotected, finding a bug such that the memory region is left unprotected, or identifying a way around the mitigation to effect a data-only attack on the protected values.</li>
</ul>
<p><sup>3</sup> Some styles are currently allowed by the sanitizer, but limited by the CSP to only allow chrome:// styles, which are part of the build. We will look at style-related issues on a case-by-case basis. We explicitly discourage researchers from re-styling a page for clickjacking attacks because we have a very high bar for an attack.</p>
<p><sup>4</sup> An example of such a bypass was identifying that <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1583949">we forgot to perform the checks on workers</a>.</p>
<p><sup>5</sup> The selected lines may move, but we intended to link to the function <tt>wasm_sandboxing_libraries()</tt> which defines which libraries are wasmboxed.</p>
<p>Notes:</p>
<ul class="mzp-u-list-styled">
<li>Bypasses that involve obtaining a mis-issued Certificate Authority certificate will be decided on a case-by-case basis, but bypasses involving administrator-installed root certificates or CA-pinned connections will be ineligible.</li>
<li>We believe all mitigations are present in the new Firefox Android app (previously Firefox for Android Preview - its the one with the URL bar at the bottom); therefore, that application is in-scope if the mitigation is present: the absence of a mitigation is something we would appreciate knowing about but may not be eligible on a bounty - it will be decided on a case-by-case basis. Our older Firefox for Android application (internal name “Fennec”) is excluded from this bounty.</li>
<li>Other things may be considered a mitigation as well, but before assuming they would be, please confirm with us in #security or at <a href="mailto:security@mozilla.org">security@mozilla.org</a></li>
</ul>
<p><strong>Bounty</strong>: Assuming the mitigation is bypassed in a testing scenario, with privileged access, we will treat a bypass of the above listed mitigations as High Impact using the table above, with the same payout range for baseline to high quality report.</p>
<p><strong>Bounty Bonus</strong>: If the mitigation is bypassed without privileged access, this would count as both a regular security vulnerability eligible for a bounty and a mitigation bypass. The vulnerability payout will be decided per the criteria and table above and the mitigation bypass adds a bonus of an additional 50% of the baseline payout for the category. e.g. a UXSS vulnerability that bypasses our HTML sanitization would earn $18K - $20K plus an additional $9000.</p>
<p><em>Note</em>: If youre in the Bounty Bonus category, you may think submitting them separately could earn you slightly more money than submitting them together. Were pretty sure that doing so would make the second report bounty-ineligible, but if you think each issue is fully independent, youre welcome to submit them separately and well consider it.</p>
<h2 id="static-analysis-bounty">Static Analysis Bounty</h2>
<p>We also have a program that rewards the submission of static analysis tools that identify present or historical security vulnerabilities in Firefox. We will accept static analysis queries <a href="https://firefox-source-docs.mozilla.org/code-quality/static-analysis/writing-new/index.html">written as clang-based checkers</a> - we have some documentation that <a href="https://firefox-source-docs.mozilla.org/code-quality/static-analysis/writing-new/index.html">may help you get started or integrate and run over Firefox as a whole</a>. Submissions should be made following <a href="#claiming-a-bounty">our instructions below</a>.</p>
<p>We will issue a bounty for the query itself, dependent upon the quality of the submission. Because this is an experiment, we are not committing to an exact amount or range for the bounty, but we expect this will typically be in the $2500-$7500 range.</p>
<p>Additionally, if your query matches presently unknown security vulnerabilities, each vulnerability it matches will be considered for a bounty independently. The amount awarded is dependent on the submission quality, as per normal bounty policy. For example purposes, well assume a high or critical vulnerability (which is the most common case for memory corruption.) A report that only shows the output of the tool would be at the minimum end ($3000), and may be less if you submit multiple false positives we need to spend time validating. However a report that includes documentation explaining and validating that the issue is in fact a vulnerability would be eligible for an increased payout. A submission that includes documentation and a test case (which we acknowledge may be difficult for bugs found via this method) would be eligible for the maximum end ($5000).</p>
<p>The quality of the static analysis submission will be judged on:</p>
<ul class="mzp-u-list-styled">
<li>Complexity of the query. Is the query identifying a simplistic or syntactical issue with tight locality? Or is it identifying a semantic problem across complicated data flows?</li>
<li>Documentation of the query. How does it work, and how did you develop it. What things did you try that didnt work, and how did you refine it. Crucially: when trying to find the bad pattern, what edge cases does your query miss?</li>
<li>Test vectors. Can you supply simple C++ programs that illustrate the vulnerable code patterns that the query matches. Can you supply programs that are edge cases the query misses?
<ul class="mzp-u-list-styled">
<li>While it may seem unusual to highlight shortcomings of your submission, from our perspective this makes the submission stronger - it gives us confidence you tested it in multiple scenarios, and shows us how we may be able to improve it.</li>
</ul></li>
<li>What Firefox issues does it identify, either currently unknown, or previously known and fixed? This is your opportunity to argue the usefulness of your query: were not going to run your query on historical versions of the codebase, so you should and demonstrate the bugs the query identifies. The more you can identify, the stronger your case is. As a rule of thumb, a query that identifies less than three distinct issues will need an exceptionally strong argument for its future usefulness.</li>
<li>The false positive rate of the query. As a rule of thumb, a query should have fewer false positives than true positives. Which means if it matches 1 valid historical issue and 3 current, false positives - you should seek to identify additional historical issues it matches or refine the query.</li>
<li>Uniqueness of the query. If we receive multiple query submissions that do the same thing, we will consider the first reported. This is similar to our existing policy that the issue must be previously unreported. However, if your submission improves upon a prior submitted query, we will consider a (smaller) bounty for your improvement upon the prior query.</li>
</ul>
<p><b>More about "Complexity of the query":</b> Consider a function that returns -1 for error, 0 for failure, and 1 for success. Miscasting this return value into a boolean is a common mistake, and we surely have some historical instances of this in our code base. If you identify a function that still has this (bad) API, such a simplistic syntactical query is still valuable to us. If the API is ours, we should fix the API and if the API isnt ours, we should use static analysis to prevent such a flaw from occurring. But its not a very sophisticated query. On the flip side, a query that does data flow analysis between a user-controlled source and attacker-controlled sink, accounting for complex transitions along the way (like IPC or JS/C++ boundaries) - that is a very sophisticated query.</p>
<p><b>Examples of Quality of Submission:</b> As mentioned, the bounty amount we grant for the query will be determined based on the quality of the submission, and an estimation of the number of issues we think it may identify in a one to three-year timespan. On the low end, if you submit a query that identifies a single historical issue of a syntactical misuse of an API we are unlikely to use in future code, we may not issue a bounty, and if we did it would be below the $2500 range. And on the high end, if you submit a query that matches 3 unknown issues today, in code written in the last year - we can expect it will identify a significant number of issues in the future and would be looking above the $7500 range. (Plus youd be eligible for separate bounties on those 3 issues.)</p>
<p><em>Note</em>: While we previously accepted submissions of CodeQL queries, we no longer do. You are of course encouraged to develop CodeQL queries if you think they will be valuable, and submit any findings you glean from them.</p>
<h2 id="claiming-a-bounty">Claiming a Bug Bounty</h2>
<p>To claim a bounty:</p>
<ul class="mzp-u-list-styled">
<li>Make sure you have a Bugzilla account.</li>
<li>Use the <a href="https://bugzilla.mozilla.org/form.client.bounty">bugzilla client bug bounty form</a> to file the issue and automatically mark it for bug bounty consideration.</li>
<li>In the "Description" field, please clearly describe one security issue or static analysis submission. Please do not include extremely verbose output in the description field, and instead attach it as described below.</li>
<li>If you have multiple bugs to file (for example, multiple findings from a single tool), file each one via this form individually, and we will link them as appropriate during review.</li>
<li>If submitting a static analysis submission, use the "Attachment" option to attach the source code of the query or plugin.</li>
<li>Attach any supporting documents, such as "proofs of concept", reproduction cases, debug output or output from a tool. Again, use the "Attachment" option. While not required, such supporting documents will improve the quality of the submission and help us judge it more quickly and accurately. If you have multiple files to attach, it is better to attach one, submit the form, and then attach the remainder to the newly-created bug rather than attaching a zip file. (The exception is for a bundle of related files, like several log files, or test vector programs.)</li>
<li>If you have filed the bug directly in Bugzilla without using the <a href="https://bugzilla.mozilla.org/form.client.bounty">Bugzilla client bug bounty form</a>, please immediately notify the Mozilla Security Group by email to <a href="mailto:security@mozilla.org">security@mozilla.org</a> and include the number of the bug you filed and a mention that you are submitting it for bounty consideration. <strong>Do not send the actual vulnerability via email.</strong></li>
</ul>
<p>We ask that you be available to follow along and provide further information on the bug as needed, and invite you to work together with Mozilla engineers in reproducing, diagnosing, and fixing the bug. As part of this process we will provide you full access to participate in our internal discussions about the bug; for more information read our policy for handling security bugs.</p>
{% endblock %}

Просмотреть файл

@ -1,198 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title_suffix %}{% endblock %}
{% block page_title %}Mozilla Security{% endblock %}
{% set body_id = "security-index" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Mozilla Security</h1>
</header>
<p class="intro">Whether youre using the Web or checking your email, you care about your security and privacy. At Mozilla we understand the importance of security. Here you will find alerts and announcements on security and privacy issues, general tips for surfing the Web and using email more securely, more information about how we maintain and enhance the security of our products, and useful links for developers.</p>
<ul class="links">
<li>
<h4><a href="{{ url('security.advisories') }}">
Mozilla Security Advisories
</a></h4>
for all products
</li>
<li>
<h4><a href="{{ url('security.known-vulnerabilities') }}">
Known vulnerabilities
</a></h4>
listed by product
</li>
<li>
<h4><a href="{{ url('security.bug-bounty') }}">
Security Bug Bounty Program
</a></h4>
Mozilla's Security Bug Bounty Program for security issues
</li>
<li>
<h4>
<a href="https://blog.mozilla.org/">The Mozilla Blog
</a></h4>
announces all of our releases
</li>
<li>
<h4><a href="https://blog.mozilla.org/security/">
The Mozilla Security Blog
</a></h4>
features security-related articles about Mozilla products.
</li>
</ul>
<section id="updates">
<p>The latest security updates will be delivered to most users
automatically. Users who have turned off automatic updates can use the
"Check for Updates..." item on the Help menu. If the menu item is disabled
your account does not have sufficient privileges to update Firefox--contact
the person who installed Firefox on your machine. Additional help is also
available through our <a href="https://support.mozilla.org/">Community
Support</a> site.</p>
</section>
<section id="browsing">
<h2 id="Tips_for_secure_browsing">Tips for Secure Browsing</h2>
<ul class="mzp-u-list-styled">
<li>Always use the most current version of your
<a href="/firefox/">browser</a>.
</li>
<li>Check for the "lock" icon on the status bar that shows that you
are on a secured web site. Also check that the URL begins with
"https" in the location bar when making transactions online.
</li>
<li>In the Tools menu of Firefox, Tools &gt; Options... &gt; Privacy,
you can clear your information with one click of a button. This
is especially useful when using a computer in a public location.
</li>
<li>Perform transactions (like shopping or submitting personal
information) at sites that are well established and that are familiar
to you. If you're not familiar with a site, make sure that the
site has a privacy policy and information about the site's security
measures.
</li>
</ul>
</section>
<section id="email">
<h2 id="Tips_for_using_email_securely">Tips for Using Email Securely</h2>
<ul class="mzp-u-list-styled">
<li>Be aware that it is extremely easy for someone to forge an email
message to make it appear as if the message has been sent by your bank,
a software vendor (e.g., Microsoft), or another entity with whom you do
business. If a message requests that you send your password or other
private information, or asks that you run or install an attached file,
then it is very likely that the message is not legitimate. When in
doubt, just mark the message as "junk" and delete it.
</li>
<li>Be cautious when clicking on links sent to you in email messages.
If you do click on such a link, double-check the name of the site as
shown in the location bar of the browser, and be especially careful if
the site name displayed is an IP address (e.g., "192.168.25.75")
instead of a domain name (e.g., "www.example.com"); in the former case
it is very likely the site is not legitimate. Don't enter any personal
information into forms displayed at such a site, and if you have any
concerns whatsoever about your security, just close the browser window.
</li>
</ul>
</section>
<section id="developers">
<h2 id="For_Developers">For Developers: Contacting Mozilla</h2>
<p>Report security-related bugs and learn more about how we secure our
products:</p>
<ul class="mzp-u-list-styled">
<li><strong>If you believe that you've found a Mozilla-related
security vulnerability, please report it by sending email to the
address <a href="mailto:security@mozilla.org">security@mozilla.org</a>.</strong> Note that your report may be
eligible for a reward; see below.
</li>
<li>For more information on how to report security vulnerabilities
and how the Mozilla community will respond to such reports, see our
<a href="{{ url('mozorg.about.governance.policies.security.bugs') }}">policy
for handling security bugs</a>.
</li>
<li>We want to make Mozilla products and sites as secure as possible, and wish to encourage research, study, timely disclosure, and rapid fixing of any serious security vulnerabilities. We've established a <a href="{{ url('security.bug-bounty') }}">Security Bug Bounty Program</a> to reward people who help us reach that objective.
</li>
<li>Mozilla-based products include a default list of CA certificates
used when connecting to SSL-enabled servers and in other contexts. If you
are a CA and would like your CA certificate(s) considered for inclusion
in Mozilla, please see the <a href="{{ url('mozorg.about.governance.policies.security.certs.policy') }}">
Mozilla CA certificate policy</a>.
</li>
</ul>
</section>
<p>Press Contact: send mail to <em>press</em> at <em>mozilla dot com</em>.</p>
<p id="pgpkey">The PGP key for <a href="mailto:security@mozilla.org">security@mozilla.org</a> below can be used to send encrypted mail or to verify responses received from that address.</p>
<div class="pgp-key">
<pre>
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGcpoSsBEADB5DcvUh0Q7tC0AGWm1pFRY989pHq3whbV+svnx1oYMj5vnBYm
+4nxthXrBbOOQTTfCj09gMdyAT1z/+9s+HJB1vU4xsndXYHLTJ1e6VfE+uwgMe/v
fW7BLleCdeaZdsvtjZqYcARr9oa5hJwxIypFEWzkgYFFczdh0LMG4lobsCOjXfsm
kUzQRh58eqwPTM3ZEo23gzVfQBhqRVvNrfYvtXoDRsUmOSseLN2DJRYLOW1zbpuf
KqK9nc/e/tkvyecXBpP+BkLf9AZ+pD23n5pS/YXVIfi2+G0dNS/UMU9PdoSuIN1v
0SRTrWQCHqAnsmf11D1CoWHEG2l7cV4a5xksNyK3GjPVcf+vvB3sV/cKgbv9XB8C
EV50JLrU85wpbpxIJGuu5Ho82lNqjiuEjwNsqVFwiIJUYaLSVkyFT/JO1TfXSDQw
mEBK2MIhd7ORlDU7X2K4mOtggyzNdRz60ini3b6u0kZ3a/aW9yHDBYufPL1HAJpX
L0zjD/n8ozOTunQuxuWtBN2J2v8KJeBVjgHiWMC1c5JcBekx6z7no6bkeZwR6Mug
2JNcZhtuYrqUxtegnUpM7tcfRhKHsgn5sJ8ci7PsYl43KE1gPD+tJ7ag07aahvN5
q/wEAbukRWK6NpAOaKzZQLynkaUzzns3KbNeIogm/x8MDevCh60BoJnXSwARAQAB
tCdNb3ppbGxhIFNlY3VyaXR5IDxzZWN1cml0eUBtb3ppbGxhLm9yZz6JAlQEEwEK
AD4WIQSt77LiRX23NxoDE0unzZnaZOne1wUCZymhKwIbAwUJBaOagAULCQgHAwUV
CgkICwUWAgMBAAIeAQIXgAAKCRCnzZnaZOne1xKKD/47wsc6e/20cYAuy8M0LKn6
fCT05+OJVVanznzRc0C//H9FWJYsxydPoABLrSZlawnSbAsAvsYLprKNbSMzKC6q
GuhO4AYS2sF3kVY27xI14wua4+BkzYaSv8Kozkbz6sJPINo93P+Qr5KmPav5eJ6Y
ZaXmfr9Xqp1b8d2KyTaNRChZ0ge+BLfmAMagskONCRS5swf6/1Mbn6FWpZLMoUtp
/N9eJLDJapocpZ1FlCn7R5Q0jWsJfv80uxuCCMwtwQZrBagh+yU9gwcYexp6aQep
lhtSQJrpebzxXaXKJBgTLML9rHJBez1O/Fs/JUmrdKZz35CCCB9hDVd9Xg9/qePZ
EsOA9NXgW5LRbCVq7Euz6E8HVe1EsdtBaLxcdwkPbm0UgI0QjvPJJgbTKzeCNbBi
EOrrJ283S+1UfAfmdWvW5hTTFvI7r5CIC3CD2XS7MOBgmyeKBlJNAcCJTMrCEGTb
p0XwDfufJE2eMKfXyolNmM836UwS1yNUY6t9BKZPFNJaLljgvUIKngIOwnITFqIo
55YGMrCCFyR9QYH2B6MSSno+d8OCrClvLqRIt4LKzfdW3VRHD03X5kQAnX8z3TDj
vy20ZlRhzZxzHBdgX67H5VxaNh+z8inCmUfaACyRwWn0dzJRkBhZTcjMJZAxQLTu
C0mYP8bqAtnWxV3OTXF99rkCDQRnKaErARAAvZyoXDRdfFqUcc4WLtMBccwIrLxU
JFoTwE+LgzWrZt7d+oXQogufSGPJ2Zqpml989PoX6DSti7M3EiZXkwNF3XLuXMdv
PwyDpkvRjhUhra1D9DOrorH55Q7gouaJnBxWpW49gEatQWYJPjAIgyjAlQrn54Lb
1weNRBCDNvX5BpsQP9C8qcSA1oHq4u36ogDNfq6Zfm/6dSOOqPf+AN/gp+WwydfD
Bq4lUGvWJj1k/Q+XbSVfo5Jb8lOvhsTd+2xVDcXoQt6KmkBLGVqNNcaodqFtyww8
kdHe3aa45tTfQt+g6KqfYLq93e+frvnMMEGJ6dm4dHOsxLNau11tH+o52qjkmW7J
T5V6rpVHaAUnhh3BIb6pPjHOV2r9V4qw/J+WI9sEWegHfi0CmB/a7qi4ZEmdPuvB
yvTJ+4rlbfTaLRnb089FetYp/IzgvAf3zoICxE9doigDLrDwtqgvjogtogV+4rE0
GUB/mVzT+ev6r1uXySNkqnuZ3zyPlu29JoBcb2ELjVxe5lXmIyvPG8d1Aldxc49N
VNdZ/r9D9J5bfDRTPc+yZ3XQeomcTwcbNGYn0oHH0bnH05PwSu2XS14RIOG5PHYc
bPAT3MyzpNYAB3uSiKkuekVM152oKTPgTa5PqFoqT6g4LqPkkLq+GAZSyl6lS8L7
X+X4T9CpNugf+gcAEQEAAYkCPAQYAQoAJhYhBK3vsuJFfbc3GgMTS6fNmdpk6d7X
BQJnKaErAhsMBQkFo5qAAAoJEKfNmdpk6d7XWSUP/1zdDiW/2/UI8hns+gDri3mh
hNjT0EqFQ/VwzN8n05/uuxba09xjo2f0cqIwUHQZ2boeAkYKWyGtPV8sYGrfIT1U
A6ev3S0fX0ARFXDGgLLBPwmfkbu+1U/ALmLW87Zok598TWvxXL3KFkuyjjjwHozE
zmecNkvkTfn3h86VHSlIDewZ8U4z29gvJeDDe8z4jDZWwth+VyvIzk8jVxKqggvT
7g7WajBRl62jL0pxHzFmCuyChZ0MmfQUJoecj3Res0WDYMP7lL2xjtSRT+zsmGIU
N6xB4bDJ38FuUBuL1RF0zsguOKMHQvatVlYvPjfWL6gNSuZhA7bgtEVzrflq2yKw
EYYL9UgDZI/QOSunUQo5OgoAww8i8sarHX/O33EDdbWN8R+VUTU7i/iOeZySx2Tg
JvnzGh72NeOmFjRmvm9SiLhIBie4JQAr0JoqLElLoHt5ZnShuOcY/jRJ6oFsxzPm
EmBAULvvbz1qJ2WSy/Mm/iEB9Eu7PxTihSpujYH0zMyud7DVwoF3sQ4bLavvnsU4
+mefGMDxS2xSxj54IeKyGSOyS5M/+b3Jzt3fkgPQ3MP7jiZcxDrjF614ldmycX/A
LRKEYUWtFnbKzNhT6kPXVZwtuFp7j65pteUoK3XDrfR8zPFS91lulCA+zPSyjs4X
q/jdznvsSsbmsw+exOBt
=NDRA
-----END PGP PUBLIC KEY BLOCK-----
</pre>
</div>
{% endblock %}

Просмотреть файл

@ -1,80 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Known Vulnerabilities in Mozilla Products{% endblock %}
{% set body_id = "known-vulnerabilities" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Known Vulnerabilities in Mozilla Products</h1>
</header>
<p>The links below list security vulnerabilities known to affect
particular versions of Mozilla products and instructions on what users
can do to protect themselves. The lists will be added to when new security
problems are found. For a complete list not sorted by product or version
please see the <a href="{{ url('security.advisories') }}">
Mozilla Foundation Security Advisories</a>.</p>
<p>Please read
<a href="{{ url('mozorg.about.governance.policies.security.bugs') }}">
Mozilla.org's security bug policy</a> for information on how we handle
security bugs. If you have found a security problem which is not on this
list and has not already been filed as a bug in
<a href="https://bugzilla.mozilla.org/query.cgi">Bugzilla</a>,
or if you find errors or inconsistencies in this list, please
<a href="mailto:security@mozilla.org">mail us</a>.
If needed our PGP key can be found on the main
<a href="{{ url('security.index') }}#pgpkey">security</a> page.</p>
<h2>Product Advisories</h2>
<ul class="mzp-u-list-styled">
<li><a href="{{ url('security.product-advisories', slug='firefox') }}">Firefox</a></li>
<li><a href="{{ url('security.product-advisories', slug='firefox-esr') }}">Firefox ESR</a></li>
<li><a href="{{ url('security.product-advisories', slug='firefox-for-ios') }}">Firefox for iOS</a></li>
<li><a href="{{ url('security.product-advisories', slug='firefox-os') }}">Firefox OS</a></li>
<li><a href="{{ url('security.product-advisories', slug='mozilla-vpn') }}">Mozilla VPN</a></li>
<li><a href="{{ url('security.product-advisories', slug='thunderbird') }}">Thunderbird</a></li>
<li><a href="{{ url('security.product-advisories', slug='thunderbird-esr') }}">Thunderbird ESR</a></li>
<li><a href="{{ url('security.product-advisories', slug='seamonkey') }}">SeaMonkey</a></li>
</ul>
<h2>Advisories for older products</h2>
<h3>Firefox</h3>
<ul class="mzp-u-list-styled">
<li><a href="{{ url('security.product-version-advisories', product='firefox', version='3.6') }}">Firefox 3.6</a></li>
<li><a href="{{ url('security.product-version-advisories', product='firefox', version='3.5') }}">Firefox 3.5</a></li>
<li><a href="{{ url('security.product-version-advisories', product='firefox', version='3.0') }}">Firefox 3.0</a></li>
<li><a href="{{ url('security.product-version-advisories', product='firefox', version='2.0') }}">Firefox 2.0</a></li>
<li><a href="{{ url('security.product-version-advisories', product='firefox', version='1.5') }}">Firefox 1.5</a></li>
<li><a href="{{ url('security.product-version-advisories', product='firefox', version='1.0') }}">Firefox 1.0</a></li>
</ul>
<h3>Thunderbird</h3>
<ul class="mzp-u-list-styled">
<li><a href="{{ url('security.product-version-advisories', product='thunderbird', version='3.1') }}">Thunderbird 3.1</a></li>
<li><a href="{{ url('security.product-version-advisories', product='thunderbird', version='3.0') }}">Thunderbird 3.0</a></li>
<li><a href="{{ url('security.product-version-advisories', product='thunderbird', version='2.0') }}">Thunderbird 2.0</a></li>
<li><a href="{{ url('security.product-version-advisories', product='thunderbird', version='1.5') }}">Thunderbird 1.5</a></li>
<li><a href="{{ url('security.product-version-advisories', product='thunderbird', version='1.0') }}">Thunderbird 1.0</a></li>
</ul>
<h3>SeaMonkey</h3>
<ul class="mzp-u-list-styled">
<li><a href="{{ url('security.product-version-advisories', product='seamonkey', version='2.0') }}">SeaMonkey 2.0</a></li>
<li><a href="{{ url('security.product-version-advisories', product='seamonkey', version='1.1') }}">SeaMonkey 1.1</a></li>
<li><a href="{{ url('security.product-version-advisories', product='seamonkey', version='1.0') }}">SeaMonkey 1.0</a></li>
</ul>
<h3>Older</h3>
<ul class="mzp-u-list-styled">
<li><a href="{{ url('security.product-advisories', slug='mozilla-suite') }}">Mozilla Suite 1.7</a></li>
<li><a href="{{ url('security.older-vulnerabilities') }}">Older vulnerabilities</a></li>
</ul>
{% endblock %}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,27 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
<section class="cve">
<h4 id="{{ id }}" class="level-heading">
<a href="#{{ id }}"><span class="anchor">#</span>{{ id }}: {{ title }}</a>
</h4>
<dl class="summary">
<dt>Reporter</dt>
<dd>{{ reporter|safe }}</dd>
<dt>Impact</dt>
<dd><span class="level {{ impact_class }}">{{ impact }}</span></dd>
</dl>
<h5>Description</h5>
{{ description|markdown }}
{% if bugs %}
<h5>References</h5>
<ul>
{% for bug in bugs -%}
<li><a href="{{ bug.url }}">{{ bug.desc|safe }}</a></li>
{%- endfor %}
</ul>
{% endif %}
</section>

Просмотреть файл

@ -1,29 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
<div>
{% for person in hofers %}
{% if loop.changed(person.date.year) %}
<details id="year-{{ person.date.year }}">
<summary><h3 data-accordion-role="tab">{{ person.date.year }}</h3></summary>
{% endif %}
{% if not loop.previtem or loop.previtem.quarter_string != person.quarter_string %}
<h4>{{ person.quarter_string }}</h4>
<ul class="mzp-u-list-styled">
{% endif %}
{% if person.url -%}
<li><a href="{{ person.url }}" rel="nofollow">{{ person.name }}</a></li>
{% else -%}
<li>{{ person.name }}</li>
{% endif %}
{% if not loop.nextitem or loop.nextitem.quarter_string != person.quarter_string %}
</ul>
{% endif %}
{% if not loop.nextitem or loop.nextitem.date.year != person.date.year %}
</details>
{% endif %}
{% endfor %}
</div>

Просмотреть файл

@ -1,29 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
<h3>Impact key</h3>
<ul>
<li class="level-item"><span class="level critical">Critical</span>
Vulnerability can be used to run attacker code and install
software, requiring no user interaction beyond normal browsing.
</li>
<li class="level-item"><span class="level high">High</span>
Vulnerability can be used to gather sensitive data
from sites in other windows or inject data or code into
those sites, requiring no more than normal browsing actions.
</li>
<li class="level-item"><span class="level moderate">Moderate</span>
Vulnerabilities that would otherwise be High or Critical
except they only work in uncommon non-default configurations or
require the user to perform complicated and/or unlikely steps.
</li>
<li class="level-item"><span class="level low">Low</span>
Minor security vulnerabilities such as Denial of Service
attacks, minor data leaks, or spoofs. (Undetectable spoofs of
SSL indicia would have "High" impact because those are generally
used to steal sensitive data intended for other sites.)
</li>
</ul>

Просмотреть файл

@ -1,53 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% set title = 'Security Advisories for ' + product_name %}
{% block page_title %}{{ title }}{% endblock %}
{% block messages %}
{% endblock %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">{{ title }}</h1>
</header>
{% if is_obsolete %}
<p class="note">{{ product_name }} is unsupported.
{% if product_slug == 'firefox' %}
Please <a href="{{ url('firefox.new') }}">upgrade to the latest version</a>.
{% elif product_slug == 'firefox-esr' %}
Please <a href="{{ url('firefox.enterprise.index') }}">upgrade to the latest version</a>.
{% elif product_slug.startswith('thunderbird') %}
{# could be thunderbird-esr which is always obsolete now #}
Please <a href="https://thunderbird.net">upgrade to the latest version</a>.
{% elif product_slug == 'seamonkey' %}
Please <a href="http://www.seamonkey-project.org/">upgrade to the latest version</a>.
{% else %}
Please upgrade to the latest version.
{% endif %}
</p>
{% endif %}
{% include "security/partials/impact_key.html" %}
{% for version in product_versions %}
<h3 id="{{ version.html_id }}" class="level-heading"><a href="#{{ version.html_id }}">
<span class="anchor">#</span>
Fixed in {{ version.name }}
</a></h3>
<ul>
{% for advisory in version.advisories.all() %}
<li class="level-item"><a href="{{ advisory.get_absolute_url() }}" data=version="{{ version.html_id }}">
<span class="level {{ advisory.impact_class }}">{{ advisory.id }}</span> {{ advisory.title|safe }}
</a></li>
{% endfor %}
</ul>
{% endfor %}
{% endblock %}

Просмотреть файл

@ -1,215 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Third-party Injection Policy{% endblock %}
{% set body_id = "third-party-innection-policy" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Third-party Injection Policy</h1>
</header>
<p>
The Firefox browser supports expanding its functionality with browser
extensions and provides an extensive and well documented set of APIs
for developers known as the <a href="https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions">WebExtensions API</a>.
To date, developers have contributed tens of thousands of extensions
available on addons.mozilla.org. Nevertheless, some third-party
developers seek to modify the browser in ways beyond what is possible
with a browser extension and resort to “hooking” the browser, effectively
injecting third-party executable code modules into Firefox processes.
Security software such as anti-virus products on Windows are the most
prevalent examples.
</p>
<h2>Maintaining the User Experience - Reliable and Secure Browsing</h2>
<p>
Even when the desired behavior might be beneficial to users, modifying
Firefox in this way is inherently risky. Such modifications may cause
browser crashes, broken features, or other unexpected problems that
degrade the user experience. When third-party software is found to
destabilize the browser, Firefox may intervene.
</p>
<p>Interventions* may include, but are not limited to:</p>
<ol class="mzp-u-list-styled">
<li>
Detecting instability locally, notifying the user, and offering them
the opportunity to block specific modules from being injected.
</li>
<li>
Detecting instability locally, automatically blocking the unstable
module, and providing the user an option to unblock it.
</li>
<li>
Detecting aggregate instability across many users, and proactively
blocking the module globally across all Firefox instances.
</li>
</ol>
<p>
<em>
*Current versions of Firefox do not automatically block problematic
modules or prompt the user to do so, but we are exploring this
functionality. Firefox does maintain a block list which is already
used when problems are discovered from crash reporting and bug
reports. See below for more information.
</em>
</p>
<p>
If a third-party feature achieved with Firefox injection works well,
thats great. However, if we become aware of a problem, we will
contact the vendor if they have shared a responsive support contact
with Mozilla. We are happy to alert external vendors about such
issues and welcome proactive communication with vendors before
issues arise. Please contact us at
<a href="mailto:thirdpartysoftware@mozilla.com">thirdpartysoftware@mozilla.com</a>.
</p>
<p>
While we prefer to work cooperatively with other developers, our
resources are finite and oftentimes we have to act quickly. We reserve
the right to block third-party injections whenever we believe this is
in the best interest of Firefox users.
</p>
<p>
We intend to review this position over time and may be more restrictive
with third-party module injection in the future.
</p>
<h2>In-Browser Diagnostics</h2>
<p>
When we encounter an interoperability issue caused by a third-party module,
we look for a workaround or implement a mitigation patch in Firefox while
contacting the vendor to request a fix. If those attempts are not
successful, we globally block the module using our
<a href="https://wiki.mozilla.org/Blocklisting/DLL">blocklist</a>.
In most cases, blocking can be limited to the problematic versions of the
module and modules can be unblocked after a fix is implemented. Not all
third-party interoperability issues are addressed. For example, some may
only affect a small number of users.
</p>
<p>
In Firefox, we provide an in-browser diagnostics page. The about:third-party
page (<a href="https://support.mozilla.org/kb/identify-problems-third-party-modules-firefox-windows">only available on Firefox for Windows</a>)
in Firefox lists the injected modules together with details about the injection
technique, loading time, and - if possible - vendor and product names.
</p>
<p>
If we detect at runtime that previous Firefox crashes were caused by a
third-party module, we may prompt the user to block or we may automatically
block the module giving the user the option to unblock the module in the
future, depending on the severity of the impact.
</p>
<h2>Technical Recommendations</h2>
<p>
The rest of this document contains guidelines and best practices to
minimize the risk of instability. We strongly recommend following these
guidelines, both to reduce stability risk and to avoid potentially being
misclassified as a source of instability.
</p>
<p>
Some of the details in this document concern implementation details that
are subject to change as we improve the performance, security and functionality
of the browser. Note that Mozilla publishes Beta and Nightly versions of
Firefox that can give you an early warning about upcoming changes that may
affect your software. We recommend testing on Nightly and Beta as well as
Release versions of Firefox.
</p>
<h2>Firefox Process Structure</h2>
<ul class="mzp-u-list-styled">
<li>
<p>Launcher Process (Windows-specific)</p>
<ul>
<li>
<p>
Browser Process (main process, sometimes referred to as parent process
or chrome process inside Firefox sources and legacy documentation)
</p>
<ul>
<li>Content Processes (render web pages)</li>
<li>Privileged Content Process (for Mozilla accounts and addons.mozilla.org)</li>
<li>Privileged about: Content-like Process</li>
<li>GPU Process</li>
<li>RDD Process (media decoding)</li>
<li>GMP Process (DRM decoding)</li>
<li>Socket Process (network handling - WebRTC)</li>
<li>WebExtensions Process</li>
<li>WebVR Process</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Guidelines for Module Injection</h2>
<p>
Processes other than the Browser Process and the Socket Process should
preferably not be injected into. Specifically, processes sitting below
the browser process will tend to be heavily sandboxed and may have very
limited ability to interact with the operating system, including standard
Win32 APIs (i.e. win32k.sys may not even be accessible), or may be blocked
from loading code with third party signatures (Arbitrary Code Guard/Code
Injection Guard). <strong>Injecting into these may stop security
functionality from working, or render the browser non functional</strong>.
</p>
<p>
As more functionality related to networking moves to the Socket Process,
injecting there may be unavoidable for software that wants to monitor
low-level network access.
</p>
<p>
The Launcher Process is a process to launch the browser process and apply
several security mitigations. Because the launcher process terminates quickly
after launching the browser process and is isolated from browsing-related work,
there is no benefit to injecting a third-party module into the launcher process.
</p>
<p>
These guidelines mean that if a third party vendor wants a module to be loaded
into our process, it is necessary that their module or injector program recognizes
the target process type and does not modify our sandboxed processes. With the
current design, the easiest way to detect the process type is to check the last
token in the command line string. If this is “-contentproc”, then you are dealing
with a child process (of any type, not necessarily content!) and typically do not
want to inject. If the type of child process is needed, this corresponds to the
last token (With “socket” being the Socket Process). Such implementation details
are subject to change.
</p>
<p>
On Windows, there are many known techniques to inject a module into a remote process.
In general, a technique implemented as a part of Windows OS is safer, such as
<a href="https://docs.microsoft.com/windows/win32/winmsg/hooks">Window message hook</a>
or <a href="https://docs.microsoft.com/windows/win32/win7appqual/appinit-dlls-in-windows-7-and-windows-server-2008-r2">AppInit_DLLs</a>.
On the other hand, a technique that modifies a code segment of a mapped image, such as
<a href="https://github.com/microsoft/detours">Microsoft Detours</a>, is strongly NOT
recommended because if <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1696571">more than one application applies a hook on the same function</a>,
behavior is undefined and the result is almost certainly breakage.
</p>
<p>
Please contact us at <a href="mailto:thirdpartiesplaceholder@mozilla.com">thirdpartysoftware@mozilla.com</a>
with questions.
</p>
{% endblock %}

Просмотреть файл

@ -1,23 +0,0 @@
{#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#}
{% extends "security/base.html" %}
{% block page_title %}Web and Services Bug Bounty Program{% endblock %}
{% set body_id = "web-bug-bounty" %}
{% block article %}
<header>
<h1 class="mzp-c-article-title">Web and Services Bug Bounty Program</h1>
</header>
<h2>Introduction</h2>
<p>The Mozilla Bug Bounty Program is designed to encourage security research into Mozilla's websites and services and to reward those who find unique and original bugs in our web infrastructure.</p>
<p><strong>We have migrated our web bug bounty program to HackerOne.</strong> Please visit our policy page to learn more and to submit reports. <a href="https://hackerone.com/mozilla">Mozilla HackerOne Program</a></p>
{% endblock %}

Просмотреть файл

@ -1,3 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

Просмотреть файл

@ -1,98 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import os.path
from unittest.mock import patch
from django.conf import settings
from bedrock.mozorg.tests import TestCase
from bedrock.security.management.commands import update_security_advisories
from bedrock.security.models import Product
def test_fix_product_name():
"""Should fix SeaMonkey and strip '.0' from names."""
assert update_security_advisories.fix_product_name("Seamonkey 2.2") == "SeaMonkey 2.2"
assert update_security_advisories.fix_product_name("Firefox 2.2") == "Firefox 2.2"
assert update_security_advisories.fix_product_name("fredflintstone 2.2") == "fredflintstone 2.2"
assert update_security_advisories.fix_product_name("Firefox 32.0") == "Firefox 32"
assert update_security_advisories.fix_product_name("Firefox 32.0.1") == "Firefox 32.0.1"
def test_filter_advisory_names():
filenames = [
"README.md",
"LICENSE.txt",
"announce/2015/mfsa2015-01.md",
"announce/2015/mfsa2016-42.yml",
"stuff/whatnot.md",
"mfsa2015-02.md",
]
good_filenames = [
settings.MOFO_SECURITY_ADVISORIES_PATH + "/announce/2015/mfsa2015-01.md",
settings.MOFO_SECURITY_ADVISORIES_PATH + "/announce/2015/mfsa2016-42.yml",
settings.MOFO_SECURITY_ADVISORIES_PATH + "/mfsa2015-02.md",
]
assert update_security_advisories.filter_advisory_filenames(filenames) == good_filenames
def test_get_ids_from_files():
filenames = [
"README.md",
"LICENSE.txt",
"announce/2015/mfsa2015-01.md",
"announce/2015/mfsa2016-42.yml",
"stuff/whatnot.md",
"mfsa2015-02.md",
]
good_ids = ["2015-01", "2016-42", "2015-02"]
assert update_security_advisories.get_ids_from_files(filenames) == good_ids
def make_mfsa(mfsa_id):
update_security_advisories.add_or_update_advisory(
{
"mfsa_id": mfsa_id,
"title": "The Dude is insecure",
"impact": "High",
"announced": "December 25, 2015",
"fixed_in": ["Firefox 43.0.1"],
},
"The Dude minds, man!",
)
class TestDBActions(TestCase):
def test_get_files_to_delete_from_db(self):
make_mfsa("2015-100")
make_mfsa("2015-101")
make_mfsa("2015-102")
make_mfsa("2015-103")
all_files = ["mfsa2015-100.md", "mfsa2015-101.md"]
assert set(update_security_advisories.get_files_to_delete_from_db(all_files)) == {"mfsa2015-102.md", "mfsa2015-103.md"}
def test_delete_orphaned_products(self):
make_mfsa("2015-100")
Product.objects.create(name="Firefox 43.0.2")
Product.objects.create(name="Firefox 43.0.3")
assert update_security_advisories.delete_orphaned_products() == 2
assert Product.objects.get().name == "Firefox 43.0.1"
@patch.object(update_security_advisories, "get_all_file_names")
@patch.object(update_security_advisories, "delete_files")
@patch.object(update_security_advisories, "update_db_from_file")
@patch.object(update_security_advisories, "GitRepo")
def test_file_name_extension_change(self, git_mock, udbff_mock, df_mock, gafn_mock):
"""
An MFSA file can now be either .md or .yml. Make sure this is an update, not a delete.
"""
make_mfsa("2016-42")
make_mfsa("2016-43")
all_files = [os.path.join(update_security_advisories.ADVISORIES_PATH, "mfsa2016-42.yml")]
gafn_mock.return_value = all_files
git_mock().has_changes.return_value = True
update_security_advisories.Command().handle_safe(quiet=True, no_git=False, clear_db=False)
udbff_mock.assert_called_with(update_security_advisories.filter_advisory_filenames(all_files)[0])
df_mock.assert_called_with(["mfsa2016-43.md"])

Просмотреть файл

@ -1,87 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from datetime import date
from bedrock.mozorg.tests import TestCase
from bedrock.security.models import HallOfFamer, MitreCVE, Product
class TestProduct(TestCase):
def test_version_ordering(self):
pv3 = Product.objects.create(name="Firefox 24.0.1")
pv2 = Product.objects.create(name="Firefox 24.0")
pv0 = Product.objects.create(name="Fennec 24.0")
pv1 = Product.objects.create(name="Firefox 23.0")
pv4 = Product.objects.create(name="Firefox 25")
pv5 = Product.objects.create(name="Firefox 22")
pvs = [pv2, pv0, pv3, pv1, pv4, pv5]
self.assertListEqual([pv0, pv5, pv1, pv2, pv3, pv4], sorted(pvs))
def test_product_version_slug(self):
"""Slug should include the version."""
pv0 = Product.objects.create(name="Firefox 24.0.1")
pv1 = Product.objects.create(name="Firefox ESR 24.2")
self.assertEqual(pv0.slug, "firefox-24.0.1")
self.assertEqual(pv1.slug, "firefox-esr-24.2")
class TestHallOfFamer(TestCase):
def test_year_quarter(self):
hf1 = HallOfFamer.objects.create(name="The Dude", program="web", date=date(2018, 3, 2))
hf2 = HallOfFamer.objects.create(name="The Dude", program="web", date=date(2017, 4, 2))
hf3 = HallOfFamer.objects.create(name="The Dude", program="web", date=date(2016, 7, 12))
hf4 = HallOfFamer.objects.create(name="The Dude", program="web", date=date(2015, 11, 7))
assert hf1.year_quarter == (2018, 1)
assert hf1.quarter_string == "1st Quarter 2018"
assert hf2.year_quarter == (2017, 2)
assert hf2.quarter_string == "2nd Quarter 2017"
assert hf3.year_quarter == (2016, 3)
assert hf3.quarter_string == "3rd Quarter 2016"
assert hf4.year_quarter == (2015, 4)
assert hf4.quarter_string == "4th Quarter 2015"
class TestMitreCVE(TestCase):
cve_id_order = 100
def _create_cve(self, products=None):
self.cve_id_order += 1
products = products or ["Firefox 60", "Firefox 60.0.1"]
return MitreCVE.objects.create(
id=f"CVE-2018-{self.cve_id_order}",
year=2018,
order=self.cve_id_order,
title="A Testing Problem",
description="There was a problem.",
products=products,
mfsa_ids=["2018-11"],
bugs=[{"url": "https://bugzilla.mozilla.org/show_bug.cgi?id=1234567", "desc": "Bug 1234567"}],
)
def test_product_versions(self):
cve = self._create_cve()
assert cve.product_versions() == {"Firefox": ["60", "60.0.1"]}
cve = self._create_cve(["Firefox ESR 60.0.1", "Firefox ESR 52.8.0", "Firefox 60.0.1"])
assert cve.product_versions() == {"Firefox": ["60.0.1"], "Firefox ESR": ["60.0.1", "52.8.0"]}
def test_get_reference_data(self):
cve = self._create_cve()
assert cve.get_reference_data() == [
{"url": "https://www.mozilla.org/security/advisories/mfsa2018-11/"},
{"url": "https://bugzilla.mozilla.org/show_bug.cgi?id=1234567"},
]
def test_get_description(self):
cve = self._create_cve()
assert cve.get_description() == "There was a problem. This vulnerability affects Firefox < 60 and Firefox < 60.0.1."
cve = self._create_cve(["Firefox ESR 60.0.1", "Firefox ESR 52.8.0", "Firefox 60.0.1"])
assert cve.get_description() == (
"There was a problem. This vulnerability affects Firefox ESR < 60.0.1, Firefox ESR < 52.8.0, and Firefox < 60.0.1."
)
cve = self._create_cve(["Firefox ESR 60.0.1"])
cve.description = "No punctuation"
assert cve.get_description() == "No punctuation. This vulnerability affects Firefox ESR < 60.0.1."
cve.description = "Punctuation but extra space. \n"
assert cve.get_description() == "Punctuation but extra space. This vulnerability affects Firefox ESR < 60.0.1."

Просмотреть файл

@ -1,335 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from datetime import date
from io import StringIO
from textwrap import dedent
from unittest.mock import call, patch
import pytest
from bedrock.security.utils import (
check_hof_data,
generate_yml_advisories_html,
mfsa_id_from_filename,
parse_bug_url,
parse_md_front_matter,
yaml_ordered_safe_load,
)
def test_check_hof_data():
good_names = [
{
"name": "El Dudarino",
"date": date(2018, 3, 20),
}
]
good_data = {"names": good_names * 200}
# should not raise exception
check_hof_data(good_data)
# empty, expect ValueError
with pytest.raises(ValueError):
check_hof_data({})
# wrong, expect ValueError
with pytest.raises(ValueError):
check_hof_data({"dude": "abides"})
# truncated, expect ValueError
truncated_data = {"names": good_names * 50}
with pytest.raises(ValueError):
check_hof_data(truncated_data)
# no name, expect ValueError
truncated_data = {"names": [{"date": date(2018, 3, 20)}] * 200}
with pytest.raises(ValueError):
check_hof_data(truncated_data)
# no date, expect ValueError
truncated_data = {"names": [{"name": "Donnie"}] * 200}
with pytest.raises(ValueError):
check_hof_data(truncated_data)
# date wrong format, expect ValueError
truncated_data = {"names": [{"name": "Donnie", "date": "2018-03-20"}] * 200}
with pytest.raises(ValueError):
check_hof_data(truncated_data)
# date too old, expect ValueError
truncated_data = {"names": [{"name": "Donnie", "date": date(1999, 12, 31)}] * 200}
with pytest.raises(ValueError):
check_hof_data(truncated_data)
def test_parse_front_matter():
"""Should return front matter and MD separately."""
lines = StringIO(
dedent(
"""
---
dude: abiding
walter: angry
donny: oblivious
---
Let's go bowling.
"""
)
)
yaml, md = parse_md_front_matter(lines)
assert yaml == dedent(
"""\
dude: abiding
walter: angry
donny: oblivious
"""
)
assert md == "\nLet's go bowling.\n"
def test_parse_front_matter_only():
"""Should not care about any other --- lines."""
lines = StringIO(
dedent(
"""
---
dude: abiding
walter: angry
---
Art
---
Maude's thing.
"""
)
)
yaml, md = parse_md_front_matter(lines)
assert yaml == "dude: abiding\nwalter: angry\n"
assert md == "\nArt\n---\n\nMaude's thing.\n"
def test_mfsa_id_from_filename():
assert mfsa_id_from_filename("announce/2014/mfsa2014-01.md") == "2014-01"
assert mfsa_id_from_filename("announce/2014/mfsa2014-101.md") == "2014-101"
assert mfsa_id_from_filename("announce/2016/mfsa2016-42.yml") == "2016-42"
assert mfsa_id_from_filename("dude.txt") is None
def test_parse_bug_url():
assert parse_bug_url("8675309") == "https://bugzilla.mozilla.org/show_bug.cgi?id=8675309"
assert parse_bug_url("1234,5678, 9012") == "https://bugzilla.mozilla.org/buglist.cgi?bug_id=1234%2C5678%2C9012"
assert parse_bug_url("http://example.com/1234") == "http://example.com/1234"
@patch("bedrock.security.utils.render_to_string")
def test_generate_yml_advisories_html(rts_mock):
rts_mock.return_value = "html"
data = yaml_ordered_safe_load(StringIO(YML_ADVISORY))
html = generate_yml_advisories_html(data)
assert html.startswith("<p>Some <strong>HTML</strong> that relates to the whole lot of em.</p>")
rts_mock.assert_has_calls(
[
call(
"security/partials/cve.html",
{
"id": "CVE-2016-2827",
"impact": "Low",
"impact_class": "low",
"title": "A sample title for a CVE here",
"reporter": "Reporty McReporterface",
"description": "Short description <strong>with HTML</strong> and multiple lines!\n\n"
"Can also have full breaks and ***markdown***!\n",
"bugs": [
{"url": "https://bugzilla.mozilla.org/show_bug.cgi?id=1289085", "desc": "Bug 1289085"},
{"url": "https://bugzilla.mozilla.org/buglist.cgi?bug_id=1289085%2C1289087", "desc": "stuff about the bugs"},
],
},
),
call(
"security/partials/cve.html",
{
"id": "CVE-2016-5270",
"impact": "High",
"impact_class": "high",
"title": "Another sampile title, this time with more length!",
"reporter": "A Nameless Evilcorp Employee",
"description": "Another short description",
"bugs": [
{"url": "https://example.com/warning.html", "desc": "A different site that is totally not bugzilla"},
],
},
),
]
)
@patch("bedrock.security.utils.render_to_string")
def test_generate_yml_advisories_html_non_cve(rts_mock):
rts_mock.return_value = "html"
data = yaml_ordered_safe_load(StringIO(YML_ADVISORY_NON_CVE))
html = generate_yml_advisories_html(data)
assert html.startswith("<p>Some <strong>HTML</strong> that relates to the whole lot of em.</p>")
rts_mock.assert_has_calls(
[
call(
"security/partials/cve.html",
{
"id": "CVE-2016-2827",
"impact": "Low",
"impact_class": "low",
"title": "A sample title for a CVE here",
"reporter": "Reporty McReporterface",
"description": "Short description <strong>with HTML</strong> and multiple lines!\n\n"
"Can also have full breaks and ***markdown***!\n",
"bugs": [
{"url": "https://bugzilla.mozilla.org/show_bug.cgi?id=1289085", "desc": "Bug 1289085"},
{"url": "https://bugzilla.mozilla.org/buglist.cgi?bug_id=1289085%2C1289087", "desc": "stuff about the bugs"},
],
},
),
call(
"security/partials/cve.html",
{
"id": "MVID-2016-5270",
"impact": "High",
"impact_class": "high",
"title": "Another sampile title, this time with more length!",
"reporter": "A Nameless Evilcorp Employee",
"description": "Another short description",
"bugs": [
{"url": "https://example.com/warning.html", "desc": "A different site that is totally not bugzilla"},
],
},
),
]
)
@patch("bedrock.security.utils.render_to_string")
def test_generate_yml_advisories_missing_things(rts_mock):
rts_mock.return_value = "html"
data = yaml_ordered_safe_load(StringIO(YML_ADVISORY_MISSING_THINGS))
generate_yml_advisories_html(data)
rts_mock.assert_has_calls(
[
call(
"security/partials/cve.html",
{
"id": "CVE-2016-2827",
"impact": "Low",
"impact_class": "low",
"title": "A sample title for a CVE here",
"reporter": "Reporty McReporterface",
"description": "Short description <strong>with HTML</strong> and multiple lines!\n\n"
"Can also have full breaks and ***markdown***!\n",
},
),
call(
"security/partials/cve.html",
{
"id": "CVE-2016-5270",
"impact": "High",
"impact_class": "high",
"title": "Another sampile title, this time with more length!",
"reporter": "A Nameless Evilcorp Employee",
"description": "Another short description",
"bugs": [
{"url": "https://bugzilla.mozilla.org/show_bug.cgi?id=1289085", "desc": "Bug 1289085"},
],
},
),
]
)
YML_ADVISORY = dedent(
"""\
announced: September 13, 2016
fixed_in:
- Firefox 49
title: Security vulnerabilities fixed in Firefox 49
description: Some **HTML** that relates to the whole lot of em.
advisories:
CVE-2016-2827:
title: A sample title for a CVE here
impact: Low
reporter: Reporty McReporterface
description: |
Short description <strong>with HTML</strong> and multiple lines!
Can also have full breaks and ***markdown***!
bugs:
- url: 1289085
- url: 1289085, 1289087
desc: stuff about the bugs
CVE-2016-5270:
title: Another sampile title, this time with more length!
impact: High
reporter: A Nameless Evilcorp Employee
description: Another short description
bugs:
- url: https://example.com/warning.html
desc: A different site that is totally not bugzilla
"""
)
YML_ADVISORY_NON_CVE = dedent(
"""\
announced: September 13, 2016
fixed_in:
- Firefox 49
title: Security vulnerabilities fixed in Firefox 49
description: Some **HTML** that relates to the whole lot of em.
advisories:
CVE-2016-2827:
title: A sample title for a CVE here
impact: Low
reporter: Reporty McReporterface
description: |
Short description <strong>with HTML</strong> and multiple lines!
Can also have full breaks and ***markdown***!
bugs:
- url: 1289085
- url: 1289085, 1289087
desc: stuff about the bugs
MVID-2016-5270:
title: Another sampile title, this time with more length!
impact: High
reporter: A Nameless Evilcorp Employee
description: Another short description
bugs:
- url: https://example.com/warning.html
desc: A different site that is totally not bugzilla
"""
)
YML_ADVISORY_MISSING_THINGS = dedent(
"""\
announced: September 13, 2016
fixed_in:
- Firefox 49
title: Security vulnerabilities fixed in Firefox 49
description:
advisories:
CVE-2016-2827:
title: A sample title for a CVE here
impact: Low
reporter: Reporty McReporterface
description: |
Short description <strong>with HTML</strong> and multiple lines!
Can also have full breaks and ***markdown***!
CVE-2016-5270:
title: Another sampile title, this time with more length!
impact: High
reporter: A Nameless Evilcorp Employee
description: Another short description
bugs:
- url: 1289085
desc:
"""
)

Просмотреть файл

@ -1,113 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from unittest.mock import patch
from product_details.version_compare import Version
from bedrock.mozorg.tests import TestCase
from bedrock.security.models import Product
from bedrock.security.views import ProductVersionView, ProductView, product_is_obsolete
def test_product_is_obsolete():
from product_details import product_details
with patch.object(product_details, "firefox_versions", {"LATEST_FIREFOX_VERSION": "33.0", "FIREFOX_ESR": "31.2.0"}):
with patch.object(product_details, "thunderbird_versions", {"LATEST_THUNDERBIRD_VERSION": "31.2.0"}):
assert product_is_obsolete("firefox", "3.6")
assert product_is_obsolete("firefox", "32")
assert product_is_obsolete("firefox-esr", "17.0")
assert product_is_obsolete("thunderbird", "30")
assert product_is_obsolete("seamonkey", "2.0")
assert product_is_obsolete("seamonkey", "2.19")
assert product_is_obsolete("other-things", "3000")
assert not product_is_obsolete("firefox", "33.0.2")
assert not product_is_obsolete("firefox", "34.0")
assert not product_is_obsolete("firefox-esr", "31.0")
assert not product_is_obsolete("thunderbird", "31")
assert not product_is_obsolete("seamonkey", "2.30")
class TestViews(TestCase):
def setUp(self):
pvnames = [
"Firefox 3.6",
"Firefox 4.0",
"Firefox 4.0.1",
"Firefox 4.2",
"Firefox 4.2.3",
"Firefox 24.0",
]
self.pvs = [Product.objects.create(name=pv) for pv in pvnames]
def test_product_view_min_version(self):
"""Should not include versions below minimum."""
pview = ProductView()
pview.kwargs = {"slug": "firefox"}
with patch.dict(pview.minimum_versions, {"firefox": Version("4.2")}):
self.assertListEqual(pview.get_queryset(), [self.pvs[5], self.pvs[4], self.pvs[3]])
with patch.dict(pview.minimum_versions, {"firefox": Version("22.0")}):
self.assertListEqual(pview.get_queryset(), [self.pvs[5]])
def test_product_version_view_filter_major(self):
"""Given a major version should return all minor versions."""
pview = ProductVersionView()
pview.kwargs = {"product": "firefox", "version": "4"}
self.assertListEqual(pview.get_queryset(), [self.pvs[4], self.pvs[3], self.pvs[2], self.pvs[1]])
def test_product_version_view_filter_minor(self):
"""Given a minor version should return all point versions."""
pview = ProductVersionView()
pview.kwargs = {"product": "firefox", "version": "4.2"}
self.assertListEqual(pview.get_queryset(), [self.pvs[4], self.pvs[3]])
class TestKVRedirects(TestCase):
def _test_names(self, url_component, expected):
# old urls lack '/en-US' prefix, but that will be the first redirect.
path = f"/en-US/security/known-vulnerabilities/{url_component}.html"
resp = self.client.get(path)
assert resp.status_code == 301
assert expected == resp["Location"].split("/")[-2]
def test_correct_redirects(self):
self._test_names("firefox", "firefox")
self._test_names("firefoxESR", "firefox-esr")
self._test_names("firefox20", "firefox-2.0")
self._test_names("thunderbird15", "thunderbird-1.5")
self._test_names("suite17", "mozilla-suite")
def test_spaces_removed(self):
"""Should succeed even if accidental spaces are in the URL.
Bug 1171181.
"""
self._test_names("firefox3%20%200", "firefox-3.0")
def test_unknown_is_404(self):
"""Should 410 instead of 500 if an unknown url matches the redirector.
Bug 1171181.
"""
path = "/en-US/security/known-vulnerabilities/the-dude-abides-15.html"
resp = self.client.get(path)
assert resp.status_code == 410
class TestOldAdvisories(TestCase):
def _test_redirect(self, path, expected):
# old urls lack '/en-US' prefix, but that will be the first redirect.
resp = self.client.get("/en-US" + path)
assert resp.status_code == 301
assert resp["Location"].endswith(expected)
def test_old_urls(self):
"""Should redirect old URLs properly."""
self._test_redirect("/security/announce/mfsa2005-31.html", "/security/advisories/mfsa2005-31/")
self._test_redirect("/security/announce/2005/mfsa2005-40.html", "/security/advisories/mfsa2005-40/")
self._test_redirect("/security/advisories/2008/mfsa2008-47.html", "/security/advisories/mfsa2008-47/")
self._test_redirect("/security/advisories/mfsa2008-66/mfsa2008-37.html", "/security/advisories/mfsa2008-37/")

Просмотреть файл

@ -1,45 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from django.urls import path, re_path
from bedrock.mozorg.util import page
from bedrock.security.views import (
AdvisoriesView,
AdvisoryView,
HallOfFameView,
KVRedirectsView,
OldAdvisoriesListView,
OldAdvisoriesView,
ProductVersionView,
ProductView,
mitre_cve_feed,
)
urlpatterns = (
page("", "security/index.html"),
page("bug-bounty/", "security/bug-bounty.html"),
page("client-bug-bounty/", "security/client-bug-bounty.html"),
page("web-bug-bounty/", "security/web-bug-bounty.html"),
page("bug-bounty/faq/", "security/bug-bounty/faq.html"),
page("bug-bounty/faq-webapp/", "security/bug-bounty/faq-webapp.html"),
page("bug-bounty/web-eligible-sites/", "security/bug-bounty/web-eligible-sites.html"),
path("bug-bounty/hall-of-fame/", HallOfFameView.as_view(program="client"), name="security.bug-bounty.hall-of-fame"),
path("bug-bounty/web-hall-of-fame/", HallOfFameView.as_view(program="web"), name="security.bug-bounty.web-hall-of-fame"),
path("advisories/", AdvisoriesView.as_view(), name="security.advisories"),
re_path(r"^advisories/mfsa(?P<pk>\d{4}-\d{2,3})/$", AdvisoryView.as_view(), name="security.advisory"),
re_path(r"^advisories/cve-feed\.json$", mitre_cve_feed, name="security.advisories.cve_feed"),
page("known-vulnerabilities/", "security/known-vulnerabilities.html"),
page("known-vulnerabilities/older-vulnerabilities/", "security/older-vulnerabilities.html"),
re_path(r"^known-vulnerabilities/(?P<slug>[a-z-]+)/$", ProductView.as_view(), name="security.product-advisories"),
re_path(
r"^known-vulnerabilities/(?P<product>[\w-]+)-(?P<version>\d{1,3}(\.\d{1,3})?)/$",
ProductVersionView.as_view(),
name="security.product-version-advisories",
),
re_path(r"^known-vulnerabilities/(?P<filename>.*)\.html$", KVRedirectsView.as_view()),
re_path(r"^(?:announce|advisories)(?:/.*)?/mfsa(?P<pk>\d{4}-\d{2,3})\.html$", OldAdvisoriesView.as_view()),
path("announce/", OldAdvisoriesListView.as_view()),
page("third-party-software-injection/", "security/third-party-injection-policy.html"),
)

Просмотреть файл

@ -1,158 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import codecs
import re
from collections import OrderedDict
from datetime import date
from django.template.loader import render_to_string
import yaml
from markdown import markdown
FILENAME_RE = re.compile(r"mfsa(\d{4}-\d{2,3})\.(md|yml)$")
def mfsa_id_from_filename(filename):
match = FILENAME_RE.search(filename)
if match:
return match.group(1)
return None
def parse_md_front_matter(lines):
"""Return the YAML and MD sections.
:param: lines iterator
:return: str YAML, str Markdown
"""
# fm_count: 0: init, 1: in YAML, 2: in Markdown
fm_count = 0
yaml_lines = []
md_lines = []
for line in lines:
# first line we care about is FM start
if fm_count < 2 and line.strip() == "---":
fm_count += 1
continue
if fm_count == 1:
yaml_lines.append(line)
if fm_count == 2:
md_lines.append(line)
if fm_count < 2:
raise ValueError("Front Matter not found.")
return "".join(yaml_lines), "".join(md_lines)
def parse_md_file(file_name):
"""Return the YAML and MD sections for file_name."""
with codecs.open(file_name, encoding="utf8") as fh:
yamltext, mdtext = parse_md_front_matter(fh)
data = yaml_ordered_safe_load(yamltext)
if "mfsa_id" not in data:
mfsa_id = mfsa_id_from_filename(file_name)
if mfsa_id:
data["mfsa_id"] = mfsa_id
return data, markdown(mdtext)
def parse_yml_file_base(file_name):
with codecs.open(file_name, encoding="utf8") as fh:
return yaml_ordered_safe_load(fh)
def parse_yml_file(file_name):
data = parse_yml_file_base(file_name)
if "mfsa_id" not in data:
mfsa_id = mfsa_id_from_filename(file_name)
if mfsa_id:
data["mfsa_id"] = mfsa_id
return data, generate_yml_advisories_html(data)
def update_advisory_bugs(advisory):
if advisory.get("bugs", None):
for bug in advisory["bugs"]:
if not bug.get("desc", None):
bug["desc"] = f"Bug {bug['url']}"
bug["url"] = parse_bug_url(bug["url"])
def generate_yml_advisories_html(data):
html = []
if data.get("description", None):
html.append(markdown(data["description"]))
for cve, advisory in data["advisories"].items():
advisory["id"] = cve
advisory["impact_class"] = advisory["impact"].lower().split(None, 1)[0]
update_advisory_bugs(advisory)
html.append(render_to_string("security/partials/cve.html", advisory))
return "\n\n".join(html)
def parse_bug_url(url):
"""
Take a bug number, list of bug numbers, or a URL and output a URL.
url could be a bug number, a comma separated list of bug numbers, or a URL.
"""
# could be an int
url = str(url).strip()
if re.match(r"^\d+$", url):
url = f"https://bugzilla.mozilla.org/show_bug.cgi?id={url}"
elif re.match(r"^[\d\s,]+$", url):
url = re.sub(r"\s", "", url).replace(",", "%2C")
url = f"https://bugzilla.mozilla.org/buglist.cgi?bug_id={url}"
return url
def yaml_ordered_safe_load(stream, object_pairs_hook=OrderedDict):
"""
Load YAML mappings as OrderedDicts
from http://stackoverflow.com/a/21912744
"""
class OrderedLoader(yaml.SafeLoader):
pass
def construct_mapping(loader, node):
loader.flatten_mapping(node)
return object_pairs_hook(loader.construct_pairs(node))
OrderedLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, construct_mapping)
return yaml.load(stream, OrderedLoader)
def check_hof_data(data):
"""Check the HOF Data and raise ValueError if there's a problem."""
if not data:
raise ValueError("HOF Data is empty")
if "names" not in data:
raise ValueError("Missing required key: names")
if len(data["names"]) < 100:
raise ValueError("Suspiciously few names returned. File may be corrupted.")
for name in data["names"]:
if "name" not in name:
raise ValueError('Key "name" required for every entry in "names"')
if "date" not in name:
raise ValueError('Key "date" required for every entry in "names"')
if not isinstance(name["date"], date):
raise ValueError(f'Key "date" should be formatted as a date (YYYY-MM-DD): {name["date"]}')
if name["date"] < date(2004, 11, 9):
raise ValueError("A date can't be set before the launch date of Firefox")

Просмотреть файл

@ -1,183 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
import re
from django.db.models import Q
from django.urls import NoReverseMatch
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_safe
from django.views.generic import DetailView, ListView, RedirectView
from jsonview.decorators import json_view
from product_details import product_details
from product_details.version_compare import Version
from bedrock.base.urlresolvers import reverse
from bedrock.mozorg.decorators import cache_control_expires
from bedrock.security.models import HallOfFamer, MitreCVE, Product, SecurityAdvisory
from lib.l10n_utils import LangFilesMixin, RequireSafeMixin
@json_view
@require_safe
def mitre_cve_feed(request):
return [cve.feed_entry() for cve in MitreCVE.objects.all()]
def product_is_obsolete(prod_name, version):
"""
Return true if the product major version is not latest.
:param prod_name: e.g. "firefox"
:param version: e.g. "33.0.2"
:return: boolean
"""
if prod_name == "seamonkey":
# latest right now is 2.30. Should be good enough for a while.
return Version(version) < Version("2.30")
major_vers = int(version.split(".")[0])
if prod_name == "firefox":
# we've got info in product-details
latest_version = product_details.firefox_versions["LATEST_FIREFOX_VERSION"]
latest_major_vers = int(latest_version.split(".")[0])
return major_vers < latest_major_vers
if prod_name == "firefox-esr":
# we've got info in product-details
latest_version = product_details.firefox_versions["FIREFOX_ESR"]
latest_major_vers = int(latest_version.split(".")[0])
return major_vers < latest_major_vers
if prod_name == "thunderbird":
# we've got info in product-details
latest_version = product_details.thunderbird_versions["LATEST_THUNDERBIRD_VERSION"]
latest_major_vers = int(latest_version.split(".")[0])
return major_vers < latest_major_vers
# everything else is obsolete
return True
class HallOfFameView(LangFilesMixin, RequireSafeMixin, ListView):
template_names = {
"client": "security/bug-bounty/hall-of-fame.html",
"web": "security/bug-bounty/web-hall-of-fame.html",
}
context_object_name = "hofers"
allow_empty = False
program = None
def get_template_names(self):
return [self.template_names[self.program]]
def get_queryset(self):
return HallOfFamer.objects.filter(program=self.program)
class AdvisoriesView(LangFilesMixin, RequireSafeMixin, ListView):
template_name = "security/advisories.html"
queryset = SecurityAdvisory.objects.only("id", "impact", "title", "announced")
context_object_name = "advisories"
class AdvisoryView(LangFilesMixin, RequireSafeMixin, DetailView):
model = SecurityAdvisory
template_name = "security/advisory.html"
context_object_name = "advisory"
class ProductView(LangFilesMixin, RequireSafeMixin, ListView):
template_name = "security/product-advisories.html"
context_object_name = "product_versions"
allow_empty = False
minimum_versions = {
"firefox": Version("4.0"),
"thunderbird": Version("6.0"),
"seamonkey": Version("2.3"),
}
def get_queryset(self):
product_slug = self.kwargs.get("slug")
versions = Product.objects.filter(product_slug=product_slug)
min_version = self.minimum_versions.get(product_slug)
if min_version:
versions = [vers for vers in versions if vers.version >= min_version]
return sorted(versions, reverse=True)
def get_context_data(self, **kwargs):
cxt = super().get_context_data(**kwargs)
cxt["product_name"] = cxt["product_versions"][0].product
return cxt
class ProductVersionView(LangFilesMixin, RequireSafeMixin, ListView):
template_name = "security/product-advisories.html"
context_object_name = "product_versions"
allow_empty = False
def get_queryset(self):
slug = "{product}-{version}".format(**self.kwargs)
qfilter = Q(slug__startswith=slug + ".")
dots = slug.count(".")
if dots < 2:
# add exact match if not point release
if slug.endswith(".0"):
# stip trailing .0 as products are stored without them
slug = slug[:-2]
qfilter |= Q(slug__exact=slug)
versions = Product.objects.filter(qfilter)
return sorted(versions, reverse=True)
def get_context_data(self, **kwargs):
cxt = super().get_context_data(**kwargs)
prod_name, version = self.kwargs["product"], self.kwargs["version"]
cxt["is_obsolete"] = product_is_obsolete(prod_name, version)
cxt["product_name"] = f"{cxt['product_versions'][0].product} {version}"
cxt["product_slug"] = prod_name
return cxt
class CachedRedirectView(RedirectView):
permanent = True
@method_decorator(cache_control_expires(24 * 30)) # 30 days
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
class OldAdvisoriesView(CachedRedirectView):
def get_redirect_url(self, **kwargs):
return reverse("security.advisory", kwargs=kwargs)
class OldAdvisoriesListView(CachedRedirectView):
def get_redirect_url(self, **kwargs):
return reverse("security.advisories")
class KVRedirectsView(CachedRedirectView):
prod_ver_re = re.compile(r"(\w+)(\d{2})$")
def get_redirect_url(self, *args, **kwargs):
url_component = kwargs["filename"].replace(" ", "")
try:
return reverse(**self.get_redirect_args(url_component))
except NoReverseMatch:
return None
def get_redirect_args(self, url_component):
if url_component == "suite17":
return dict(viewname="security.product-advisories", kwargs={"slug": "mozilla-suite"})
match = self.prod_ver_re.match(url_component)
if match:
product, version = match.groups()
return dict(viewname="security.product-version-advisories", kwargs={"product": product, "version": f"{version[0]}.{version[1]}"})
if url_component.endswith("ESR"):
return dict(viewname="security.product-advisories", kwargs={"slug": url_component[:-3] + "-esr"})
return dict(viewname="security.product-advisories", kwargs={"slug": url_component})

Просмотреть файл

@ -317,10 +317,6 @@ EXCLUDE_EDIT_TEMPLATES = [
"firefox/releases/notes.html",
"firefox/releases/system_requirements.html",
"mozorg/about/forums.html",
"security/advisory.html",
"security/advisories.html",
"security/product-advisories.html",
"security/known-vulnerabilities.html",
]
# Also allow entire directories to be skipped
EXCLUDE_EDIT_TEMPLATES_DIRECTORIES = [
@ -746,7 +742,6 @@ INSTALLED_APPS = [
"bedrock.mozorg",
"bedrock.newsletter",
"bedrock.privacy",
"bedrock.security",
"bedrock.releasenotes",
"bedrock.utils",
"bedrock.sitemaps",
@ -972,10 +967,6 @@ RELEASE_NOTES_PATH = config("RELEASE_NOTES_PATH", default=data_path("release_not
RELEASE_NOTES_REPO = config("RELEASE_NOTES_REPO", default="https://github.com/mozilla/release-notes.git")
RELEASE_NOTES_BRANCH = config("RELEASE_NOTES_BRANCH", default="master")
MOFO_SECURITY_ADVISORIES_PATH = config("MOFO_SECURITY_ADVISORIES_PATH", default=data_path("mofo_security_advisories"))
MOFO_SECURITY_ADVISORIES_REPO = config("MOFO_SECURITY_ADVISORIES_REPO", default="https://github.com/mozilla/foundation-security-advisories.git")
MOFO_SECURITY_ADVISORIES_BRANCH = config("MOFO_SECURITY_ADVISORIES_BRANCH", default="master")
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r"^/([a-zA-Z-]+/)?(newsletter)/"

Просмотреть файл

@ -220,27 +220,23 @@ def test_get_wagtail_urls__ensure_locale_codes_not_stripped(dummy_wagtail_pages)
@patch("bedrock.sitemaps.utils.get_static_urls")
@patch("bedrock.sitemaps.utils.get_release_notes_urls")
@patch("bedrock.sitemaps.utils.get_security_urls")
@patch("bedrock.sitemaps.utils.get_wagtail_urls")
@patch("bedrock.sitemaps.utils.output_json")
def test_update_sitemaps(
mock_output_json,
mock_get_wagtail_urls,
mock_get_security_urls,
mock_get_release_notes_urls,
mock_get_static_urls,
):
"Light check to ensure we've not added _new_ things we haven't added tests for"
mock_get_wagtail_urls.return_value = {"wagtail": "dummy1"}
mock_get_security_urls.return_value = {"security": "dummy3"}
mock_get_release_notes_urls.return_value = {"release_notes": "dummy4"}
mock_get_static_urls.return_value = {"static_urls": "dummy5"}
update_sitemaps()
expected = {
"wagtail": "dummy1",
"security": "dummy3",
"release_notes": "dummy4",
"static_urls": "dummy5",
}

Просмотреть файл

@ -15,50 +15,6 @@ from django.urls import resolvers
from wagtail.models import Page
from bedrock.releasenotes.models import ProductRelease
from bedrock.security.models import SecurityAdvisory
SEC_KNOWN_VULNS = [
"/security/known-vulnerabilities/firefox/",
"/security/known-vulnerabilities/firefox-esr/",
"/security/known-vulnerabilities/firefox-for-ios/",
"/security/known-vulnerabilities/firefox-os/",
"/security/known-vulnerabilities/mozilla-vpn/",
"/security/known-vulnerabilities/thunderbird/",
"/security/known-vulnerabilities/thunderbird-esr/",
"/security/known-vulnerabilities/seamonkey/",
"/security/known-vulnerabilities/firefox-3.6/",
"/security/known-vulnerabilities/firefox-3.5/",
"/security/known-vulnerabilities/firefox-3.0/",
"/security/known-vulnerabilities/firefox-2.0/",
"/security/known-vulnerabilities/firefox-1.5/",
"/security/known-vulnerabilities/firefox-1.0/",
"/security/known-vulnerabilities/thunderbird-3.1/",
"/security/known-vulnerabilities/thunderbird-3.0/",
"/security/known-vulnerabilities/thunderbird-2.0/",
"/security/known-vulnerabilities/thunderbird-1.5/",
"/security/known-vulnerabilities/thunderbird-1.0/",
"/security/known-vulnerabilities/seamonkey-2.0/",
"/security/known-vulnerabilities/seamonkey-1.1/",
"/security/known-vulnerabilities/seamonkey-1.0/",
"/security/known-vulnerabilities/mozilla-suite/",
]
def get_security_urls():
urls = {url: ["en-US"] for url in SEC_KNOWN_VULNS}
for advisory in SecurityAdvisory.objects.all():
try:
adv_url = advisory.get_absolute_url()
except resolvers.NoReverseMatch:
continue
# strip "/en-US" off the front
if adv_url.startswith("/en-US"):
adv_url = adv_url[6:]
urls[adv_url] = ["en-US"]
return urls
def get_release_notes_urls():
@ -201,7 +157,6 @@ def get_wagtail_urls():
def update_sitemaps():
urls = get_static_urls()
urls.update(get_release_notes_urls())
urls.update(get_security_urls())
urls.update(get_wagtail_urls())
# Output static files

Просмотреть файл

@ -26,7 +26,6 @@ locale404 = "lib.l10n_utils.locale_selection"
urlpatterns = bedrock_i18n_patterns(
# Main pages
path("privacy/", include("bedrock.privacy.urls")),
path("security/", include("bedrock.security.urls")),
path("", include("bedrock.firefox.urls")),
path("", include("bedrock.mozorg.urls")), # these are locale-needing URLs, vs mozorg.nonlocale_urls
path("", include("bedrock.newsletter.urls")),

Просмотреть файл

@ -33,7 +33,6 @@ failure_detected=false
# Please ensure all new command calls are suffixed with || failure_detected=true
python manage.py update_product_details_files || failure_detected=true
python manage.py update_security_advisories --quiet || failure_detected=true
python manage.py update_release_notes --quiet || failure_detected=true
python manage.py update_newsletter_data --quiet || failure_detected=true
python manage.py update_sitemaps_data --quiet || failure_detected=true

Просмотреть файл

@ -1,24 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
.mzp-u-data-table {
td:has(> ul) {
border-top: 0;
margin-top: $spacing-xl;
}
ul.multiple-item-list {
margin-bottom: 0;
}
td.two-col-cell {
text-align: center;
}
td.two-col-cell:not(.first-of-section) {
border-top: 0;
}
}

Просмотреть файл

@ -1,51 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
.advisory {
.summary {
margin-bottom: 0;
dt {
@include font-size(16px);
font-weight: bold;
}
dd {
margin-bottom: 10px;
padding-left: $layout-sm;
}
@media #{$mq-sm} {
@supports (display: grid) {
display: grid;
grid-template-columns: 100px 1fr;
grid-row-gap: 10px;
dt {
display: block;
}
dd {
display: block;
padding-left: 0;
margin-bottom: 0;
}
}
}
}
.cve {
margin-bottom: $layout-md;
h5 {
@include font-size(16px);
}
p {
margin-bottom: $spacing-sm;
}
}
}

Просмотреть файл

@ -1,22 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
#older-vulnerabilities {
.mzp-c-article {
max-width: 100%;
}
}
.mzp-u-data-table {
th,
td {
vertical-align: top;
}
td {
@include font-size(14px);
}
}

Просмотреть файл

@ -1,81 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
// Security impact levels
.level-item {
padding: 0.714rem 0 0.5rem;
position: relative;
}
.level {
@include text-body-xs;
background: $color-marketing-gray-10;
border-right: 3px solid $color-marketing-gray-30;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05), 0 -1px 0 rgba(0, 0, 0, 0.05) inset;
color: #000;
display: inline-block;
font-style: normal;
font-weight: bold;
line-height: 1;
padding: 4px;
min-width: 90px;
&.moderate {
background: $color-yellow-10;
border-color: $color-yellow-40;
}
&.high {
background: $color-orange-10;
border-color: $color-orange-50;
}
&.critical {
background: $color-red-10;
border-color: $color-red-50;
}
}
// move levels to the left once there's enough space
@media #{$mq-sm} {
.level-item {
padding-left: 110px;
.level {
left: 0;
position: absolute;
top: 1rem;
}
}
}
// linkable headings in product advisories
.level-heading {
position: relative;
a,
a:visited {
color: inherit;
text-decoration: none;
&:hover,
&:focus,
&:active {
.anchor {
color: $color-link;
}
}
}
.anchor {
position: absolute;
left: -1em;
width: 1em;
color: $color-marketing-gray-40;
vertical-align: middle;
}
}

Просмотреть файл

@ -1,23 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
.links {
li {
margin-bottom: 1.25em;
padding-bottom: 0.25em;
border-bottom: 2px solid $color-marketing-gray-20;
}
}
@media #{$mq-lg} {
@supports (display: grid) {
.links {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: $gutter-width;
}
}
}

Просмотреть файл

@ -1,13 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
p.note {
border-color: $color-marketing-gray-20;
border-style: solid;
border-width: 2px 0;
background: $color-marketing-gray-10;
padding: $layout-sm;
}

Просмотреть файл

@ -1,10 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use '~@mozilla-protocol/core/protocol/css/includes/lib' as *;
details {
@include clearfix;
margin-bottom: $layout-sm;
}

Просмотреть файл

@ -1,13 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
@use 'components/advisory';
@use 'components/data-table';
@use 'components/level';
@use 'components/links';
@use 'components/note';
.pgp-key {
overflow-x: auto; // only add scrollbar with horizontal overflow
}

Просмотреть файл

@ -140,12 +140,6 @@
],
"name": "firefox_new_ie"
},
{
"files": [
"css/security/security.scss"
],
"name": "security"
},
{
"files": [
"css/firefox/testflight.scss"
@ -158,18 +152,6 @@
],
"name": "contribute"
},
{
"files": [
"css/security/client-bug-bounty.scss"
],
"name": "client-bug-bounty"
},
{
"files": [
"css/security/hall-of-fame.scss"
],
"name": "security-bug-bounty-hall-of-fame"
},
{
"files": [
"css/mozorg/manifesto.scss"