Example #1
0
bool XSSAuditor::filterEmbedToken(HTMLToken& token)
{
    ASSERT(token.type() == HTMLTokenTypes::StartTag);
    ASSERT(hasName(token, embedTag));

    bool didBlockScript = false;
    if (isContainedInRequest(decodedSnippetForName(token))) {
        didBlockScript |= eraseAttributeIfInjected(token, codeAttr, String(), SrcLikeAttribute);
        didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string(), SrcLikeAttribute);
        didBlockScript |= eraseAttributeIfInjected(token, typeAttr);
    }
    return didBlockScript;
}
Example #2
0
bool XSSAuditor::filterScriptToken(HTMLToken& token)
{
    ASSERT(token.type() == HTMLTokenTypes::StartTag);
    ASSERT(hasName(token, scriptTag));

    m_cachedDecodedSnippet = decodedSnippetForName(token);
    m_shouldAllowCDATA = m_parser->tokenizer()->shouldAllowCDATA();

    if (isContainedInRequest(decodedSnippetForName(token)))
        return eraseAttributeIfInjected(token, srcAttr, blankURL().string(), SrcLikeAttribute);

    return false;
}
Example #3
0
bool XSSAuditor::filterAppletToken(HTMLToken& token)
{
    ASSERT(m_state == Initial);
    ASSERT(token.type() == HTMLToken::StartTag);
    ASSERT(hasName(token, appletTag));

    bool didBlockScript = false;

    didBlockScript |= eraseAttributeIfInjected(token, codeAttr);
    didBlockScript |= eraseAttributeIfInjected(token, objectAttr);

    return didBlockScript;
}
Example #4
0
bool XSSAuditor::filterEmbedToken(HTMLToken& token)
{
    ASSERT(m_state == Initial);
    ASSERT(token.type() == HTMLToken::StartTag);
    ASSERT(hasName(token, embedTag));

    bool didBlockScript = false;

    didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string());
    didBlockScript |= eraseAttributeIfInjected(token, typeAttr);

    return didBlockScript;
}
Example #5
0
bool XSSAuditor::filterScriptToken(HTMLToken& token)
{
    ASSERT(m_state == Initial);
    ASSERT(token.type() == HTMLToken::StartTag);
    ASSERT(hasName(token, scriptTag));

    if (eraseAttributeIfInjected(token, srcAttr, blankURL().string()))
        return true;

    m_state = AfterScriptStartTag;
    m_cachedSnippet = m_parser->sourceForToken(token);
    return false;
}
Example #6
0
bool XSSAuditor::filterObjectToken(HTMLToken& token)
{
    ASSERT(m_state == Initial);
    ASSERT(token.type() == HTMLTokenTypes::StartTag);
    ASSERT(hasName(token, objectTag));

    bool didBlockScript = false;

    didBlockScript |= eraseAttributeIfInjected(token, dataAttr, blankURL().string(), SrcLikeAttribute);
    didBlockScript |= eraseAttributeIfInjected(token, typeAttr);
    didBlockScript |= eraseAttributeIfInjected(token, classidAttr);

    return didBlockScript;
}
Example #7
0
void XSSAuditor::filterToken(HTMLToken& token)
{
    if (m_state == Uninitialized)
        init();
   
    ASSERT(m_state == Initialized);
    if (!m_isEnabled || m_xssProtection == XSSProtectionDisabled)
        return;

    bool didBlockScript = false;
    if (token.type() == HTMLTokenTypes::StartTag)
        didBlockScript = filterStartToken(token);
    else if (m_scriptTagNestingLevel) {
        if (token.type() == HTMLTokenTypes::Character)
            didBlockScript = filterCharacterToken(token);
        else if (token.type() == HTMLTokenTypes::EndTag)
            filterEndToken(token);
    }

    if (didBlockScript) {
        // FIXME: Consider using a more helpful console message.
        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
        m_parser->document()->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage);

        bool didBlockEntirePage = (m_xssProtection == XSSProtectionBlockEnabled);
        if (didBlockEntirePage)
             m_parser->document()->frame()->loader()->stopAllLoaders();

        if (!m_notifiedClient) {
            m_parser->document()->frame()->loader()->client()->didDetectXSS(m_parser->document()->url(), didBlockEntirePage);
            m_notifiedClient = true;
        }

        if (didBlockEntirePage)
            m_parser->document()->frame()->navigationScheduler()->scheduleLocationChange(m_parser->document()->securityOrigin(), blankURL(), String());
    }
}
void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLToken& rawToken)
{
    AtomicHTMLToken token(rawToken);

    // We clear the rawToken in case constructTreeFromAtomicToken
    // synchronously re-enters the parser. We don't clear the token immedately
    // for Character tokens because the AtomicHTMLToken avoids copying the
    // characters by keeping a pointer to the underlying buffer in the
    // HTMLToken. Fortunately, Character tokens can't cause us to re-enter
    // the parser.
    //
    // FIXME: Stop clearing the rawToken once we start running the parser off
    // the main thread or once we stop allowing synchronous JavaScript
    // execution from parseAttribute.
    if (rawToken.type() != HTMLToken::Character)
        rawToken.clear();

    m_treeBuilder->constructTree(&token);

    if (!rawToken.isUninitialized()) {
        ASSERT(rawToken.type() == HTMLToken::Character);
        rawToken.clear();
    }
}
Example #9
0
//------------------------------------------------------------------------------------------------
void XMLReader::HandleStart (HTMLToken t) {
	string val = StringUtil::ToLowerCopy(t.GetValue());

	if (val == "board")
		inBoard = true;
	else if (val == "history")
		inHistory = true;
	else if (val == "move") {
		moveNum = 1;
		move.SetCaptured(NOTYPE);
		inMove = true;
	}


	if (val == "piece" && inMove) {
		switch(moveNum) {
			case 0 : 
				break;
			case 1 : {
				move.SetType(GetTypeByName(t.GetAttribute("type")));
				move.SetColor(GetColorByName(t.GetAttribute("color")));
				Position pstart;
				pstart.SetRow(atoi((t.GetAttribute("row")).c_str()));
				pstart.SetCol(atoi((t.GetAttribute("column")).c_str()));
				move.SetStart(pstart);
				moveNum++;
				break;
			}
			case 2 : {
				Position pend;
				pend.SetRow(atoi((t.GetAttribute("row")).c_str()));
				pend.SetCol(atoi((t.GetAttribute("column")).c_str()));
				move.SetEnd(pend);
				moveNum++;
				break;
			}
			case 3 :
				move.SetCaptured(GetTypeByName(t.GetAttribute("type")));
				moveNum++;
				break;
		}
	}
}
Example #10
0
void GameLoader::LoadBoard(HTMLTokenizer & tokenizer, Board * boardPtr) const
{
	HTMLToken currentToken = tokenizer.GetNextToken();
	while (currentToken.GetValue() != "board")
	{
		CheckForEndToken(currentToken);
		currentToken = tokenizer.GetNextToken();
	}

	currentToken = tokenizer.GetNextToken();
	while (currentToken.GetValue() != "board")
	{
		CheckForEndToken(currentToken);
		if (currentToken.GetValue() == "piece")
		{
			int pieceType = ConvertTypeStrToInt(currentToken.GetAttribute("type"));
			int pieceColor = ConvertColorStrToInt(currentToken.GetAttribute("color"));
			int col = atoi(currentToken.GetAttribute("column").c_str());
			int row = atoi(currentToken.GetAttribute("row").c_str());
			boardPtr->SetPiece(BoardPosition(row, col), pieceType, pieceColor);
		}
		currentToken = tokenizer.GetNextToken();
	}
}
Example #11
0
bool XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token)
{
    ASSERT(m_state == AfterScriptStartTag);
    m_state = Initial;

    if (token.type() != HTMLToken::Character) {
        ASSERT(token.type() == HTMLToken::EndTag || token.type() == HTMLToken::EndOfFile);
        return false;
    }

    int start = 0;
    // FIXME: We probably want to grab only the first few characters of the
    //        contents of the script element.
    int end = token.endIndex() - token.startIndex();
    if (isContainedInRequest(m_cachedSnippet + snippetForRange(token, start, end))) {
        token.eraseCharacters();
        token.appendToCharacter(' '); // Technically, character tokens can't be empty.
        return true;
    }
    return false;
}
Example #12
0
bool XSSAuditor::filterTokenAfterScriptStartTag(HTMLToken& token)
{
    ASSERT(m_state == AfterScriptStartTag);
    m_state = Initial;

    if (token.type() != HTMLTokenTypes::Character) {
        ASSERT(token.type() == HTMLTokenTypes::EndTag || token.type() == HTMLTokenTypes::EndOfFile);
        return false;
    }

    TextResourceDecoder* decoder = m_parser->document()->decoder();
    if (isContainedInRequest(fullyDecodeString(m_cachedSnippet, decoder))) {
        int start = 0;
        int end = token.endIndex() - token.startIndex();
        String snippet = snippetForJavaScript(snippetForRange(token, start, end));
        if (isContainedInRequest(fullyDecodeString(snippet, decoder))) {
            token.eraseCharacters();
            token.appendToCharacter(' '); // Technically, character tokens can't be empty.
            return true;
        }
    }
    return false;
}
void TokenPreloadScanner::updatePredictedBaseURL(const HTMLToken& token)
{
    ASSERT(m_predictedBaseElementURL.isEmpty());
    if (auto* hrefAttribute = findAttribute(token.attributes(), hrefAttr.localName().string()))
        m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(hrefAttribute->value))).isolatedCopy();
}
void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<PreloadRequest>>& requests, Document& document)
{
    switch (token.type()) {
    case HTMLToken::Character:
        if (!m_inStyle)
            return;
        m_cssScanner.scan(token.characters(), requests);
        return;

    case HTMLToken::EndTag: {
        TagId tagId = tagIdFor(token.name());
#if ENABLE(TEMPLATE_ELEMENT)
        if (tagId == TagId::Template) {
            if (m_templateCount)
                --m_templateCount;
            return;
        }
#endif
        if (tagId == TagId::Style) {
            if (m_inStyle)
                m_cssScanner.reset();
            m_inStyle = false;
        } else if (tagId == TagId::Picture && !m_pictureSourceState.isEmpty())
            m_pictureSourceState.removeLast();

        return;
    }

    case HTMLToken::StartTag: {
#if ENABLE(TEMPLATE_ELEMENT)
        if (m_templateCount)
            return;
#endif
        TagId tagId = tagIdFor(token.name());
#if ENABLE(TEMPLATE_ELEMENT)
        if (tagId == TagId::Template) {
            ++m_templateCount;
            return;
        }
#endif
        if (tagId == TagId::Style) {
            m_inStyle = true;
            return;
        }
        if (tagId == TagId::Base) {
            // The first <base> element is the one that wins.
            if (!m_predictedBaseElementURL.isEmpty())
                return;
            updatePredictedBaseURL(token);
            return;
        }
        if (tagId == TagId::Picture) {
            m_pictureSourceState.append(false);
            return;
        }

        StartTagScanner scanner(tagId, m_deviceScaleFactor);
        scanner.processAttributes(token.attributes(), document, m_pictureSourceState);
        if (auto request = scanner.createPreloadRequest(m_predictedBaseElementURL))
            requests.append(WTFMove(request));
        return;
    }

    default:
        return;
    }
}
Example #15
0
bool HTMLParser::isHeadStart(HTMLToken & token){
  string lower = token.GetValue();
  StringUtil::ToLower(lower);
  return (token.GetType() == TAG_START && lower.compare("head") == 0);
}
Example #16
0
void GameLoader::LoadMoveHistory(HTMLTokenizer & tokenizer, MoveHistory * gameHistory) const
{
	HTMLToken currentToken = tokenizer.GetNextToken();
	while (currentToken.GetValue() != "history")
	{
		CheckForEndToken(currentToken);
		currentToken = tokenizer.GetNextToken();
	}

	currentToken = tokenizer.GetNextToken();
	while (currentToken.GetValue() != "history")
	{
		CheckForEndToken(currentToken);
		if (currentToken.GetValue() == "move"
				&& currentToken.GetType() == HTMLTokenType::TAG_START)
		{
			while (currentToken.GetValue() != "piece")
			{
				CheckForEndToken(currentToken);
				currentToken = tokenizer.GetNextToken();
			}
			HTMLToken origin = currentToken;

			currentToken = tokenizer.GetNextToken();
			while (currentToken.GetValue() != "piece")
			{
				CheckForEndToken(currentToken);
				currentToken = tokenizer.GetNextToken();
			}
			HTMLToken destination = currentToken;

			currentToken = tokenizer.GetNextToken();

			int originPieceType = ConvertTypeStrToInt(origin.GetAttribute("type"));
			int originPieceColor = ConvertColorStrToInt(origin.GetAttribute("color"));
			int originCol = atoi(origin.GetAttribute("column").c_str());
			int originRow = atoi(origin.GetAttribute("row").c_str());
			int destinationCol = atoi(destination.GetAttribute("column").c_str());
			int destinationRow = atoi(destination.GetAttribute("row").c_str());
			int capturedPieceType = -1;
			int capturedCol = -1;
			int capturedRow = -1;

			while (currentToken.GetValue() != "piece"
					&& currentToken.GetValue() != "move")
			{
				CheckForEndToken(currentToken);
				currentToken = tokenizer.GetNextToken();
			}

			if (currentToken.GetValue() == "piece")
			{
				capturedPieceType = ConvertTypeStrToInt(currentToken.GetAttribute("type"));
				capturedCol = atoi(currentToken.GetAttribute("column").c_str());
				capturedRow = atoi(currentToken.GetAttribute("row").c_str());
			}

			gameHistory->AddMove(Move(originPieceType,
					originPieceColor, BoardPosition(originRow, originCol),
					BoardPosition(destinationRow, destinationCol),
					capturedPieceType, BoardPosition(capturedRow, capturedCol)));
		}
		else
		{
			currentToken = tokenizer.GetNextToken();
		}
	}
}
String XSSAuditor::decodedSnippetForName(const HTMLToken& token)
{
    // Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
    return fullyDecodeString(m_parser->sourceForToken(token), m_parser->document()->decoder()).substring(0, token.name().size() + 1);
}
Example #18
0
bool HTMLParser::isScriptEnd(HTMLToken & token){
  string lower = token.GetValue();
  StringUtil::ToLower(lower);
  return (token.GetType() == TAG_END && lower == "script");    
}
Example #19
0
bool HTMLParser::isTitleEnd(HTMLToken & token){
  string lower = token.GetValue();
  StringUtil::ToLower(lower);
  return (token.GetType() == TAG_END && lower.compare("title") == 0);
}
static bool hasName(const HTMLToken& token, const QualifiedName& name)
{
    return threadSafeMatch(token.name(), name);
}
Example #21
0
bool HTMLParser::isText(HTMLToken & token){
  string lower = token.GetValue();
  StringUtil::ToLower(lower);
  return (token.GetType() == TEXT && !isWhiteSpace(lower));
}
Example #22
0
CompactHTMLToken::CompactHTMLToken(const HTMLToken& token)
    : m_type(token.type())
{
    switch (m_type) {
    case HTMLTokenTypes::Uninitialized:
        ASSERT_NOT_REACHED();
        break;
    case HTMLTokenTypes::DOCTYPE:
        m_data = String(token.name().data(), token.name().size());
        m_publicIdentifier = String(token.publicIdentifier().data(), token.publicIdentifier().size());
        m_systemIdentifier = String(token.systemIdentifier().data(), token.systemIdentifier().size());
        break;
    case HTMLTokenTypes::EndOfFile:
        break;
    case HTMLTokenTypes::StartTag:
        m_attributes.reserveInitialCapacity(token.attributes().size());
        for (Vector<AttributeBase>::const_iterator it = token.attributes().begin(); it != token.attributes().end(); ++it)
            m_attributes.append(CompactAttribute(String(it->m_name.data(), it->m_name.size()), String(it->m_value.data(), it->m_value.size())));
        // Fall through!
    case HTMLTokenTypes::EndTag:
        m_selfClosing = token.selfClosing();
        // Fall through!
    case HTMLTokenTypes::Comment:
    case HTMLTokenTypes::Character:
        if (token.isAll8BitData())
            m_data = String::make8BitFrom16BitSource(token.data().data(), token.data().size());
        else
            m_data = String(token.data().data(), token.data().size());
        break;
    default:
        ASSERT_NOT_REACHED();
        break;
    }
}
Example #23
0
bool HTMLParser::isHeaderEnd(HTMLToken & token){
  string lower = token.GetValue();
  StringUtil::ToLower(lower);
	boost::regex re("[hH][1-9]");
	return (boost::regex_match(lower, re) && token.GetType() == TAG_END);
}
TEST(AtomicHTMLTokenTest, EmptyAttributeValueFromCompactHTMLToken)
{
    HTMLToken token;
    token.beginStartTag('a');
    token.addNewAttribute();
    token.beginAttributeName(3);
    token.appendToAttributeName('b');
    token.endAttributeName(4);
    token.addNewAttribute();
    token.beginAttributeName(5);
    token.appendToAttributeName('c');
    token.endAttributeName(6);
    token.beginAttributeValue(8);
    token.endAttributeValue(8);

    AtomicHTMLToken atoken(CompactHTMLToken(&token, TextPosition()));

    const blink::Attribute* attributeB = atoken.getAttributeItem(
        QualifiedName(AtomicString(), "b", AtomicString()));
    ASSERT_TRUE(attributeB);
    EXPECT_FALSE(attributeB->value().isNull());
    EXPECT_TRUE(attributeB->value().isEmpty());

    const blink::Attribute* attributeC = atoken.getAttributeItem(
        QualifiedName(AtomicString(), "c", AtomicString()));
    ASSERT_TRUE(attributeC);
    EXPECT_FALSE(attributeC->value().isNull());
    EXPECT_TRUE(attributeC->value().isEmpty());

    const blink::Attribute* attributeD = atoken.getAttributeItem(
        QualifiedName(AtomicString(), "d", AtomicString()));
    EXPECT_FALSE(attributeD);
}
static bool hasName(const HTMLToken& token, const QualifiedName& name)
{
    return equalIgnoringNullity(token.name(), static_cast<const String&>(name.localName()));
}
Example #26
0
bool HTMLParser::isLinkStart(HTMLToken & token){
  string lower = token.GetValue();
  StringUtil::ToLower(lower);
  return (token.GetType() == TAG_START && lower == "a");  
}