1/*
2 * Copyright (C) 2011 Adam Barth. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef XSSAuditor_h
27#define XSSAuditor_h
28
29#include "core/html/parser/HTMLToken.h"
30#include "platform/network/HTTPParsers.h"
31#include "platform/text/SuffixTree.h"
32#include "platform/weborigin/KURL.h"
33#include "wtf/PassOwnPtr.h"
34#include "wtf/text/TextEncoding.h"
35
36namespace blink {
37
38class Document;
39class HTMLDocumentParser;
40class HTMLSourceTracker;
41class XSSInfo;
42class XSSAuditorDelegate;
43
44struct FilterTokenRequest {
45    FilterTokenRequest(HTMLToken& token, HTMLSourceTracker& sourceTracker, bool shouldAllowCDATA)
46        : token(token)
47        , sourceTracker(sourceTracker)
48        , shouldAllowCDATA(shouldAllowCDATA)
49    { }
50
51    HTMLToken& token;
52    HTMLSourceTracker& sourceTracker;
53    bool shouldAllowCDATA;
54};
55
56class XSSAuditor {
57    WTF_MAKE_NONCOPYABLE(XSSAuditor);
58public:
59    XSSAuditor();
60
61    void init(Document*, XSSAuditorDelegate*);
62    void initForFragment();
63
64    PassOwnPtr<XSSInfo> filterToken(const FilterTokenRequest&);
65    bool isSafeToSendToAnotherThread() const;
66
67    void setEncoding(const WTF::TextEncoding&);
68
69private:
70    static const size_t kMaximumFragmentLengthTarget = 100;
71
72    enum State {
73        Uninitialized,
74        FilteringTokens,
75        PermittingAdjacentCharacterTokens,
76        SuppressingAdjacentCharacterTokens
77    };
78
79    enum TruncationKind {
80        NoTruncation,
81        NormalAttributeTruncation,
82        SrcLikeAttributeTruncation,
83        ScriptLikeAttributeTruncation
84    };
85
86    bool filterStartToken(const FilterTokenRequest&);
87    void filterEndToken(const FilterTokenRequest&);
88    bool filterCharacterToken(const FilterTokenRequest&);
89    bool filterScriptToken(const FilterTokenRequest&);
90    bool filterObjectToken(const FilterTokenRequest&);
91    bool filterParamToken(const FilterTokenRequest&);
92    bool filterEmbedToken(const FilterTokenRequest&);
93    bool filterAppletToken(const FilterTokenRequest&);
94    bool filterFrameToken(const FilterTokenRequest&);
95    bool filterMetaToken(const FilterTokenRequest&);
96    bool filterBaseToken(const FilterTokenRequest&);
97    bool filterFormToken(const FilterTokenRequest&);
98    bool filterInputToken(const FilterTokenRequest&);
99    bool filterButtonToken(const FilterTokenRequest&);
100
101    bool eraseDangerousAttributesIfInjected(const FilterTokenRequest&);
102    bool eraseAttributeIfInjected(const FilterTokenRequest&, const QualifiedName&, const String& replacementValue = String(), TruncationKind treatment = NormalAttributeTruncation);
103
104    String canonicalizedSnippetForTagName(const FilterTokenRequest&);
105    String canonicalizedSnippetForJavaScript(const FilterTokenRequest&);
106    String nameFromAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&);
107    String snippetFromAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&);
108    String canonicalize(String, TruncationKind);
109
110    bool isContainedInRequest(const String&);
111    bool isLikelySafeResource(const String& url);
112
113    KURL m_documentURL;
114    bool m_isEnabled;
115
116    ReflectedXSSDisposition m_xssProtection;
117    bool m_didSendValidCSPHeader;
118    bool m_didSendValidXSSProtectionHeader;
119
120    String m_decodedURL;
121    String m_decodedHTTPBody;
122    String m_httpBodyAsString;
123    OwnPtr<SuffixTree<ASCIICodebook> > m_decodedHTTPBodySuffixTree;
124
125    State m_state;
126    bool m_scriptTagFoundInRequest;
127    unsigned m_scriptTagNestingLevel;
128    WTF::TextEncoding m_encoding;
129};
130
131}
132
133#endif
134