[CSHARP-930] If any of the keys in a Dictionary contains a null character serialization fails Created: 13/Mar/14 Updated: 13/Apr/16 Resolved: 21/Mar/14 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Serialization |
| Affects Version/s: | 1.9 |
| Fix Version/s: | 1.9 |
| Type: | Bug | Priority: | Minor - P4 |
| Reporter: | Blake Niemyjski | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Windows |
||
| Backwards Compatibility: | Fully Compatible |
| Description |
|
I came across the following error when I tried to serialize one of our documents. We submit exception documents with our product. So the following document came from a security scan of some kind.. Anyways mongo blew up and we caught the exception. We have a few hundred reports of this. The value trying to be inserted is "\u0000\"><script>alert(309)</script>" System.ArgumentException : Element names cannot contain nulls. |
| Comments |
| Comment by Githook User [ 21/Mar/14 ] | ||||||
|
Author: {u'username': u'rstam', u'name': u'rstam', u'email': u'robert@10gen.com'}Message: | ||||||
| Comment by Blake Niemyjski [ 13/Mar/14 ] | ||||||
|
Thanks guys for the explanation. I'll add some checks to our code before inserting to try and detect null strings. If we could get a check added into the driver to change the representation automatically that would be sweet for others who are not expecting this behavior. | ||||||
| Comment by Robert Stam [ 13/Mar/14 ] | ||||||
|
In your case, the element names are coming from the representation chosen for the dictionary (property G of your class C). You can configure your POCO to use a different representation for dictionaries that will be safe even when some of the dictionary keys have nulls in them (and therefore aren't safe as element names);
The resulting JSON will look slightly different though... so this is a schema change for your application:
There arguably is a bug here though... and here's why: the default representation for a Dictionary<K,V> is Dynamic, which means that the serializer looks at the keys and determines whether the keys are safe to use as element names. If they are safe, then it uses the Document representation, otherwise it uses the ArrayOfArrays representation. The bug is that it isn't looking for nulls. If your dictionary has keys that are not valid BSON element names, I would recommend you go ahead and force the desired safe representation (ArrayOfArrays or ArrayOfDocuments). With Dynamic some of your dictionaries might be stored as nested documents, while others might be stored as arrays of key value pairs, depending on what the key values are. By explicitly choosing the representation yourself you get a consistent representation. It's also a bit faster at runtime since it no longer has to scan the key values to decide what representation to use. | ||||||
| Comment by Robert Stam [ 13/Mar/14 ] | ||||||
|
Nulls are only prohibited by the BSON spec in element names. They are fully supported in string values. If you suspect your string data might have the occasional null character then make sure you don't use those strings as element names, but instead design your schema so that they are values instead of element names. | ||||||
| Comment by Craig Wilson [ 13/Mar/14 ] | ||||||
|
Thanks for the test... MongoDB does not allow nulls inside element names as documented in the bsonspec. See the e_name and the corresponding documentation on a CSTRING. Since C# is a unicode language, C# is taking your string and converting \u0000 to null. In turn, the .NET driver takes a null and attempts to write it as UTF-8 null. This is what is happening in your test case. It might not be what is happening in your application. You can make the test pass by using a string literal in your test case (or escaping the first slash in your unicode string). Let me know if this makes sense or if you still think there is an issue. | ||||||
| Comment by Blake Niemyjski [ 13/Mar/14 ] | ||||||
|
I've added a pull request here with a breaking unit test: https://github.com/mongodb/mongo-csharp-driver/pull/178 |