Commit 5541d74f authored by mkwst@chromium.org's avatar mkwst@chromium.org

Define "opaque" FormData objects.

As defined at [1], opaque FormData objects block JavaScript access to
'get()', 'getAll()', 'has()', and iteration. The data is available
internally for consumption in Fetch, but can't be directly accessed by
JavaScript in a page's context.

[1]: https://w3c.github.io/webappsec/specs/credentialmanagement/#opaque-formdata

BUG=526995

Review URL: https://codereview.chromium.org/1323043002

git-svn-id: svn://svn.chromium.org/blink/trunk@201559 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent da0b52a6
...@@ -3797,6 +3797,7 @@ ...@@ -3797,6 +3797,7 @@
'frame/csp/CSPSourceListTest.cpp', 'frame/csp/CSPSourceListTest.cpp',
'frame/csp/CSPSourceTest.cpp', 'frame/csp/CSPSourceTest.cpp',
'frame/csp/ContentSecurityPolicyTest.cpp', 'frame/csp/ContentSecurityPolicyTest.cpp',
'html/DOMFormDataTest.cpp',
'html/HTMLDimensionTest.cpp', 'html/HTMLDimensionTest.cpp',
'html/HTMLFormControlElementTest.cpp', 'html/HTMLFormControlElementTest.cpp',
'html/HTMLImageElementTest.cpp', 'html/HTMLImageElementTest.cpp',
......
...@@ -77,11 +77,13 @@ private: ...@@ -77,11 +77,13 @@ private:
DOMFormData::DOMFormData(const WTF::TextEncoding& encoding) DOMFormData::DOMFormData(const WTF::TextEncoding& encoding)
: FormDataList(encoding) : FormDataList(encoding)
, m_opaque(false)
{ {
} }
DOMFormData::DOMFormData(HTMLFormElement* form) DOMFormData::DOMFormData(HTMLFormElement* form)
: FormDataList(UTF8Encoding()) : FormDataList(UTF8Encoding())
, m_opaque(false)
{ {
if (!form) if (!form)
return; return;
...@@ -120,6 +122,8 @@ void DOMFormData::append(ExecutionContext* context, const String& name, Blob* bl ...@@ -120,6 +122,8 @@ void DOMFormData::append(ExecutionContext* context, const String& name, Blob* bl
void DOMFormData::get(const String& name, FormDataEntryValue& result) void DOMFormData::get(const String& name, FormDataEntryValue& result)
{ {
if (m_opaque)
return;
Entry entry = getEntry(name); Entry entry = getEntry(name);
if (entry.isString()) if (entry.isString())
result.setUSVString(entry.string()); result.setUSVString(entry.string());
...@@ -132,6 +136,10 @@ void DOMFormData::get(const String& name, FormDataEntryValue& result) ...@@ -132,6 +136,10 @@ void DOMFormData::get(const String& name, FormDataEntryValue& result)
HeapVector<FormDataEntryValue> DOMFormData::getAll(const String& name) HeapVector<FormDataEntryValue> DOMFormData::getAll(const String& name)
{ {
HeapVector<FormDataEntryValue> results; HeapVector<FormDataEntryValue> results;
if (m_opaque)
return results;
HeapVector<FormDataList::Entry> entries = FormDataList::getAll(name); HeapVector<FormDataList::Entry> entries = FormDataList::getAll(name);
for (const FormDataList::Entry& entry : entries) { for (const FormDataList::Entry& entry : entries) {
ASSERT(entry.name() == name); ASSERT(entry.name() == name);
...@@ -148,6 +156,13 @@ HeapVector<FormDataEntryValue> DOMFormData::getAll(const String& name) ...@@ -148,6 +156,13 @@ HeapVector<FormDataEntryValue> DOMFormData::getAll(const String& name)
return results; return results;
} }
bool DOMFormData::has(const String& name)
{
if (m_opaque)
return false;
return hasEntry(name);
}
void DOMFormData::set(const String& name, const String& value) void DOMFormData::set(const String& name, const String& value)
{ {
setData(name, value); setData(name, value);
...@@ -160,6 +175,9 @@ void DOMFormData::set(const String& name, Blob* blob, const String& filename) ...@@ -160,6 +175,9 @@ void DOMFormData::set(const String& name, Blob* blob, const String& filename)
PairIterable<String, FormDataEntryValue>::IterationSource* DOMFormData::startIteration(ScriptState*, ExceptionState&) PairIterable<String, FormDataEntryValue>::IterationSource* DOMFormData::startIteration(ScriptState*, ExceptionState&)
{ {
if (m_opaque)
return new DOMFormDataIterationSource(new DOMFormData(nullptr));
return new DOMFormDataIterationSource(this); return new DOMFormDataIterationSource(this);
} }
......
...@@ -70,14 +70,18 @@ public: ...@@ -70,14 +70,18 @@ public:
void append(ExecutionContext*, const String& name, Blob*, const String& filename = String()); void append(ExecutionContext*, const String& name, Blob*, const String& filename = String());
void get(const String& name, FormDataEntryValue& result); void get(const String& name, FormDataEntryValue& result);
HeapVector<FormDataEntryValue> getAll(const String& name); HeapVector<FormDataEntryValue> getAll(const String& name);
bool has(const String& name);
void set(const String& name, const String& value); void set(const String& name, const String& value);
void set(const String& name, Blob*, const String& filename = String()); void set(const String& name, Blob*, const String& filename = String());
void makeOpaque() { m_opaque = true; }
private: private:
explicit DOMFormData(const WTF::TextEncoding&); explicit DOMFormData(const WTF::TextEncoding&);
explicit DOMFormData(HTMLFormElement*); explicit DOMFormData(HTMLFormElement*);
IterationSource* startIteration(ScriptState*, ExceptionState&) override; IterationSource* startIteration(ScriptState*, ExceptionState&) override;
bool m_opaque;
}; };
} // namespace blink } // namespace blink
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/html/DOMFormData.h"
#include "core/html/FormDataList.h"
#include <gtest/gtest.h>
namespace blink {
TEST(DOMFormDataTest, opacityGet)
{
DOMFormData* fd = DOMFormData::create(UTF8Encoding());
fd->append("name1", "value1");
FileOrUSVString result;
fd->get("name1", result);
EXPECT_TRUE(result.isUSVString());
EXPECT_EQ("value1", result.getAsUSVString());
FormDataList::Entry entry = fd->getEntry("name1");
EXPECT_EQ("value1", entry.string());
fd->makeOpaque();
// Web-exposed interface should be opaque.
FileOrUSVString opaqueResult;
fd->get("name1", opaqueResult);
EXPECT_TRUE(opaqueResult.isNull());
// Internal interface should be uneffected.
FormDataList::Entry opaqueEntry = fd->getEntry("name1");
EXPECT_EQ("value1", opaqueEntry.string());
}
TEST(DOMFormDataTest, opacityGetAll)
{
DOMFormData* fd = DOMFormData::create(UTF8Encoding());
fd->append("name1", "value1");
HeapVector<FormDataEntryValue> results = fd->getAll("name1");
EXPECT_EQ(1u, results.size());
EXPECT_TRUE(results[0].isUSVString());
EXPECT_EQ("value1", results[0].getAsUSVString());
EXPECT_EQ(1u, fd->size());
fd->makeOpaque();
// Web-exposed interface should be opaque.
results = fd->getAll("name1");
EXPECT_EQ(0u, results.size());
// Internal interface should be uneffected.
EXPECT_EQ(1u, fd->size());
}
TEST(DOMFormDataTest, opacityHas)
{
DOMFormData* fd = DOMFormData::create(UTF8Encoding());
fd->append("name1", "value1");
EXPECT_TRUE(fd->has("name1"));
EXPECT_TRUE(fd->hasEntry("name1"));
fd->makeOpaque();
// Web-exposed interface should be opaque.
EXPECT_FALSE(fd->has("name1"));
// Internal interface should be uneffected.
EXPECT_TRUE(fd->hasEntry("name1"));
}
} // namespace blink
...@@ -47,7 +47,7 @@ typedef (File or USVString) FormDataEntryValue; ...@@ -47,7 +47,7 @@ typedef (File or USVString) FormDataEntryValue;
[RuntimeEnabled=FormDataNewMethods, ImplementedAs=deleteEntry] void delete(USVString name); [RuntimeEnabled=FormDataNewMethods, ImplementedAs=deleteEntry] void delete(USVString name);
[RuntimeEnabled=FormDataNewMethods] FormDataEntryValue? get(USVString name); [RuntimeEnabled=FormDataNewMethods] FormDataEntryValue? get(USVString name);
[RuntimeEnabled=FormDataNewMethods] sequence<FormDataEntryValue> getAll(USVString name); [RuntimeEnabled=FormDataNewMethods] sequence<FormDataEntryValue> getAll(USVString name);
[RuntimeEnabled=FormDataNewMethods, ImplementedAs=hasEntry] boolean has(USVString name); [RuntimeEnabled=FormDataNewMethods] boolean has(USVString name);
// TODO(philipj): The value argument should be FormDataEntryValue and there // TODO(philipj): The value argument should be FormDataEntryValue and there
// should be no optional filename argument. // should be no optional filename argument.
[RuntimeEnabled=FormDataNewMethods] void set(USVString name, Blob value, optional USVString filename); [RuntimeEnabled=FormDataNewMethods] void set(USVString name, Blob value, optional USVString filename);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment