예제 #1
0
 private void ValidateHttp10(Package package)
 {
     // We should never see Expect: for HTTP/1.0 requests
     if (package.HeadersMixed.ContainsKey("Expect")
         && package.HeadersMixed["Expect"].IndexOf
             ("100-continue", StringComparison.InvariantCultureIgnoreCase) < 0) {
                 package.Raise(Errors.Http10Expect);
     }
 }
예제 #2
0
        public RuleProcessing Validate(Package package)
        {
            // Enforce RFC 2965 sec 3.3.5 and 9.1
            // Bots wanting new-style cookies should send Cookie2
            // FIXME: Amazon Kindle is broken; Amazon has been notified 9/24/08
            if (package.HeadersMixed.ContainsKey("Cookie") &&
                package.HeadersMixed["Cookie"].Contains("$Version=0") &&
                !package.HeadersMixed.ContainsKey("Cookie2") &&
                !package.Request.UserAgent.Contains("Kindle/")) {
                package.Raise(Errors.InvalidCookies);
            }

            return RuleProcessing.Continue;
        }
예제 #3
0
        public RuleProcessing Validate(Package package)
        {
            if (package.Request.HttpMethod != "POST" && String.IsNullOrEmpty(package.Request.UserAgent))
                package.Raise(Errors.UserAgentMissing);

            // Broken spambots send URLs with various invalid characters
            // Some broken browsers send the #vector in the referer field :(
            // Worse yet, some Javascript client-side apps do the same in
            // blatant violation of the protocol and good sense.
            // if (strpos($package['request_uri'], "#") !== FALSE || strpos($package['headers_mixed']['Referer'], "#") !== FALSE) {

            if (package.Request.RawUrl.Contains('#'))
                package.RaiseStrict(Errors.Malicious);

            // A pretty nasty SQL injection attack on IIS servers
            if (package.Request.RawUrl.Contains(";DECLARE%20@"))
                package.Raise(Errors.Malicious);

            // Range: field exists and begins with 0
            // Real user-agents do not start ranges at 0
            // NOTE: this blocks the whois.sc bot. No big loss.
            // Exceptions: MT (not fixable); LJ (refuses to fix; may be
            // blocked again in the future); Facebook
            if (package.HeadersMixed.ContainsKey("Range")
                && package.HeadersMixed["Range"].Contains("=0-")) {
                if (!(
                    package.Request.UserAgent.StartsWith("MovableType") ||
                    package.Request.UserAgent.StartsWith("URI::Fetch") ||
                    package.Request.UserAgent.StartsWith("php-openid/") ||
                    package.Request.UserAgent.StartsWith("facebookexternalhit")
                )) {
                    package.RaiseStrict(Errors.RangeHeaderZero);
                }
            }

            // Content-Range is a response header, not a request header
            if (package.HeadersMixed.ContainsKey("Content-Range"))
                package.Raise(Errors.InvalidRangeHeader);

            // Lowercase via is used by open proxies/referrer spammers
            // Exceptions: Clearswift uses lowercase via (refuses to fix;
            // may be blocked again in the future)
            if (package.Request.Headers["via"] != null &&
                !package.Request.Headers["via"].Contains("Clearswift") &&
                !package.Request.UserAgent.Contains("CoralWebPrx"))
                package.Raise(Errors.InvalidVia);

            // pinappleproxy is used by referrer spammers
            if (package.HeadersMixed.ContainsKey("Via")) {
                string via = package.HeadersMixed["Via"].ToLowerInvariant();
                if (via.Contains("pinappleproxy") || via.Contains("pcnetserver") || via.Contains("invisiware"))
                    package.Raise(Errors.BannedProxy);
            }

            // TE: if present must have Connection: TE
            // RFC 2616 14.39
            // Blocks Microsoft ISA Server 2004 in strict mode. Contact Microsoft
            // to obtain a hotfix.
            if (package.HeadersMixed.ContainsKey("Te")) {
                if (Regex.Match(package.HeadersMixed["Connection"], @"\bTE\b").Success)
                    package.RaiseStrict(Errors.TeWithoutConnectionTe);
            }

            if (package.HeadersMixed.ContainsKey("Connection")) {
                // Connection: keep-alive and close are mutually exclusive.
                // Keep-Alive shouldn't appear twice, neither should Close.
                var connection = package.HeadersMixed.GetValues("Connection");
                var keepAlives = connection.Sum
                    (x => Regex.Matches(x, @"\bKeep-Alive\b", RegexOptions.IgnoreCase).Count);
                var closes = connection.Sum
                    (x => Regex.Matches(x, @"\bClose\b", RegexOptions.IgnoreCase).Count);
                if (keepAlives + closes > 1)
                    package.Raise(Errors.InvalidConnectionHeader);

                // Keep-Alive format in RFC 2068; some bots mangle these headers
                if (connection.Any(x => x.IndexOf
                    ("Keep-Alive: ", StringComparison.InvariantCultureIgnoreCase) >= 0))
                    package.Raise(Errors.MaliciousConnectionHeader);
            }

            // Headers which are not seen from normal user agents; only malicious bots
            if (package.HeadersMixed.ContainsKey("X-Aaaaaaaaaaaa") ||
                package.HeadersMixed.ContainsKey("X-Aaaaaaaaaa"))
                package.Raise(Errors.ProhibitedHeader);

            // Proxy-Connection does not exist and should never be seen in the wild
            // http://lists.w3.org/Archives/Public/ietf-http-wg-old/1999JanApr/0032.html
            // http://lists.w3.org/Archives/Public/ietf-http-wg-old/1999JanApr/0040.html
            if (package.HeadersMixed.ContainsKey("Proxy-Connection"))
                package.RaiseStrict(Errors.ProxyConnectionHeaderPresent);

            if (package.HeadersMixed.ContainsKey("Referer")) {
                string referer = package.HeadersMixed["Referer"];
                // Referer, if it exists, must not be blank
                if (referer == String.Empty)
                    package.Raise(Errors.BlankReferer);

                // Referer, if it exists, must contain a :
                // While a relative URL is technically valid in Referer, all known
                // legitimate user-agents send an absolute URL
                if (!referer.Contains(":"))
                    package.Raise(Errors.CorruptReferer);
            }

            return RuleProcessing.Continue;
        }
