Changeset 77041 in webkit
- Timestamp:
- Jan 28, 2011 6:08:44 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r77034 r77041 1 2011-01-28 Adam Barth <abarth@webkit.org> 2 3 Reviewed by Eric Seidel. 4 5 XSSFilter should log to the console when it blocks something 6 https://bugs.webkit.org/show_bug.cgi?id=53354 7 8 This patch refactors a bunch of methods in XSSFilter to return a bool 9 indicating whether they blocked anything. Using this bool, we decide 10 whether to log to the console. We're using the same log message as the 11 XSSAuditor, but it seems likely we can improve this message in the 12 future (especially by piping in the correct line number, which is now 13 accessible via the parser). 14 15 * html/parser/XSSFilter.cpp: 16 (WebCore::HTMLNames::isNameOfInlineEventHandler): 17 (WebCore::XSSFilter::filterToken): 18 (WebCore::XSSFilter::filterTokenInitial): 19 (WebCore::XSSFilter::filterTokenAfterScriptStartTag): 20 (WebCore::XSSFilter::filterScriptToken): 21 (WebCore::XSSFilter::filterObjectToken): 22 (WebCore::XSSFilter::filterEmbedToken): 23 (WebCore::XSSFilter::filterAppletToken): 24 (WebCore::XSSFilter::filterMetaToken): 25 (WebCore::XSSFilter::filterBaseToken): 26 (WebCore::XSSFilter::eraseInlineEventHandlersIfInjected): 27 * html/parser/XSSFilter.h: 28 1 29 2011-01-28 Adam Barth <abarth@webkit.org> 2 30 -
trunk/Source/WebCore/html/parser/XSSFilter.cpp
r77034 r77041 61 61 } 62 62 63 bool isNameOf ScriptCarryingAttribute(const Vector<UChar, 32>& name)64 { 65 const size_t lengthOfShortest ScriptCarryingAttribute = 5; // To wit: oncut.66 if (name.size() < lengthOfShortest ScriptCarryingAttribute)63 bool isNameOfInlineEventHandler(const Vector<UChar, 32>& name) 64 { 65 const size_t lengthOfShortestInlineEventHandlerName = 5; // To wit: oncut. 66 if (name.size() < lengthOfShortestInlineEventHandlerName) 67 67 return false; 68 68 return name[0] == 'o' && name[1] == 'n'; … … 105 105 return; 106 106 107 bool didBlockScript = false; 108 107 109 switch (m_state) { 108 110 case Initial: 111 didBlockScript = filterTokenInitial(token); 109 112 break; 110 113 case AfterScriptStartTag: 111 filterTokenAfterScriptStartTag(token);114 didBlockScript = filterTokenAfterScriptStartTag(token); 112 115 ASSERT(m_state == Initial); 113 116 m_cachedSnippet = String(); 114 return; 115 } 117 break; 118 } 119 120 if (didBlockScript) { 121 // FIXME: Consider using a more helpful console message. 122 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); 123 // FIXME: We should add the real line number to the console. 124 m_parser->document()->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); 125 } 126 #endif 127 } 128 129 bool XSSFilter::filterTokenInitial(HTMLToken& token) 130 { 131 ASSERT(m_state == Initial); 116 132 117 133 if (token.type() != HTMLToken::StartTag) 118 return; 134 return false; 135 136 bool didBlockScript = eraseInlineEventHandlersIfInjected(token); 119 137 120 138 if (hasName(token, scriptTag)) 121 return filterScriptToken(token); 122 123 if (hasName(token, objectTag)) 124 return filterObjectToken(token); 125 126 if (hasName(token, embedTag)) 127 return filterEmbedToken(token); 128 129 if (hasName(token, appletTag)) 130 return filterAppletToken(token); 131 132 if (hasName(token, metaTag)) 133 return filterMetaToken(token); 134 135 if (hasName(token, baseTag)) 136 return filterBaseToken(token); 137 138 for (size_t i = 0; i < token.attributes().size(); ++i) { 139 const HTMLToken::Attribute& attribute = token.attributes().at(i); 140 if (!isNameOfScriptCarryingAttribute(attribute.m_name)) 141 continue; 142 if (!isContainedInRequest(snippetForAttribute(token, attribute))) 143 continue; 144 token.eraseValueOfAttribute(i); 145 } 146 #endif 147 } 148 149 void XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token) 139 didBlockScript |= filterScriptToken(token); 140 else if (hasName(token, objectTag)) 141 didBlockScript |= filterObjectToken(token); 142 else if (hasName(token, embedTag)) 143 didBlockScript |= filterEmbedToken(token); 144 else if (hasName(token, appletTag)) 145 didBlockScript |= filterAppletToken(token); 146 else if (hasName(token, metaTag)) 147 didBlockScript |= filterMetaToken(token); 148 else if (hasName(token, baseTag)) 149 didBlockScript |= filterBaseToken(token); 150 151 return didBlockScript; 152 } 153 154 bool XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token) 150 155 { 151 156 ASSERT(m_state == AfterScriptStartTag); … … 154 159 if (token.type() != HTMLToken::Character) { 155 160 ASSERT(token.type() == HTMLToken::EndTag || token.type() == HTMLToken::EndOfFile); 156 return ;161 return false; 157 162 } 158 163 … … 164 169 token.eraseCharacters(); 165 170 token.appendToCharacter(' '); // Technically, character tokens can't be empty. 166 } 167 } 168 169 void XSSFilter::filterScriptToken(HTMLToken& token) 171 return true; 172 } 173 return false; 174 } 175 176 bool XSSFilter::filterScriptToken(HTMLToken& token) 170 177 { 171 178 ASSERT(m_state == Initial); … … 174 181 175 182 if (eraseAttributeIfInjected(token, srcAttr)) 176 return ;183 return true; 177 184 178 185 m_state = AfterScriptStartTag; 179 186 m_cachedSnippet = m_parser->sourceForToken(token); 180 } 181 182 void XSSFilter::filterObjectToken(HTMLToken& token) 187 return false; 188 } 189 190 bool XSSFilter::filterObjectToken(HTMLToken& token) 183 191 { 184 192 ASSERT(m_state == Initial); … … 186 194 ASSERT(hasName(token, objectTag)); 187 195 188 eraseAttributeIfInjected(token, dataAttr); 189 eraseAttributeIfInjected(token, typeAttr); 190 eraseAttributeIfInjected(token, classidAttr); 191 } 192 193 void XSSFilter::filterEmbedToken(HTMLToken& token) 196 bool didBlockScript = false; 197 198 didBlockScript |= eraseAttributeIfInjected(token, dataAttr); 199 didBlockScript |= eraseAttributeIfInjected(token, typeAttr); 200 didBlockScript |= eraseAttributeIfInjected(token, classidAttr); 201 202 return didBlockScript; 203 } 204 205 bool XSSFilter::filterEmbedToken(HTMLToken& token) 194 206 { 195 207 ASSERT(m_state == Initial); … … 197 209 ASSERT(hasName(token, embedTag)); 198 210 199 eraseAttributeIfInjected(token, srcAttr); 200 eraseAttributeIfInjected(token, typeAttr); 201 } 202 203 void XSSFilter::filterAppletToken(HTMLToken& token) 211 bool didBlockScript = false; 212 213 didBlockScript |= eraseAttributeIfInjected(token, srcAttr); 214 didBlockScript |= eraseAttributeIfInjected(token, typeAttr); 215 216 return didBlockScript; 217 } 218 219 bool XSSFilter::filterAppletToken(HTMLToken& token) 204 220 { 205 221 ASSERT(m_state == Initial); … … 207 223 ASSERT(hasName(token, appletTag)); 208 224 209 eraseAttributeIfInjected(token, codeAttr); 210 eraseAttributeIfInjected(token, objectAttr); 211 } 212 213 void XSSFilter::filterMetaToken(HTMLToken& token) 225 bool didBlockScript = false; 226 227 didBlockScript |= eraseAttributeIfInjected(token, codeAttr); 228 didBlockScript |= eraseAttributeIfInjected(token, objectAttr); 229 230 return didBlockScript; 231 } 232 233 bool XSSFilter::filterMetaToken(HTMLToken& token) 214 234 { 215 235 ASSERT(m_state == Initial); … … 217 237 ASSERT(hasName(token, metaTag)); 218 238 219 eraseAttributeIfInjected(token, http_equivAttr);220 } 221 222 voidXSSFilter::filterBaseToken(HTMLToken& token)239 return eraseAttributeIfInjected(token, http_equivAttr); 240 } 241 242 bool XSSFilter::filterBaseToken(HTMLToken& token) 223 243 { 224 244 ASSERT(m_state == Initial); … … 226 246 ASSERT(hasName(token, baseTag)); 227 247 228 eraseAttributeIfInjected(token, hrefAttr); 248 return eraseAttributeIfInjected(token, hrefAttr); 249 } 250 251 bool XSSFilter::eraseInlineEventHandlersIfInjected(HTMLToken& token) 252 { 253 bool didBlockScript = false; 254 for (size_t i = 0; i < token.attributes().size(); ++i) { 255 const HTMLToken::Attribute& attribute = token.attributes().at(i); 256 if (!isNameOfInlineEventHandler(attribute.m_name)) 257 continue; 258 if (!isContainedInRequest(snippetForAttribute(token, attribute))) 259 continue; 260 token.eraseValueOfAttribute(i); 261 didBlockScript = true; 262 } 263 return didBlockScript; 229 264 } 230 265 -
trunk/Source/WebCore/html/parser/XSSFilter.h
r77034 r77041 46 46 }; 47 47 48 void filterTokenAfterScriptStartTag(HTMLToken&); 49 void filterScriptToken(HTMLToken&); 50 void filterObjectToken(HTMLToken&); 51 void filterEmbedToken(HTMLToken&); 52 void filterAppletToken(HTMLToken&); 53 void filterMetaToken(HTMLToken&); 54 void filterBaseToken(HTMLToken&); 48 bool filterTokenInitial(HTMLToken&); 49 bool filterTokenAfterScriptStartTag(HTMLToken&); 55 50 51 bool filterScriptToken(HTMLToken&); 52 bool filterObjectToken(HTMLToken&); 53 bool filterEmbedToken(HTMLToken&); 54 bool filterAppletToken(HTMLToken&); 55 bool filterMetaToken(HTMLToken&); 56 bool filterBaseToken(HTMLToken&); 57 58 bool eraseInlineEventHandlersIfInjected(HTMLToken&); 56 59 bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&); 57 60
Note: See TracChangeset
for help on using the changeset viewer.