{"record":{"id":"64ba6bb1e8ae5a7c","repo":"phacility/phabricator","slug":"monospaced-font-value-s-is-unsafe-you-may-only","errorCode":null,"errorMessage":"Monospaced font value \"%s\" is unsafe. You may only enter letters, numbers, spaces, commas, periods, hyphens, forward slashes, and double quotes","messagePattern":"Monospaced font value \"(.+?)\" is unsafe\\. You may only enter letters, numbers, spaces, commas, periods, hyphens, forward slashes, and double quotes","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"src/applications/settings/setting/PhabricatorMonospacedFontSetting.php","lineNumber":34,"sourceCode":"  protected function getSettingOrder() {\n    return 500;\n  }\n\n  protected function getControlInstructions() {\n    return pht(\n      'You can customize the font used when showing monospaced text, '.\n      'including source code. You should enter a valid CSS font declaration '.\n      'like: `13px Consolas`');\n  }\n\n  public function validateTransactionValue($value) {\n    if (!strlen($value)) {\n      return;\n    }\n\n    $filtered = self::filterMonospacedCSSRule($value);\n    if ($filtered !== $value) {\n      throw new Exception(\n        pht(\n          'Monospaced font value \"%s\" is unsafe. You may only enter '.\n          'letters, numbers, spaces, commas, periods, hyphens, '.\n          'forward slashes, and double quotes',\n          $value));\n    }\n  }\n\n  public static function filterMonospacedCSSRule($monospaced) {\n    // Prevent the user from doing dangerous things.\n    return preg_replace('([^a-z0-9 ,\"./-]+)i', '', $monospaced);\n  }\n\n}\n","sourceCodeStart":16,"sourceCodeEnd":49,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/settings/setting/PhabricatorMonospacedFontSetting.php#L16-L49","documentation":"The monospaced font preference accepts only a CSS font shorthand built from a whitelist: letters, digits, spaces, commas, periods, hyphens, forward slashes, and double quotes. filterMonospacedCSSRule() strips everything else, and validateTransactionValue() throws when the filtered result differs from the input - i.e. the submitted value contained disallowed characters. This blocks CSS injection through the settings panel.","triggerScenarios":"Saving Settings > Display > Monospaced Font with values containing single quotes ('13px \\'Courier New\\''), semicolons or colons ('font-family: Consolas;'), parentheses, braces, or url()/escape syntax - anything outside the whitelist.","commonSituations":"Pasting a full CSS rule instead of a font shorthand; single-quoting multiword font names out of habit; trying to smuggle in extra properties like font-weight or line-height via declarations.","solutions":["Submit only the font shorthand: size then family list, e.g. `13px \"Courier New\", monospace`","Use double quotes for multiword font names - single quotes are stripped and trigger the error","Remove property names, semicolons, colons, parentheses, and braces entirely"],"exampleFix":"// before\n13px 'Courier New'; font-weight: bold;\n\n// after\n13px \"Courier New\", monospace","handlingStrategy":"validation","validationCode":"// Mirror the server-side whitelist before saving\n$filtered = preg_replace('([^a-z0-9 ,\"./-]+)i', '', $value);\nif ($filtered !== $value) {\n  // reject client-side: value contains characters outside the allowed set\n}","typeGuard":"function isSafeMonospacedFontValue($v) {\n  if (!strlen($v)) { return true; } // empty = default, allowed\n  return preg_replace('([^a-z0-9 ,\"./-]+)i', '', $v) === $v;\n}","tryCatchPattern":"try {\n  // apply settings transaction\n} catch (Exception $ex) {\n  // sanitize or blank the font value, then resubmit\n}","preventionTips":["Enter only the font shorthand: size followed by family list","Use double quotes for multiword fonts; never single quotes","No property names, semicolons, colons, parentheses, or braces","Validate against the whitelist in the UI before POSTing"],"tags":["settings","css","sanitization","user-preferences"],"backgroundTag":"input-sanitization-rejected","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}