예제 #4
0
        // Validates user agents claiming to be MSIE

        private void ValidateMSIE(Package package)
        {
            AssertAccept(package);

            // MSIE does NOT send "Windows ME" or "Windows XP" in the user agent
            if (package.Request.UserAgent.Contains("Windows ME") ||
                package.Request.UserAgent.Contains("Windows XP") ||
                package.Request.UserAgent.Contains("Windows 2000") ||
                package.Request.UserAgent.Contains("Win32"))
                package.Raise(Errors.InvalidMSIEWindowsVersion);

            // MSIE does NOT send Connection: TE but Akamai does
            // Bypass this test when Akamai detected
            if (package.HeadersMixed.ContainsKey("Akamai-Origin-Hop")) return;

            // The latest version of IE for Windows CE also uses Connection: TE
            if (package.Request.UserAgent.Contains("IEMobile")) return;

            if (package.HeadersMixed.ContainsKey("Connection")) {
                if (Regex.Match(package.HeadersMixed["Connection"], @"\bTE\b").Success) {
                    package.Raise(Errors.InvalidMSIEWithTE);
                }
            }
        }
예제 #5
0
        /* ====== Assertions ====== */

        // Assert that the "Accept" HTTP header is present. Bona fide browsers all send this.

        private void AssertAccept(Package package)
        {
            if (!package.HeadersMixed.ContainsKey("Accept"))
                package.Raise(Errors.AcceptMissing);
        }
예제 #6
0
        /* ====== Movable Type ====== */

        // See movabletype.inc.php in BB original.

        private void ValidateMovableType(Package package)
        {
            // Is it a trackback?
            if (package.Request.HttpMethod == "POST") {
                if (package.HeadersMixed.ContainsKey("Range")
                    && package.HeadersMixed["Range"] == "bytes=0-99999") {
                        package.Raise(Errors.InvalidRangeHeader);
                }
            }
        }