1<?php if (!defined('BB2_CORE')) die('I said no cheating!');
2
3// Enforce adherence to protocol version claimed by user-agent.
4
5function bb2_protocol($settings, $package)
6{
7	// Is it claiming to be HTTP/1.0?  Then it shouldn't do HTTP/1.1 things
8	// Always run this test; we should never see Expect:
9	if (array_key_exists('Expect', $package['headers_mixed']) && stripos($package['headers_mixed']['Expect'], "100-continue") !== FALSE && !strcmp($package['server_protocol'], "HTTP/1.0")) {
10		return "a0105122";
11	}
12
13	// Is it claiming to be HTTP/1.1?  Then it shouldn't do HTTP/1.0 things
14	// Blocks some common corporate proxy servers in strict mode
15	if ($settings['strict'] && !strcmp($package['server_protocol'], "HTTP/1.1")) {
16		if (array_key_exists('Pragma', $package['headers_mixed']) && strpos($package['headers_mixed']['Pragma'], "no-cache") !== FALSE && !array_key_exists('Cache-Control', $package['headers_mixed'])) {
17			return "41feed15";
18		}
19	}
20	return false;
21}
22
23function bb2_cookies($settings, $package)
24{
25	// Enforce RFC 2965 sec 3.3.5 and 9.1
26	// Bots wanting new-style cookies should send Cookie2
27	// FIXME: Amazon Kindle is broken; Amazon has been notified 9/24/08
28	if (@strpos($package['headers_mixed']['Cookie'], '$Version=0') !== FALSE && !array_key_exists('Cookie2', $package['headers_mixed']) && strpos($package['headers_mixed']['User-Agent'], "Kindle/") === FALSE) {
29		return '6c502ff1';
30	}
31	return false;
32}
33
34function bb2_misc_headers($settings, $package)
35{
36	@$ua = $package['headers_mixed']['User-Agent'];
37
38	if (!strcmp($package['request_method'], "POST") && empty($ua)) {
39		return "f9f2b8b9";
40	}
41
42	// Broken spambots send URLs with various invalid characters
43	// Some broken browsers send the #vector in the referer field :(
44	// if (strpos($package['request_uri'], "#") !== FALSE || strpos($package['headers_mixed']['Referer'], "#") !== FALSE) {
45	if ($settings['strict'] && strpos($package['request_uri'], "#") !== FALSE) {
46		return "dfd9b1ad";
47	}
48	// A pretty nasty SQL injection attack on IIS servers
49	if (strpos($package['request_uri'], ";DECLARE%20@") !== FALSE) {
50		return "dfd9b1ad";
51	}
52
53	// Range: field exists and begins with 0
54	// Real user-agents do not start ranges at 0
55	// NOTE: this blocks the whois.sc bot. No big loss.
56	// Exceptions: MT (not fixable); LJ (refuses to fix; may be
57	// blocked again in the future); Facebook
58	if ($settings['strict'] && array_key_exists('Range', $package['headers_mixed']) && strpos($package['headers_mixed']['Range'], "=0-") !== FALSE) {
59		if (strncmp($ua, "MovableType", 11) && strncmp($ua, "URI::Fetch", 10) && strncmp($ua, "php-openid/", 11) && strncmp($ua, "facebookexternalhit", 19)) {
60			return "7ad04a8a";
61		}
62	}
63
64	// Content-Range is a response header, not a request header
65	if (array_key_exists('Content-Range', $package['headers_mixed'])) {
66		return '7d12528e';
67	}
68
69	// Lowercase via is used by open proxies/referrer spammers
70	// Exceptions: Clearswift uses lowercase via (refuses to fix;
71	// may be blocked again in the future)
72	// Coral CDN uses lowercase via
73	if (array_key_exists('via', $package['headers']) &&
74		strpos($package['headers']['via'],'Clearswift') === FALSE &&
75		strpos($ua,'CoralWebPrx') === FALSE) {
76		return "9c9e4979";
77	}
78
79	// pinappleproxy is used by referrer spammers
80	if (array_key_exists('Via', $package['headers_mixed'])) {
81		if (stripos($package['headers_mixed']['Via'], "pinappleproxy") !== FALSE || stripos($package['headers_mixed']['Via'], "PCNETSERVER") !== FALSE || stripos($package['headers_mixed']['Via'], "Invisiware") !== FALSE) {
82			return "939a6fbb";
83		}
84	}
85
86	// TE: if present must have Connection: TE
87	// RFC 2616 14.39
88	// Blocks Microsoft ISA Server 2004 in strict mode. Contact Microsoft
89	// to obtain a hotfix.
90	if ($settings['strict'] && array_key_exists('Te', $package['headers_mixed'])) {
91		if (!preg_match('/\bTE\b/', $package['headers_mixed']['Connection'])) {
92			return "582ec5e4";
93		}
94	}
95
96	if (array_key_exists('Connection', $package['headers_mixed'])) {
97		// Connection: keep-alive and close are mutually exclusive
98		if (preg_match('/\bKeep-Alive\b/i', $package['headers_mixed']['Connection']) && preg_match('/\bClose\b/i', $package['headers_mixed']['Connection'])) {
99			return "a52f0448";
100		}
101		// Close shouldn't appear twice
102		if (preg_match('/\bclose,\s?close\b/i', $package['headers_mixed']['Connection'])) {
103			return "a52f0448";
104		}
105		// Keey-Alive shouldn't appear twice either
106		if (preg_match('/\bkeep-alive,\s?keep-alive\b/i', $package['headers_mixed']['Connection'])) {
107			return "a52f0448";
108		}
109	}
110
111
112	// Headers which are not seen from normal user agents; only malicious bots
113	if (array_key_exists('X-Aaaaaaaaaaaa', $package['headers_mixed']) || array_key_exists('X-Aaaaaaaaaa', $package['headers_mixed'])) {
114		return "b9cc1d86";
115	}
116	// Proxy-Connection does not exist and should never be seen in the wild
117	if ($settings['strict'] && array_key_exists('Proxy-Connection', $package['headers_mixed'])) {
118		return "b7830251";
119	}
120
121	if (array_key_exists('Referer', $package['headers_mixed'])) {
122		// Referer, if it exists, must not be blank
123		if (empty($package['headers_mixed']['Referer'])) {
124			return "69920ee5";
125		}
126
127		// Referer, if it exists, must contain a :
128		// While a relative URL is technically valid in Referer, all known
129		// legit user-agents send an absolute URL
130		if (strpos($package['headers_mixed']['Referer'], ":") === FALSE) {
131			return "45b35e30";
132		}
133	}
134
135	// "uk" is not a language (ISO 639) nor a country (ISO 3166)
136	// oops, yes it is :( Please shoot any Ukrainian spammers you see.
137#	if (preg_match('/\buk\b/', $package['headers_mixed']['Accept-Language'])) {
138#		return "35ea7ffa";
139#	}
140
141	return false;
142}
143
144?>
145