Bug 1360694 - [Form Autofill] Cap the length of profile fields saved in storage. r=ralin draft
authorLuke Chang <lchang@mozilla.com>
Thu, 19 Oct 2017 12:06:40 +0800
changeset 683072 d61b5d954fd7dfbeb470ab4175faa90f2c26941b
parent 682993 a21099ce055f983cd642732d49148d3bfaa2d686
child 736522 f8a1fd3e506592e7f38fc68e78267cffa5003c0c
push id85243
push userbmo:lchang@mozilla.com
push dateThu, 19 Oct 2017 06:31:53 +0000
reviewersralin
bugs1360694
milestone58.0a1
Bug 1360694 - [Form Autofill] Cap the length of profile fields saved in storage. r=ralin MozReview-Commit-ID: I9x0tnGEt1Y
browser/extensions/formautofill/FormAutofillHandler.jsm
browser/extensions/formautofill/FormAutofillUtils.jsm
browser/extensions/formautofill/test/unit/test_createRecords.js
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -666,17 +666,17 @@ FormAutofillHandler.prototype = {
             data[type].record[detail.fieldName] = "";
             return;
           }
 
           let text = element.selectedOptions[0].text.trim();
           value = FormAutofillUtils.getAbbreviatedStateName([value, text]) || text;
         }
 
-        if (!value) {
+        if (!value || value.length > FormAutofillUtils.MAX_FIELD_VALUE_LENGTH) {
           // Keep the property and preserve more information for updating
           data[type].record[detail.fieldName] = "";
           return;
         }
 
         data[type].record[detail.fieldName] = value;
 
         if (detail.state == "AUTO_FILLED") {
@@ -684,18 +684,18 @@ FormAutofillHandler.prototype = {
         }
       });
     });
 
     this._normalizeAddress(data.address);
 
     if (data.address && !this._isAddressRecordCreatable(data.address.record)) {
       log.debug("No address record saving since there are only",
-                     Object.keys(data.address.record).length,
-                     "usable fields");
+                Object.keys(data.address.record).length,
+                "usable fields");
       delete data.address;
     }
 
     if (data.creditCard && !this._isCreditCardRecordCreatable(data.creditCard.record)) {
       log.debug("No credit card record saving since card number is invalid");
       delete data.creditCard;
     }
 
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -24,32 +24,37 @@ const ENABLED_AUTOFILL_CREDITCARDS_PREF 
 const MANAGE_ADDRESSES_KEYWORDS = ["manageAddressesTitle", "addNewAddressTitle"];
 const EDIT_ADDRESS_KEYWORDS = [
   "givenName", "additionalName", "familyName", "organization", "streetAddress",
   "state", "province", "city", "country", "zip", "postalCode", "email", "tel",
 ];
 const MANAGE_CREDITCARDS_KEYWORDS = ["manageCreditCardsTitle", "addNewCreditCardTitle", "showCreditCardsBtnLabel"];
 const EDIT_CREDITCARD_KEYWORDS = ["cardNumber", "nameOnCard", "cardExpires"];
 
+// The maximum length of data to be saved in a single field for preventing DoS
+// attacks that fill the user's hard drive(s).
+const MAX_FIELD_VALUE_LENGTH = 200;
+
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 this.FormAutofillUtils = {
   get AUTOFILL_FIELDS_THRESHOLD() { return 3; },
   get isAutofillEnabled() { return this.isAutofillAddressesEnabled || this.isAutofillCreditCardsEnabled; },
   get isAutofillCreditCardsEnabled() { return this.isAutofillCreditCardsAvailable && this._isAutofillCreditCardsEnabled; },
 
   ADDRESSES_COLLECTION_NAME,
   CREDITCARDS_COLLECTION_NAME,
   ENABLED_AUTOFILL_ADDRESSES_PREF,
   ENABLED_AUTOFILL_CREDITCARDS_PREF,
   MANAGE_ADDRESSES_KEYWORDS,
   EDIT_ADDRESS_KEYWORDS,
   MANAGE_CREDITCARDS_KEYWORDS,
   EDIT_CREDITCARD_KEYWORDS,
+  MAX_FIELD_VALUE_LENGTH,
 
   _fieldNameInfo: {
     "name": "name",
     "given-name": "name",
     "additional-name": "name",
     "family-name": "name",
     "organization": "organization",
     "street-address": "address",
--- a/browser/extensions/formautofill/test/unit/test_createRecords.js
+++ b/browser/extensions/formautofill/test/unit/test_createRecords.js
@@ -3,25 +3,56 @@
  */
 
 "use strict";
 
 Cu.import("resource://formautofill/FormAutofillHandler.jsm");
 
 const TESTCASES = [
   {
+    description: "Don't contain a field whose length of value is greater than 200",
+    document: `<form>
+                <input id="given-name" autocomplete="given-name">
+                <input id="organization" autocomplete="organization">
+                <input id="address-level1" autocomplete="address-level1">
+                <input id="country" autocomplete="country">
+                <input id="cc-number" autocomplete="cc-number">
+                <input id="cc-name" autocomplete="cc-name">
+               </form>`,
+    formValue: {
+      "given-name": "John",
+      "organization": "*".repeat(200),
+      "address-level1": "*".repeat(201),
+      "country": "US",
+      "cc-number": "1111222233334444",
+      "cc-name": "*".repeat(201),
+    },
+    expectedRecord: {
+      address: {
+        "given-name": "John",
+        "organization": "*".repeat(200),
+        "address-level1": "",
+        "country": "US",
+      },
+      creditCard: {
+        "cc-number": "1111222233334444",
+        "cc-name": "",
+      },
+    },
+  },
+  {
     description: "Don't create address record if filled data is less than 3",
     document: `<form>
                 <input id="given-name" autocomplete="given-name">
-                <input id="family-name" autocomplete="family-name">
+                <input id="organization" autocomplete="organization">
                 <input id="country" autocomplete="country">
                </form>`,
     formValue: {
       "given-name": "John",
-      "family-name": "Doe",
+      "organization": "Mozilla",
     },
     expectedRecord: {
       address: undefined,
     },
   },
   {
     description: "\"country\" using @autocomplete shouldn't be identified aggressively",
     document: `<form>