[Webkit-unassigned] [Bug 26199] Implement a reflective XSS filter
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Sun Jun 14 12:29:52 PDT 2009
https://bugs.webkit.org/show_bug.cgi?id=26199
------- Comment #15 from sam at webkit.org 2009-06-14 12:29 PDT -------
(From update of attachment 31154)
> @@ -132,6 +133,9 @@ public:
> NPObject* createScriptObjectForPluginElement(HTMLPlugInElement*);
> NPObject* windowScriptNPObject();
> #endif
> +
> + // Returns the XSSAuditor associated with this ScriptController.
> + XSSAuditor* activeXSSAuditor() { return m_XSSAuditor.get(); }
Why activeXSSAuditor? Will there be more than one per scriptController in the
future?
>
> private:
> void initScriptIfNeeded()
> @@ -164,6 +168,9 @@ private:
> #if PLATFORM(MAC)
> RetainPtr<WebScriptObject> m_windowScriptObject;
> #endif
> +
> + // The XSSAuditor associated with this ScriptController.
> + OwnPtr<XSSAuditor> m_XSSAuditor;
Does the auditor have to be a pointer here?
>
> class Tokenizer {
> public:
> @@ -58,11 +59,19 @@ namespace WebCore {
> virtual void executeScriptsWaitingForStylesheets() {}
>
> virtual bool isHTMLTokenizer() const { return false; }
> +
> + // Returns the XSSAuditor associated with this tokenizer.
> + XSSAuditor* activeXSSAuditor() const { return m_XSSAuditor; }
> +
> + // Associates the specified XSSAuditor with this tokenizer.
> + // @param auditor the XSSAuditor to associate with this tokenizer.
We don't use @param syntax. In fact, neither of these comments are really
necessary as the code is self explanatory.
> + void setXSSAuditor(XSSAuditor* auditor) { m_XSSAuditor = auditor; }
>
> protected:
> Tokenizer(bool viewSourceMode = false)
> : m_parserStopped(false)
> , m_inViewSourceMode(viewSourceMode)
> + , m_XSSAuditor(0)
> {
> }
>
> +namespace WebCore {
> +
> +// This method also appears in file ResourceResponseBase.cpp.
> +static bool isControlCharacter(UChar c)
> +{
> + return c < ' ' || c == 127;
> +}
> +
> +XSSAuditor::XSSAuditor(Frame* frame)
> + : m_isEnabled(false)
> + , m_frame(frame)
> +{
> + if (Settings* settings = frame->settings())
> + m_isEnabled = settings->xssAuditorEnabled();
> +}
> +
> +XSSAuditor::~XSSAuditor()
> +{
> +}
> +
> +bool XSSAuditor::canEvaluate(const ScriptSourceCode& sourceCode) const
> +{
> + if (!m_isEnabled)
> + return true;
> +
> + return canEvaluate(String(sourceCode.jsSourceCode().data(), sourceCode.jsSourceCode().length()));
> +}
> +
> +bool XSSAuditor::canEvaluate(const String& sourceCode) const
> +{
> + if (!m_isEnabled)
> + return true;
> +
> + if (findInRequest(sourceCode)) {
> + String consoleMessage = "Refused to execute a JavaScript script. Source code of script found within request.\n";
The message should be a static.
> + m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, consoleMessage, 1, String());
> + return false;
> + }
> + return true;
> +}
> +
> +bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code) const
> +{
> + if (!m_isEnabled)
> + return true;
> +
> + return canEvaluate(code);
> +}
> +
> +bool XSSAuditor::canLoadExternalScriptFromSrc(const String& url) const
> +{
> + if (!m_isEnabled)
> + return true;
> +
> + if (findInRequest(url)) {
> + String consoleMessage = "Refused to execute a JavaScript script. Source code of script found within request.\n";
The message should be a static.
> + m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, consoleMessage, 1, String());
> + return false;
> + }
> + return true;
> +}
> +
> +bool XSSAuditor::canLoadObject(const String& url) const
> +{
> + if (!m_isEnabled)
> + return true;
> +
> + if (findInRequest(url)) {
> + String consoleMessage = "Refused to execute a JavaScript script. Source code of script found within request";
The message should be a static.
> + m_frame->domWindow()->console()->addMessage(OtherMessageSource, ErrorMessageLevel, consoleMessage, 1, String());
> + return false;
> + }
> + return true;
> +}
> +
> +// static
This comment is not necessary.
> +String XSSAuditor::decodeURL(const String& str, const TextEncoding& encoding, bool allowNullCharacters)
> +{
> + String result;
> + String url = str;
> +
> + url.replace('+', ' ');
> + result = decodeURLEscapeSequences(url, encoding);
> + return (allowNullCharacters)? result : result.removeCharacters(&isControlCharacter);
Missing space after (allowNullCharacters). The parens are not needed as well.
> + // The XSSAuditor class is used to prevent type 1 cross-site scripting
> + // vulnerabilites (also known as reflected vulnerabilities).
> + //
> + // More specifically, the XSSAuditor class decides whether the execution of
> + // a script is to be allowed or denied based on the content of any
> + // user-submitted data, including:
> + //
> + // * the query string of the URL.
> + // * the HTTP-POST data.
> + //
> + // If the source code of a script resembles any user-submitted data then it
> + // is denied execution.
> + //
> + // When you instantiate the XSSAuditor you must specify the {@link Frame}
> + // of the page that you wish to audit.
> + //
> + // Bindings
> + //
> + // An XSSAuditor is instantiated within the contructor of a
> + // ScriptController object and passed the Frame the script originated. The
> + // ScriptController calls back to the XSSAuditor to determine whether a
> + // JavaScript script is safe to execute before executing it. The following
> + // methods call into XSSAuditor:
> + //
> + // * ScriptController::evaluate - used to evaluate JavaScript scripts.
> + // * ScriptController::createInlineEventListener - used to create JavaScript event handlers.
> + // * HTMLTokenizer#scriptHandler - used to load external JavaScript scripts.
The use of # is inconsistent with the rest of the comment.
> + //
> + class XSSAuditor {
> + public:
> + // Creates a new XSSAuditor object that is associated with the specified frame.
> + // @param frame the frame to associate with this auditor.
We don't use @param syntax. In fact, this comment is not necessary.
Overall this looks great, but I want to defer r+ing this until we have some
performance analysis done on it, even it only in the disabled state. Sunspider
and some form of plt testing would be sufficient I think. Though I would also
like to see some targeted performance tests of the cases where the auditor will
be used.
--
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
More information about the webkit-unassigned
mailing list