Changeset 85388 in webkit


Ignore:
Timestamp:
Apr 29, 2011 9:30:03 PM (13 years ago)
Author:
abarth@webkit.org
Message:

2011-04-29 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

CSP script-src should block eval
https://bugs.webkit.org/show_bug.cgi?id=59850

Test that both function-eval and operator-eval are correctly blocked
and allowed according to the policy.

  • http/tests/security/contentSecurityPolicy/eval-allowed-expected.txt: Added.
  • http/tests/security/contentSecurityPolicy/eval-allowed.html: Added.
  • http/tests/security/contentSecurityPolicy/eval-blocked-expected.txt: Added.
  • http/tests/security/contentSecurityPolicy/eval-blocked.html: Added.

2011-04-29 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

CSP script-src should block eval
https://bugs.webkit.org/show_bug.cgi?id=59850

ggaren recommend a different approach to this patch, essentially
installing a new function for function-eval and changing the AST
representation of operator-eval to call function-eval. However, I'm
not sure that approach is workable because the ASTBuilder doesn't know
about global objects, and there is added complication due to the cache.

This approach is more dynamic, adding a branch in EvalExecutable to
detect whether eval is current disabled in the lexical scope. The spec
is slightly unclear about whether we should return undefined or throw
an exception. I've asked Brandon to clarify the spec, but throwing an
exception seems natural.

  • JavaScriptCore.exp:
  • runtime/Executable.cpp: (JSC::EvalExecutable::compileInternal):
  • runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::disableEval):
  • runtime/JSGlobalObject.h: (JSC::JSGlobalObject::JSGlobalObject): (JSC::JSGlobalObject::isEvalEnabled):

2011-04-29 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

CSP script-src should block eval
https://bugs.webkit.org/show_bug.cgi?id=59850

Rather than have JavaScriptCore call back into WebCore to learn whether
eval is enabled, we push that bit of the policy into JavaScriptCore.

Tests: http/tests/security/contentSecurityPolicy/eval-allowed.html

http/tests/security/contentSecurityPolicy/eval-blocked.html

  • bindings/js/ScriptController.cpp: (WebCore::ScriptController::disableEval):
  • bindings/js/ScriptController.h:
  • page/ContentSecurityPolicy.cpp: (WebCore::ContentSecurityPolicy::didReceiveHeader): (WebCore::ContentSecurityPolicy::internalAllowEval): (WebCore::ContentSecurityPolicy::allowEval):
  • page/ContentSecurityPolicy.h:
