Verified Commit d631563b authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

Bug 41116: Normalize system fonts.

System fonts are an enormous fingerprinting vector.
Even with font allow lists and with our custom configuration on Linux,
which counter metrics measurements, getComputedStyle leaks several
details.
This patch counters both these kinds of attacks.
parent de24dc95
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -1978,6 +1978,14 @@ static void GetSystemUIFontFamilies([[maybe_unused]] nsAtom* aLangGroup,
  nsFont systemFont;
  nsFont systemFont;
  gfxFontStyle fontStyle;
  gfxFontStyle fontStyle;
  nsAutoString systemFontName;
  nsAutoString systemFontName;
  if (nsContentUtils::ShouldResistFingerprinting()) {
#ifdef XP_MACOSX
    *aFamilies.AppendElement() = "-apple-system"_ns;
#else
    *aFamilies.AppendElement() = "sans-serif"_ns;
#endif
    return;
  }
  if (!LookAndFeel::GetFont(StyleSystemFont::Menu, systemFontName, fontStyle)) {
  if (!LookAndFeel::GetFont(StyleSystemFont::Menu, systemFontName, fontStyle)) {
    return;
    return;
  }
  }
+47 −1
Original line number Original line Diff line number Diff line
@@ -9678,6 +9678,50 @@ already_AddRefed<nsFontMetrics> nsLayoutUtils::GetMetricsFor(
  return aPresContext->GetMetricsFor(font, params);
  return aPresContext->GetMetricsFor(font, params);
}
}


static void GetSpoofedSystemFontForRFP(LookAndFeel::FontID aFontID,
                                       gfxFontStyle& aStyle, nsAString& aName) {
#if defined(XP_MACOSX)
  aName = u"-apple-system"_ns;
  // Values taken from a macOS 10.15 system.
  switch (aFontID) {
    case LookAndFeel::FontID::Caption:
    case LookAndFeel::FontID::Menu:
      aStyle.size = 13;
      break;
    case LookAndFeel::FontID::SmallCaption:
      aStyle.weight = gfxFontStyle::FontWeight::BOLD;
      // fall-through
    case LookAndFeel::FontID::MessageBox:
    case LookAndFeel::FontID::StatusBar:
      aStyle.size = 11;
      break;
    default:
      aStyle.size = 12;
      break;
  }
#elif defined(XP_WIN)
  // Windows uses Segoe UI for Latin alphabets, but other fonts for some RTL
  // languages, so we fallback to sans-serif to fall back to the user's
  // default sans-serif. Size is 12px for all system fonts (tried in an en-US
  // system).
  // Several Android systems reported Roboto 12px, so similar to what Windows
  // does.
  aName = u"sans-serif"_ns;
  aStyle.size = 12;
#elif !defined(MOZ_WIDGET_ANDROID)
  // On Linux, there is not a default. For example, GNOME on Debian uses
  // Cantarell, 14.667px. Ubuntu Mate uses the Ubuntu font, but also 14.667px.
  // Fedora with KDE uses Noto Sans, 13.3333px, but it uses Noto Sans on
  // GNOME, too.
  // In general, Linux uses some sans-serif, but its size can vary between
  // 12px and 16px. We chose 15px because it is what Firefox is doing for the
  // UI font-size.
  aName = u"sans-serif"_ns;
  aStyle.size = 15;
#endif
  // No need to do anything on Android, as font and sizes are already fixed.
}

/* static */
/* static */
void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
                                      LookAndFeel::FontID aFontID,
                                      LookAndFeel::FontID aFontID,
@@ -9685,7 +9729,9 @@ void nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont,
                                      const Document* aDocument) {
                                      const Document* aDocument) {
  gfxFontStyle fontStyle;
  gfxFontStyle fontStyle;
  nsAutoString systemFontName;
  nsAutoString systemFontName;
  if (!LookAndFeel::GetFont(aFontID, systemFontName, fontStyle)) {
  if (aDocument->ShouldResistFingerprinting(RFPTarget::Unknown)) {
    GetSpoofedSystemFontForRFP(aFontID, fontStyle, systemFontName);
  } else if (!LookAndFeel::GetFont(aFontID, systemFontName, fontStyle)) {
    return;
    return;
  }
  }
  systemFontName.Trim("\"'");
  systemFontName.Trim("\"'");