⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286860 in webkit


Ignore:
Timestamp:
Dec 10, 2021, 11:00:44 AM (5 years ago)
Author:
Patrick Griffis
Message:

LayoutTests/imported/w3c:
CSP: Implement protections against nonce-hijacking
https://bugs.webkit.org/show_bug.cgi?id=233087

Reviewed by Brent Fulgham.

Update expectations.

  • web-platform-tests/content-security-policy/script-src/nonce-enforce-blocked-expected.txt:

Source/WebCore:
CSP: Prevent nonce-hijacking
https://bugs.webkit.org/show_bug.cgi?id=233087

Reviewed by Brent Fulgham.

Implement protections against nonce-hijacking as described in this spec:

https://www.w3.org/TR/CSP3/#security-nonce-hijacking

  • dom/Element.cpp:

(WebCore::Element::isNonceable const):
(WebCore::Element::nonce const):

  • dom/Element.h:

(WebCore::Element::hasDuplicateAttribute const):
(WebCore::Element::setHasDuplicateAttribute):

  • html/parser/AtomHTMLToken.h:

(WebCore::AtomHTMLToken::hasDuplicateAttribute const):
(WebCore::AtomHTMLToken::initializeAttributes):

  • html/parser/HTMLConstructionSite.cpp:

(WebCore::setAttributes):
(WebCore::HTMLConstructionSite::insertCustomElement):

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r286855 r286860  
     12021-12-10  Patrick Griffis  <pgriffis@igalia.com>
     2
     3        CSP: Implement protections against nonce-hijacking
     4        https://bugs.webkit.org/show_bug.cgi?id=233087
     5
     6        Reviewed by Brent Fulgham.
     7
     8        Update expectations.
     9
     10        * web-platform-tests/content-security-policy/script-src/nonce-enforce-blocked-expected.txt:
     11
    1122021-12-10  Chris Dumez  <cdumez@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/content-security-policy/script-src/nonce-enforce-blocked-expected.txt

    r246330 r286860  
    11
    2 FAIL Unnonced scripts generate reports. assert_unreached: '<script' attribute, no execution. Reached unreachable code
     2PASS Unnonced scripts generate reports.
    33
  • trunk/Source/WebCore/ChangeLog

    r286858 r286860  
     12021-12-10  Patrick Griffis  <pgriffis@igalia.com>
     2
     3        CSP: Prevent nonce-hijacking
     4        https://bugs.webkit.org/show_bug.cgi?id=233087
     5
     6        Reviewed by Brent Fulgham.
     7
     8        Implement protections against nonce-hijacking as described in this spec:
     9          https://www.w3.org/TR/CSP3/#security-nonce-hijacking
     10
     11        * dom/Element.cpp:
     12        (WebCore::Element::isNonceable const):
     13        (WebCore::Element::nonce const):
     14        * dom/Element.h:
     15        (WebCore::Element::hasDuplicateAttribute const):
     16        (WebCore::Element::setHasDuplicateAttribute):
     17        * html/parser/AtomHTMLToken.h:
     18        (WebCore::AtomHTMLToken::hasDuplicateAttribute const):
     19        (WebCore::AtomHTMLToken::initializeAttributes):
     20        * html/parser/HTMLConstructionSite.cpp:
     21        (WebCore::setAttributes):
     22        (WebCore::HTMLConstructionSite::insertCustomElement):
     23
    1242021-12-09  Darin Adler  <darin@apple.com>
    225
  • trunk/Source/WebCore/dom/Element.cpp

    r286776 r286860  
    7575#include "HTMLOptionElement.h"
    7676#include "HTMLParserIdioms.h"
     77#include "HTMLScriptElement.h"
    7778#include "HTMLSelectElement.h"
    7879#include "HTMLTemplateElement.h"
     
    110111#include "SVGNames.h"
    111112#include "SVGSVGElement.h"
     113#include "SVGScriptElement.h"
    112114#include "ScriptDisallowedScope.h"
    113115#include "ScrollIntoViewOptions.h"
     
    319321}
    320322
     323bool Element::isNonceable() const
     324{
     325    // https://www.w3.org/TR/CSP3/#is-element-nonceable
     326    if (elementRareData()->nonce().isNull())
     327        return false;
     328
     329    if (hasDuplicateAttribute())
     330        return false;
     331
     332    if (hasAttributes()
     333        && (is<HTMLScriptElement>(*this) || is<SVGScriptElement>(*this))) {
     334        static const char scriptString[] = "<script";
     335        static const char styleString[] = "<style";
     336
     337        for (const auto& attribute : attributesIterator()) {
     338            auto name = attribute.localName().convertToASCIILowercase();
     339            auto value = attribute.value().convertToASCIILowercase();
     340            if (name.contains(scriptString)
     341                || name.contains(styleString)
     342                || value.contains(scriptString)
     343                || value.contains(styleString))
     344                return false;
     345        }
     346    }
     347
     348    return true;
     349}
     350
    321351const AtomString& Element::nonce() const
    322352{
    323     return hasRareData() ? elementRareData()->nonce() : emptyAtom();
     353    if (hasRareData() && isNonceable())
     354        return elementRareData()->nonce();
     355
     356    return emptyAtom();
    324357}
    325358
  • trunk/Source/WebCore/dom/Element.h

    r286136 r286860  
    653653    String debugDescription() const override;
    654654
     655    bool hasDuplicateAttribute() const { return m_hasDuplicateAttribute; };
     656    void setHasDuplicateAttribute(bool hasDuplicateAttribute) { m_hasDuplicateAttribute = hasDuplicateAttribute; };
     657
    655658protected:
    656659    Element(const QualifiedName&, Document&, ConstructionType);
     
    688691    bool isUserActionElementHasFocusVisible() const;
    689692    bool isUserActionElementHasFocusWithin() const;
     693
     694    bool isNonceable() const;
    690695
    691696    virtual void didAddUserAgentShadowRoot(ShadowRoot&) { }
     
    766771    QualifiedName m_tagName;
    767772    RefPtr<ElementData> m_elementData;
     773
     774    bool m_hasDuplicateAttribute { false };
    768775};
    769776
  • trunk/Source/WebCore/html/parser/AtomHTMLToken.h

    r282142 r286860  
    3232namespace WebCore {
    3333
     34enum class HasDuplicateAttribute : bool { No, Yes };
     35
    3436class AtomHTMLToken {
    3537public:
     
    7072
    7173    const String& comment() const;
     74
     75    HasDuplicateAttribute hasDuplicateAttribute() const { return m_hasDuplicateAttribute; };
    7276
    7377private:
     
    9195    bool m_selfClosing; // StartTag, EndTag.
    9296    Vector<Attribute> m_attributes; // StartTag, EndTag.
     97
     98    HasDuplicateAttribute m_hasDuplicateAttribute { HasDuplicateAttribute::No };
    9399};
    94100
     
    209215        if (!hasAttribute(m_attributes, localName))
    210216            m_attributes.uncheckedAppend(Attribute(QualifiedName(nullAtom(), localName, nullAtom()), HTMLAtomStringCache::makeAttributeValue(attribute.value)));
     217        else
     218            m_hasDuplicateAttribute = HasDuplicateAttribute::Yes;
    211219    }
    212220}
  • trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp

    r286308 r286860  
    5656using namespace HTMLNames;
    5757
    58 static inline void setAttributes(Element& element, Vector<Attribute>& attributes, ParserContentPolicy parserContentPolicy)
     58static inline void setAttributes(Element& element, Vector<Attribute>& attributes, HasDuplicateAttribute hasDuplicateAttribute, ParserContentPolicy parserContentPolicy)
    5959{
    6060    if (!scriptingContentIsAllowed(parserContentPolicy))
    6161        element.stripScriptingAttributes(attributes);
    6262    element.parserSetAttributes(attributes);
     63    element.setHasDuplicateAttribute(hasDuplicateAttribute == HasDuplicateAttribute::Yes);
    6364}
    6465
    6566static inline void setAttributes(Element& element, AtomHTMLToken& token, ParserContentPolicy parserContentPolicy)
    6667{
    67     setAttributes(element, token.attributes(), parserContentPolicy);
     68    setAttributes(element, token.attributes(), token.hasDuplicateAttribute(), parserContentPolicy);
    6869}
    6970
     
    517518void HTMLConstructionSite::insertCustomElement(Ref<Element>&& element, const AtomString& localName, Vector<Attribute>&& attributes)
    518519{
    519     setAttributes(element, attributes, m_parserContentPolicy);
     520    setAttributes(element, attributes, HasDuplicateAttribute::No, m_parserContentPolicy);
    520521    attachLater(currentNode(), element.copyRef());
    521522    m_openElements.push(HTMLStackItem::create(WTFMove(element), localName, WTFMove(attributes)));
Note: See TracChangeset for help on using the changeset viewer.