Location:
trunk
Files:
4 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r85387 r85388  
     12011-04-29  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        CSP script-src should block eval
     6        https://bugs.webkit.org/show_bug.cgi?id=59850
     7
     8        Test that both function-eval and operator-eval are correctly blocked
     9        and allowed according to the policy.
     10
     11        * http/tests/security/contentSecurityPolicy/eval-allowed-expected.txt: Added.
     12        * http/tests/security/contentSecurityPolicy/eval-allowed.html: Added.
     13        * http/tests/security/contentSecurityPolicy/eval-blocked-expected.txt: Added.
     14        * http/tests/security/contentSecurityPolicy/eval-blocked.html: Added.
     15
    1162011-04-29  Joseph Pecoraro  <joepeck@webkit.org>
    217
  • trunk/LayoutTests/platform/chromium/test_expectations.txt

    r85367 r85388  
    32133213// This test is very flaky on Mac and a little flaky on Win and Linux.
    32143214BUGXXX : media/video-delay-load-event.html = PASS TEXT
     3215
     3216// We need help from V8 to implement this feature.
     3217// http://code.google.com/p/v8/issues/detail?id=1258
     3218BUGV8: http/tests/security/contentSecurityPolicy/eval-blocked.html = TEXT
    32153219
    32163220// These tests appears to timeout every 10 or 20 runs.
  • trunk/Source/JavaScriptCore/ChangeLog

    r85372 r85388  
     12011-04-29  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        CSP script-src should block eval
     6        https://bugs.webkit.org/show_bug.cgi?id=59850
     7
     8        ggaren recommend a different approach to this patch, essentially
     9        installing a new function for function-eval and changing the AST
     10        representation of operator-eval to call function-eval.  However, I'm
     11        not sure that approach is workable because the ASTBuilder doesn't know
     12        about global objects, and there is added complication due to the cache.
     13
     14        This approach is more dynamic, adding a branch in EvalExecutable to
     15        detect whether eval is current disabled in the lexical scope.  The spec
     16        is slightly unclear about whether we should return undefined or throw
     17        an exception.  I've asked Brandon to clarify the spec, but throwing an
     18        exception seems natural.
     19
     20        * JavaScriptCore.exp:
     21        * runtime/Executable.cpp:
     22        (JSC::EvalExecutable::compileInternal):
     23        * runtime/JSGlobalObject.cpp:
     24        (JSC::JSGlobalObject::disableEval):
     25        * runtime/JSGlobalObject.h:
     26        (JSC::JSGlobalObject::JSGlobalObject):
     27        (JSC::JSGlobalObject::isEvalEnabled):
     28
    1292011-04-29  Gavin Barraclough  <barraclough@apple.com>
    230
  • trunk/Source/JavaScriptCore/JavaScriptCore.exp

    r85117 r85388  
    156156__ZN3JSC13StatementNode6setLocEii
    157157__ZN3JSC14JSGlobalObject10globalExecEv
     158__ZN3JSC14JSGlobalObject11disableEvalEv
    158159__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
    159160__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r84860 r85388  
    103103    JSGlobalData* globalData = &exec->globalData();
    104104    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
     105    if (!lexicalGlobalObject->isEvalEnabled())
     106        return throwError(exec, createEvalError(exec, "Eval is disabled"));
    105107    RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
    106108    if (!evalNode) {
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r84679 r85388  
    377377}
    378378
     379void JSGlobalObject::disableEval()
     380{
     381    ASSERT(m_isEvalEnabled);
     382    m_isEvalEnabled = false;
     383}
     384
    379385void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile)
    380386{
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r84679 r85388  
    113113        SymbolTable m_symbolTable;
    114114
     115        bool m_isEvalEnabled;
     116
    115117    public:
    116118        void* operator new(size_t, JSGlobalData*);
     
    121123            , m_globalScopeChain()
    122124            , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
     125            , m_isEvalEnabled(true)
    123126        {
    124127            COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
     
    132135            , m_globalScopeChain()
    133136            , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
     137            , m_isEvalEnabled(true)
    134138        {
    135139            COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
     
    144148            , m_globalScopeChain()
    145149            , m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
     150            , m_isEvalEnabled(true)
    146151        {
    147152            COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
     
    234239        virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
    235240
     241        void disableEval();
     242        bool isEvalEnabled() { return m_isEvalEnabled; }
     243
    236244        void copyGlobalsFrom(RegisterFile&);
    237245        void copyGlobalsTo(RegisterFile&);
  • trunk/Source/WebCore/ChangeLog

    r85385 r85388  
     12011-04-29  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        CSP script-src should block eval
     6        https://bugs.webkit.org/show_bug.cgi?id=59850
     7
     8        Rather than have JavaScriptCore call back into WebCore to learn whether
     9        eval is enabled, we push that bit of the policy into JavaScriptCore.
     10
     11        Tests: http/tests/security/contentSecurityPolicy/eval-allowed.html
     12               http/tests/security/contentSecurityPolicy/eval-blocked.html
     13
     14        * bindings/js/ScriptController.cpp:
     15        (WebCore::ScriptController::disableEval):
     16        * bindings/js/ScriptController.h:
     17        * page/ContentSecurityPolicy.cpp:
     18        (WebCore::ContentSecurityPolicy::didReceiveHeader):
     19        (WebCore::ContentSecurityPolicy::internalAllowEval):
     20        (WebCore::ContentSecurityPolicy::allowEval):
     21        * page/ContentSecurityPolicy.h:
     22
    1232011-04-29  Joseph Pecoraro  <joepeck@webkit.org>
    224
  • trunk/Source/WebCore/bindings/js/ScriptController.cpp

    r83385 r85388  
    238238}
    239239
     240void ScriptController::disableEval()
     241{
     242    windowShell(mainThreadNormalWorld())->window()->disableEval();
     243}
     244
    240245bool ScriptController::processingUserGesture()
    241246{
  • trunk/Source/WebCore/bindings/js/ScriptController.h

    r83385 r85388  
    108108
    109109    int eventHandlerLineNumber() const;
    110    
     110
     111    void disableEval();
     112
    111113    void setProcessingTimerCallback(bool b) { m_processingTimerCallback = b; }
    112114    static bool processingUserGesture();
  • trunk/Source/WebCore/bindings/v8/ScriptController.cpp

    r84890 r85388  
    306306}
    307307
     308void ScriptController::disableEval()
     309{
     310    // FIXME: We need help from V8 to implement this function:
     311    // http://code.google.com/p/v8/issues/detail?id=1258
     312}
     313
    308314PassScriptInstance ScriptController::createScriptInstanceForWidget(Widget* widget)
    309315{
  • trunk/Source/WebCore/bindings/v8/ScriptController.h

    r77755 r85388  
    119119    bool haveInterpreter() const;
    120120
     121    void disableEval();
     122
    121123    static bool canAccessFromCurrentOrigin(Frame*);
    122124
  • trunk/Source/WebCore/page/ContentSecurityPolicy.cpp

    r85381 r85388  
    470470    parse(header);
    471471    m_havePolicy = true;
     472
     473    if (!internalAllowEval()) {
     474        if (Frame* frame = m_document->frame())
     475            frame->script()->disableEval();
     476    }
    472477}
    473478
     
    544549}
    545550
     551bool ContentSecurityPolicy::internalAllowEval() const
     552{
     553    return !m_scriptSrc || m_scriptSrc->allowEval();
     554}
     555
    546556bool ContentSecurityPolicy::allowEval() const
    547557{
    548     if (!m_scriptSrc || m_scriptSrc->allowEval())
     558    if (internalAllowEval())
    549559        return true;
    550560
  • trunk/Source/WebCore/page/ContentSecurityPolicy.h

    r85381 r85388  
    7171
    7272    void reportViolation(const String& directiveText, const String& consoleMessage) const;
     73    bool internalAllowEval() const;
    7374
    7475    bool m_havePolicy;
Note: See TracChangeset for help on using the changeset viewer.