indexeddb: add recursion limit for idb key decoding
Bug: 1114430 Change-Id: I8379fe033e39ffc898e8799cd3c1e1e8e1743984 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2393188 Commit-Queue: enne <enne@chromium.org> Commit-Queue: Jeremy Roman <jbroman@chromium.org> Auto-Submit: enne <enne@chromium.org> Reviewed-by: Jeremy Roman <jbroman@chromium.org> Reviewed-by: Daniel Murphy <dmurph@chromium.org> Cr-Commit-Position: refs/heads/master@{#805089}
This commit is contained in:

committed by
Commit Bot

parent
73f1a5ff4c
commit
d46483a800
content/browser/indexed_db
third_party/blink
@ -359,10 +359,15 @@ bool DecodeBinary(StringPiece* slice, base::span<const uint8_t>* value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeIDBKey(StringPiece* slice, std::unique_ptr<IndexedDBKey>* value) {
|
||||
bool DecodeIDBKeyRecursive(StringPiece* slice,
|
||||
std::unique_ptr<IndexedDBKey>* value,
|
||||
size_t recursion) {
|
||||
if (slice->empty())
|
||||
return false;
|
||||
|
||||
if (recursion > IndexedDBKey::kMaximumDepth)
|
||||
return false;
|
||||
|
||||
unsigned char type = (*slice)[0];
|
||||
slice->remove_prefix(1);
|
||||
|
||||
@ -378,7 +383,7 @@ bool DecodeIDBKey(StringPiece* slice, std::unique_ptr<IndexedDBKey>* value) {
|
||||
IndexedDBKey::KeyArray array;
|
||||
while (length--) {
|
||||
std::unique_ptr<IndexedDBKey> key;
|
||||
if (!DecodeIDBKey(slice, &key))
|
||||
if (!DecodeIDBKeyRecursive(slice, &key, recursion + 1))
|
||||
return false;
|
||||
array.push_back(*key);
|
||||
}
|
||||
@ -425,6 +430,10 @@ bool DecodeIDBKey(StringPiece* slice, std::unique_ptr<IndexedDBKey>* value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DecodeIDBKey(StringPiece* slice, std::unique_ptr<IndexedDBKey>* value) {
|
||||
return DecodeIDBKeyRecursive(slice, value, 0);
|
||||
}
|
||||
|
||||
bool DecodeDouble(StringPiece* slice, double* value) {
|
||||
if (slice->size() < sizeof(*value))
|
||||
return false;
|
||||
|
@ -21,6 +21,11 @@ class BLINK_COMMON_EXPORT IndexedDBKey {
|
||||
public:
|
||||
typedef std::vector<IndexedDBKey> KeyArray;
|
||||
|
||||
// Non-standard limits, selected to avoid breaking real-world use of the API
|
||||
// while also preventing buggy (or malicious) code from causing crashes.
|
||||
static constexpr size_t kMaximumDepth = 2000;
|
||||
static constexpr size_t kMaximumArraySize = 1000000;
|
||||
|
||||
IndexedDBKey(); // Defaults to mojom::IDBKeyType::Invalid.
|
||||
explicit IndexedDBKey(mojom::IDBKeyType); // must be Null or Invalid
|
||||
explicit IndexedDBKey(KeyArray array);
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.h"
|
||||
|
||||
#include "third_party/blink/public/common/indexeddb/indexeddb_key.h"
|
||||
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
|
||||
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
|
||||
@ -167,11 +168,6 @@ v8::Local<v8::Value> ToV8(const IDBAny* impl,
|
||||
return v8::Undefined(isolate);
|
||||
}
|
||||
|
||||
// Non-standard limits, selected to avoid breaking real-world use of the API
|
||||
// while also preventing buggy (or malicious) code from causing crashes.
|
||||
const size_t kMaximumDepth = 2000;
|
||||
const size_t kMaximumArraySize = 1000000;
|
||||
|
||||
// Convert a simple (non-Array) script value to an Indexed DB key. If the
|
||||
// conversion fails due to a detached buffer, an exception is thrown. If
|
||||
// the value can't be converted into a key, an 'Invalid' key is returned. This
|
||||
@ -264,7 +260,7 @@ static std::unique_ptr<IDBKey> CreateIDBKeyFromValue(
|
||||
// Initial state.
|
||||
{
|
||||
v8::Local<v8::Array> array = value.As<v8::Array>();
|
||||
if (array->Length() > kMaximumArraySize)
|
||||
if (array->Length() > IndexedDBKey::kMaximumArraySize)
|
||||
return IDBKey::CreateInvalid();
|
||||
|
||||
stack.push_back(std::make_unique<Record>(array));
|
||||
@ -320,8 +316,8 @@ static std::unique_ptr<IDBKey> CreateIDBKeyFromValue(
|
||||
} else {
|
||||
// A sub-array; push onto the stack and start processing it.
|
||||
v8::Local<v8::Array> array = item.As<v8::Array>();
|
||||
if (seen.Contains(array) || stack.size() >= kMaximumDepth ||
|
||||
array->Length() > kMaximumArraySize) {
|
||||
if (seen.Contains(array) || stack.size() >= IndexedDBKey::kMaximumDepth ||
|
||||
array->Length() > IndexedDBKey::kMaximumArraySize) {
|
||||
return IDBKey::CreateInvalid();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user