You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2016/11/04 14:20:16 UTC

svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Author: wrowe
Date: Fri Nov  4 14:20:16 2016
New Revision: 1768036

URL: http://svn.apache.org/viewvc?rev=1768036&view=rev
Log:
Add an option to enforce stricter HTTP conformance

This is a first stab, the checks will likely have to be revised.
For now, we check

 * if the request line contains control characters
 * if the request uri has fragment or username/password
 * that the request method is standard or registered with RegisterHttpMethod
 * that the request protocol is of the form HTTP/[1-9]+.[0-9]+,
   or missing for 0.9
 * if there is garbage in the request line after the protocol
 * if any request header contains control characters
 * if any request header has an empty name
 * for the host name in the URL or Host header:
   - if an IPv4 dotted decimal address: Reject octal or hex values, require
     exactly four parts
   - if a DNS host name: Reject non-alphanumeric characters besides '.' and
     '-'. As a side effect, this rejects multiple Host headers.
 * if any response header contains control characters
 * if any response header has an empty name
 * that the Location response header (if present) has a valid scheme and is
   absolute

If we have a host name both from the URL and the Host header, we replace the
Host header with the value from the URL to enforce RFC conformance.

There is a log-only mode, but the loglevels of the logged messages need some
thought/work. Currently, the  checks for incoming data log for 'core' and the
checks for outgoing data log for 'http'. Maybe we need a way to configure the
loglevels separately from the core/http loglevels.

change protocol number parsing in strict mode according to HTTPbis draft
- only accept single digit version components
- don't accept white-space after protocol specification

Clean up comment, fix log tags.
Submitted by: sf
Backports: r1426877, r1426879, r1426988, r1426992


Modified:
    httpd/httpd/branches/2.4.x-merge-http-strict/   (props changed)
    httpd/httpd/branches/2.4.x-merge-http-strict/CHANGES
    httpd/httpd/branches/2.4.x-merge-http-strict/include/ap_mmn.h
    httpd/httpd/branches/2.4.x-merge-http-strict/include/http_core.h
    httpd/httpd/branches/2.4.x-merge-http-strict/include/httpd.h
    httpd/httpd/branches/2.4.x-merge-http-strict/modules/http/http_filters.c
    httpd/httpd/branches/2.4.x-merge-http-strict/server/core.c
    httpd/httpd/branches/2.4.x-merge-http-strict/server/protocol.c
    httpd/httpd/branches/2.4.x-merge-http-strict/server/util.c
    httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c

Propchange: httpd/httpd/branches/2.4.x-merge-http-strict/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Nov  4 14:20:16 2016
@@ -2,4 +2,4 @@
 /httpd/httpd/branches/2.4.17-protocols-http2:1701609-1705681
 /httpd/httpd/branches/revert-ap-ldap:1150158-1150173
 /httpd/httpd/branches/wombat-integration:723609-723841
-/httpd/httpd/trunk:1200475,1200478,1200482,1200491,1200496,1200513,1200550,1200556,1200580,1200605,1200612,1200614,1200639,1200646,1200656,1200667,1200679,1200699,1200702,1200955,1200957,1200961,1200963,1200968,1200975,1200977,1201032,1201042,1201111,1201194,1201198,1201202,1201443,1201450,1201460,1201956,1202236,1202453,1202456,1202886,1203400,1203491,1203632,1203714,1203859,1203980,1204630,1204968,1204990,1205061,1205075,1205379,1205885,1206291,1206472,1206587,1206850,1206940,1206978,1207719,1208753,1208835,1209053,1209085,1209417,1209432,1209461,1209601,1209603,1209618,1209623,1209741,1209754,1209766,1209776,1209797-1209798,1209811-1209812,1209814,1209908,1209910,1209913,1209916-1209917,1209947,1209952,1210067,1210080,1210120,1210124,1210130,1210148,1210219,1210221,1210252,1210284,1210336,1210378,1210725,1210892,1210951,1210954,1211351-1211352,1211364,1211490,1211495,1211528,1211663,1211680,1212872,1212883,1213338,1213380-1213381,1213391,1213399,1213567,1214003,1214005,1214015,12
 15514,1220462,1220467,1220493,1220524,1220570,1220768,1220794,1220826,1220846,1221205,1221292,1222335,1222370,1222473,1222915,1222917,1222921,1222930,1223048,1225060,1225197-1225199,1225223,1225380,1225476,1225478,1225791,1225795-1225796,1226339,1226375,1227910,1228700,1228816,1229024,1229059,1229099,1229116,1229134,1229136,1229930,1230286,1231255,1231257,1231442,1231446,1231508,1231510,1231518,1232575,1232594,1232630,1232838,1234180,1234297,1234479,1234511,1234565,1234574,1234642-1234643,1234876,1234899,1235019,1236122,1236701,1237407,1238545,1238768,1239029-1239030,1239071,1239565,1240315,1240470,1240778,1241069,1241071,1242089,1242798,1242967,1243176,1243246,1243797,1243799,1244211,1245717,1290823,1290835,1291819-1291820,1291834,1291840,1292043,1293405,1293534-1293535,1293658,1293678,1293708,1294306,1294349,1294356,1294358,1294372,1294471,1297560,1299718,1299786,1300766,1301111,1301725,1302444,1302483,1302653,1302665,1302674,1303201,1303435,1303827,1304087,1304874-1304875,1305167
 ,1305586,1306350,1306409,1306426,1306841,1307790,1308327,1308459,1309536,1309567,1311468,1324760,1325218,1325227,1325250,1325265,1325275,1325632,1325724,1326980,1326984,1326991,1327689,1328325-1328326,1328339,1328345,1328950,1330189,1330964,1331110,1331115,1331942,1331977,1332378,1333969,1334343,1335882,1337344,1341906,1341913,1343085,1343087,1343094,1343099,1343109,1343935,1345319,1345329,1346905,1347980,1348036,1348653,1348656,1348660,1349905,1351012-1351020,1351071-1351072,1351074,1351737,1352047,1352534,1352909-1352912,1357685,1358061,1359057,1359881,1359884,1361153,1361298,1361766,1361773,1361778,1361784,1361791-1361792,1361801,1361803,1362020,1362538,1362707,1363035,1363183,1363186,1363312,1363440,1363557,1363589,1363829,1363832,1363836-1363837,1363853,1364133,1364138,1364229,1364601,1364695,1365001,1365020,1365029,1365479,1366319,1366344,1366621,1367778,1367819,1368053,1368058,1368094,1368121,1368131,1368393,1368396,1369419,1369568,1369604,1369618,1369904,1369995,1369999,1370
 001,1370466,1370592,1370615-1370616,1370763,1371387,1371791,1371801,1371878,1371903,1373270,1373447,1373898,1373955,1374157,1374199,1374247,1374874,1374877,1374880,1375006,1375009,1375011,1375013,1375584,1376695,1376700,1378178,1383490,1384408,1384913,1386576,1386578,1386726,1386822,1386880,1386913,1387085,1387088,1387110,1387389,1387444,1387603,1387607,1387633,1387693,1387979,1388029,1388445,1388447,1388648,1388660,1388825,1388899,1389316,1389339,1389481,1389506,1389564,1389566-1389569,1390562,1390564,1391396,1391398,1391771,1392120,1392122,1392150,1392214,1392345-1392347,1392850,1393033,1393058,1393152,1393338,1393564,1394079,1395225,1395253-1395256,1395792,1396440,1397172,1397320,1397636,1397687,1397710,1397716,1398025,1398040,1398066,1398478,1398480-1398481,1398970,1399413,1399687,1399708,1400700,1401448,1402924,1403476,1403483,1403492,1404653,1405407,1405856,1405973,1406068,1406493,1406495,1406616,1406646,1406719,1406760,1407004,1407006,1407085,1407088,1407248,1407381,1407459-1
 407460,1407528,1407599,1407643,1407853,1407965,1408093,1408402,1408958,1408961,1409170,1409437,1409726,1409800,1410681,1410954,1411862,1412278,1413732,1414094,1415008,1415023,1415075,1416121,1416150,1416278,1417197,1417440,1417529,1418524,1418556,1418648,1418655,1418703,1418721,1418752,1418769,1419084,1419719,1419726,1419755,1419781,1419796,1420120,1420124,1420149,1420184,1420644,1420685-1420686,1420975,1421288,1421323,1421851,1421912,1421953,1422135,1422549,1422594,1422712,1422855,1422937,1422943,1422980,1423353,1423933,1425360,1425366,1425771-1425772,1425775,1425777,1425874,1426827,1426850,1426975,1427546,1428184,1428280,1428916,1429228,1429559,1429561,1429564,1429582,1430575,1430814,1430869,1433001,1433613,1433682,1433861,1433988,1435178,1435811,1436058,1436401,1439083,1439106,1439114,1439404,1439623,1442309,1442320,1442326,1442412,1442759,1442865,1447993,1448171,1448453,1451478,1451484,1451633,1451849,1451905,1451921,1452128,1452195,1452259,1452281,1452551,1452911,1452949,145295
 4,1453022,1453574,1453604,1453875-1453876,1453963,1453981,1454386,1454414-1454415,1454888,1457437,1457450,1457471,1457504,1457520-1457521,1457610,1457995,1458003-1458004,1458020,1458285,1458447,1458456,1462266,1462269,1462643,1463044-1463047,1463052,1463056,1463455,1463736,1463750,1463754,1464675,1464721,1464762,1465115-1465116,1465190,1467765,1468581,1470183,1470679,1470940,1471449,1475878,1476604,1476621,1476642,1476644-1476645,1476652,1476680,1477094,1477530,1478382,1478748,1479117,1479216,1479222,1479411,1479528,1479905,1479966,1480046,1480627,1481197,1481302,1481306,1481396-1481397,1481891,1482041,1482075,1482170,1482555,1482859,1482996,1483005,1483027,1483190,1484343,1484398,1484832,1484910,1484914,1485409,1485668,1486490,1487528,1487530,1488158,1488164,1488296,1488471,1488492,1488644,1490493,1490507,1490550,1490761,1490994,1491155,1491221,1491234,1491458,1491479,1491538,1491564,1491724,1492663,1492710,1492782,1493330,1493921,1493925,1494536,1495501,1496194,1496338,1496429,149
 6709,1497371,1497588,1498880,1499679,1500323,1500345,1500362,1500423,1500437,1500483,1500519,1501294,1501369,1501399,1501913,1502665,1502772,1503680,1503866,1503990-1503991,1504276,1506474,1506714,1509872,1509983,1510084-1510085,1510098,1510588,1510707,1511093,1513492,1513508,1514039,1514064,1514214-1514215,1514255,1514267,1514617,1515050,1515162,1515403,1515411,1515420,1517025,1517045,1517175,1517366,1517386,1517388,1518265,1518269,1519475,1520368,1520445,1520760,1520908,1521909,1523235,1523239,1523281,1523387,1524101,1524158,1524192,1524368,1524388,1524770,1525276,1525280-1525281,1525931,1526168,1526189,1526647,1526666,1527008,1527220,1527291,1527294-1527295,1527509,1527925-1527926,1528143,1528718,1529014,1529277,1529449,1529559,1529988,1529991,1530793,1531340,1531370,1531505,1531672,1531961-1531962,1532746,1532816,1533065,1533224,1534321,1534754,1534890,1534892,1536310,1537535,1538490,1540051-1540052,1541181,1541270,1541368,1542338,1542379,1542533,1542562,1542615,1543020,1543147,
 1543149,1543174,1544381,1544774,1544784,1544812,1544820,1545286,1545292,1545325,1545364,1545408,1545411,1546692-1546693,1546730,1546759-1546760,1546801,1546804-1546805,1546835-1546836,1547845,1550061,1550302,1550307,1551685,1551714,1551802,1552130,1552227,1553204,1553824,1554161,1554168,1554170,1554175-1554176,1554179,1554181,1554184,1554188,1554192,1554195,1554276,1554281,1554300-1554301,1554994-1554995,1555240,1555259,1555266,1555423-1555424,1555463-1555464,1555467,1555555,1555569,1556206,1556428,1556911-1556912,1556914,1556937,1557317,1557617,1558483,1559351,1559828,1560367,1560546,1560679,1560689,1560729,1560977,1560979,1561137,1561262,1561385,1561660,1561923,1562472,1563193,1563379,1563381,1563417-1563418,1563420,1564052,1564437,1564475,1564756,1564760,1565081,1565711,1568404,1569615,1570288,1570598,1571369,1572092,1572198,1572543,1572561,1572611,1572630,1572655,1572663,1572668-1572671,1572896,1572905,1572911,1572967,1573224,1573229,1573626,1574151,1575400,1576233,1576741,15787
 60,1578762,1580568,1583005,1583007-1583008,1583027,1583175,1583191,1584098,1584430,1584434,1584572,1584653,1584658,1584665,1584703,1584878,1584884,1584896,1585054,1585072,1585090,1585435,1585609,1585824,1585918-1585919,1586745,1586827,1587036,1587040,1587053,1587255,1587594,1587607,1587639,1587654,1588054,1588065,1588213,1588330,1588427,1588519,1588527,1588704,1588851,1588853,1588868,1589413,1590437,1590509,1591143,1591320,1591322,1591328,1591390,1591394,1591401,1591472,1591508,1592032,1592037,1592500,1592511,1592514,1592529,1592615,1592632,1593745,1594625,1594643,1594648,1595305,1595321,1595426,1597182,1597349,1597352,1597639,1597642,1598107,1598946,1599535,1601076,1601184-1601185,1601274,1601291,1601624,1601630,1601919,1601995,1602338,1602978,1602989,1603027,1603029,1603122,1603156,1603915,1604382,1604461,1604631,1605207,1605827,1605829,1607960,1608284,1608785,1608999,1609914,1609936,1609938,1610207,1610311,1610353,1610366,1610491,1610652,1610674,1611165,1611169,1611244,1611600,16
 11871,1611978,1612068,1615026,1615289,1617018,1618401,1618541,1619297,1619383,1619444,1619483,1619835,1620324,1620461,1620932,1621367,1621372,1621417,1621453,1621806,1622450,1624234,1624349,1625196,1625952,1626050,1626978,1628104,1628918-1628919,1628924,1628950,1629235,1629239,1629244,1629250,1629372,1629440-1629441,1629485,1629507-1629508,1629519,1629577,1629652,1629916,1631885,1632454,1632740,1632742,1633730-1633731,1633793,1634120,1634237,1634425,1634736,1634836,1635510,1635558,1635644-1635645,1635762,1637112,1638072-1638073,1638879,1639614,1640031,1640036,1640040,1640042,1640331,1641077,1641095,1641376,1642099,1642484,1642499,1642847,1642868,1643034,1643284,1643537,1643825,1644245,1646282,1646724,1647035,1648201,1648394,1648433,1648719,1648840,1649001,1649043,1649632,1649966,1650047,1650061,1650309-1650310,1650320,1651088,1652829,1652929,1652931,1652955,1652982,1652985,1652989,1653941,1653978,1653997,1656225,1656669,1657256,1657261,1657636,1657638,1657685,1657881,1657897,1658760
 ,1658765,1661067,1661258,1661448,1661464,1661486,1662245-1662246,1663017,1663647,1664071,1664133,1664205,1664299,1664709,1665215,1665218,1665625,1665643,1665721,1666297,1666361,1666363,1666468,1666618,1666998,1667385-1667386,1668532,1668535,1668553,1669130,1669289,1669292,1670434,1671364,1671396-1671397,1671918,1672289,1672453,1672466,1672480,1672483,1672564,1672757,1672985,1672989,1673113,1673155,1673368,1673455,1673769,1674056,1674538,1674542,1674606,1674632,1674697,1675103,1675410,1675533,1676085,1676654,1676709,1676842,1677096,1677143-1677146,1677149,1677151,1677153-1677156,1677159,1677339,1677462,1677702,1677830,1677832,1677834-1677835,1678763,1679032,1679181-1679182,1679192,1679428,1679432,1679470,1679620,1679712,1680276,1680895,1680900,1680942,1681037,1681424,1681440,1681685,1681694,1681795,1682482,1682816,1682819,1682907,1682923,1682937,1682979,1682988,1683044,1683047,1683123,1683881,1683884,1684057,1684171,1684900,1685069,1685339,1685345,1685347,1685349-1685350,1685650,1685
 659,1685779,1686085,1686853,1686856,1687539,1687680,1687980,1688274,1688331,1688339-1688341,1688343,1688399,1688474-1688475,1688536,1688538,1688660,1689325,1689605,1689694,1689698,1690120,1690137,1690248,1691374,1691582,1691592,1691819,1691908,1692285,1692432,1692486,1692516,1693792,1693918-1693919,1693963,1694903,1694936,1694950-1694951,1695170,1695727,1695874,1695885,1695920,1696105,1696264,1696266,1696279,1696428,1696442,1696565,1696592,1696607,1696755,1696881,1697013,1697015,1697051,1697323,1697339,1697370,1697389,1697446,1697543,1697634,1697855,1698023,1698103,1698107,1698116,1698133,1698330,1700271,1700275,1700317-1700322,1700326,1700328,1700330-1700332,1700334,1700336,1700338,1700418,1700514,1700777,1700851,1700917,1700925,1700968,1701005,1701145,1701178,1701204,1701347,1701436,1701545,1701717,1702643,1702919,1703152,1703417,1703642,1703807,1703813,1703822,1703871,1703902,1703952,1704099,1704241,1704262,1704797,1704799,1704826,1705099,1705134,1705194,1705217,1705257,1705749,1
 705776,1705823,1705826,1705828,1705833,1705983,1706275,1706627,1706635,1706637,1706640,1706918,1706942,1706989,1707002,1707230-1707231,1707497,1707519,1707591,1707626-1707627,1707640,1707831,1707883,1707889,1708107,1709008,1709587,1709596,1709602,1709995,1710095,1710105,1710231,1710380,1710391,1710419,1710572,1710583,1710723,1711479,1711553,1711648,1711728,1711902,1712382,1713040,1713209,1713937,1715023,1715255,1715273,1715567-1715568,1715570-1715572,1715576,1715581-1715585,1715886,1716211,1716388,1716460,1716487,1716660,1716940,1717063,1717086,1717639,1717816,1717934,1717958,1717975,1717985,1718314,1718338,1718400,1718514,1718556,1718569,1718598,1719016,1719018,1719189-1719190,1719252,1719254-1719255,1719257,1719967,1720129,1720996,1721313,1721685,1721899,1722137,1722154,1722177,1722195,1722229,1722320,1722328,1722334,1722350-1722351,1722358,1722377,1722572,1722701,1723122,1723143,1723284,1723295,1723567,1723953,1724847,1724857,1724879,1724992-1724993,1724995,1725018,1725031,172509
 0,1725120,1725149,1725325,1725328,1725387,1725392,1725394-1725395,1725445,1725468,1725485,1725489,1725498-1725499,1725516,1725523,1725545,1725567,1725581,1725602,1725822,1725940,1725967,1726009,1726026,1726038,1726049,1726051-1726052,1726055,1726086,1726167,1726233,1726798,1726881,1726888,1727071,1727111,1727317,1727544,1727573,1727603,1727842,1728326,1728804,1729208,1729374,1729376,1729826,1729847,1729929-1729931,1729960,1730297,1730640,1730723,1730865,1731929,1732228,1732252,1732353,1732369,1732716,1732954,1732986,1733056,1733064,1733068,1733088-1733089,1733275,1733523,1733537,1733691,1734006,1734125,1734239,1734294,1734412,1734561,1734807,1734817,1734947,1734955,1734989,1735088,1735159,1735337,1735608-1735609,1735611,1735668,1735786,1735931,1735935,1735942,1735952,1736156,1736243,1736250,1736463,1736681,1736686,1737006,1737014,1737020-1737021,1737102,1737114,1737125,1737254,1737256,1737265,1737447,1737449,1737451,1737476,1738217,1738331,1738333,1738563,1739008,1739146,1739151,173
 9193,1739303,1739312,1739738,1739932,1740075,1740084,1740108,1740110,1740155,1740735,1741045,1741065,1741112,1741115,1741268,1741310,1741392,1741414,1741446,1741461,1741557,1741564,1741596,1741621,1741648,1741934,1742005,1742135,1742260,1742359,1742444-1742447,1742460,1742791-1742792,1743335,1743517,1743699,1743788,1743816,1744203-1744204,1744206,1744283,1744415,1744421,1744458-1744459,1744712,1744751,1744767,1744778,1744980,1745034,1745175,1745767,1745835,1746207,1746647,1746988,1747170,1747531,1747550,1747735,1747808,1747810,1747946,1748047,1748155,1748368,1748448,1748531,1748653,1748888,1749151,1749401,1749404,1749505,1749658-1749659,1749676,1749678,1749695,1749924-1749925,1750043,1750218,1750335,1750392,1750407,1750412,1750416,1750420,1750474,1750494,1750507-1750508,1750553,1750567,1750750,1750779,1750854-1750855,1750947,1750955,1750960,1751970,1752087,1752096,1752145,1752347,1752415,1753167,1753224,1753228-1753229,1753257,1753315-1753316,1753498,1753541,1753592,1753594,1753777,
 1754129,1754391,1754399,1754414,1754534,1755323,1756038,1756611,1756844,1756846,1756852-1756853,1757010-1757011,1757524,1757534,1757540,1757662-1757663,1757985,1758003,1758083,1758307-1758311,1758446,1758558,1759984,1760018,1761434,1761477,1761479,1761548,1762517,1762703,1763158,1763246,1763613,1764005,1764040,1764236,1764243,1764255,1765318,1765328,1765357,1765420,1766097,1766129,1766308,1766424,1766691,1766851,1766857,1767128,1767180-1767181,1767553,1767564,1767803
+/httpd/httpd/trunk:1200475,1200478,1200482,1200491,1200496,1200513,1200550,1200556,1200580,1200605,1200612,1200614,1200639,1200646,1200656,1200667,1200679,1200699,1200702,1200955,1200957,1200961,1200963,1200968,1200975,1200977,1201032,1201042,1201111,1201194,1201198,1201202,1201443,1201450,1201460,1201956,1202236,1202453,1202456,1202886,1203400,1203491,1203632,1203714,1203859,1203980,1204630,1204968,1204990,1205061,1205075,1205379,1205885,1206291,1206472,1206587,1206850,1206940,1206978,1207719,1208753,1208835,1209053,1209085,1209417,1209432,1209461,1209601,1209603,1209618,1209623,1209741,1209754,1209766,1209776,1209797-1209798,1209811-1209812,1209814,1209908,1209910,1209913,1209916-1209917,1209947,1209952,1210067,1210080,1210120,1210124,1210130,1210148,1210219,1210221,1210252,1210284,1210336,1210378,1210725,1210892,1210951,1210954,1211351-1211352,1211364,1211490,1211495,1211528,1211663,1211680,1212872,1212883,1213338,1213380-1213381,1213391,1213399,1213567,1214003,1214005,1214015,12
 15514,1220462,1220467,1220493,1220524,1220570,1220768,1220794,1220826,1220846,1221205,1221292,1222335,1222370,1222473,1222915,1222917,1222921,1222930,1223048,1225060,1225197-1225199,1225223,1225380,1225476,1225478,1225791,1225795-1225796,1226339,1226375,1227910,1228700,1228816,1229024,1229059,1229099,1229116,1229134,1229136,1229930,1230286,1231255,1231257,1231442,1231446,1231508,1231510,1231518,1232575,1232594,1232630,1232838,1234180,1234297,1234479,1234511,1234565,1234574,1234642-1234643,1234876,1234899,1235019,1236122,1236701,1237407,1238545,1238768,1239029-1239030,1239071,1239565,1240315,1240470,1240778,1241069,1241071,1242089,1242798,1242967,1243176,1243246,1243797,1243799,1244211,1245717,1290823,1290835,1291819-1291820,1291834,1291840,1292043,1293405,1293534-1293535,1293658,1293678,1293708,1294306,1294349,1294356,1294358,1294372,1294471,1297560,1299718,1299786,1300766,1301111,1301725,1302444,1302483,1302653,1302665,1302674,1303201,1303435,1303827,1304087,1304874-1304875,1305167
 ,1305586,1306350,1306409,1306426,1306841,1307790,1308327,1308459,1309536,1309567,1311468,1324760,1325218,1325227,1325250,1325265,1325275,1325632,1325724,1326980,1326984,1326991,1327689,1328325-1328326,1328339,1328345,1328950,1330189,1330964,1331110,1331115,1331942,1331977,1332378,1333969,1334343,1335882,1337344,1341906,1341913,1343085,1343087,1343094,1343099,1343109,1343935,1345319,1345329,1346905,1347980,1348036,1348653,1348656,1348660,1349905,1351012-1351020,1351071-1351072,1351074,1351737,1352047,1352534,1352909-1352912,1357685,1358061,1359057,1359881,1359884,1361153,1361298,1361766,1361773,1361778,1361784,1361791-1361792,1361801,1361803,1362020,1362538,1362707,1363035,1363183,1363186,1363312,1363440,1363557,1363589,1363829,1363832,1363836-1363837,1363853,1364133,1364138,1364229,1364601,1364695,1365001,1365020,1365029,1365479,1366319,1366344,1366621,1367778,1367819,1368053,1368058,1368094,1368121,1368131,1368393,1368396,1369419,1369568,1369604,1369618,1369904,1369995,1369999,1370
 001,1370466,1370592,1370615-1370616,1370763,1371387,1371791,1371801,1371878,1371903,1373270,1373447,1373898,1373955,1374157,1374199,1374247,1374874,1374877,1374880,1375006,1375009,1375011,1375013,1375584,1376695,1376700,1378178,1383490,1384408,1384913,1386576,1386578,1386726,1386822,1386880,1386913,1387085,1387088,1387110,1387389,1387444,1387603,1387607,1387633,1387693,1387979,1388029,1388445,1388447,1388648,1388660,1388825,1388899,1389316,1389339,1389481,1389506,1389564,1389566-1389569,1390562,1390564,1391396,1391398,1391771,1392120,1392122,1392150,1392214,1392345-1392347,1392850,1393033,1393058,1393152,1393338,1393564,1394079,1395225,1395253-1395256,1395792,1396440,1397172,1397320,1397636,1397687,1397710,1397716,1398025,1398040,1398066,1398478,1398480-1398481,1398970,1399413,1399687,1399708,1400700,1401448,1402924,1403476,1403483,1403492,1404653,1405407,1405856,1405973,1406068,1406493,1406495,1406616,1406646,1406719,1406760,1407004,1407006,1407085,1407088,1407248,1407381,1407459-1
 407460,1407528,1407599,1407643,1407853,1407965,1408093,1408402,1408958,1408961,1409170,1409437,1409726,1409800,1410681,1410954,1411862,1412278,1413732,1414094,1415008,1415023,1415075,1416121,1416150,1416278,1417197,1417440,1417529,1418524,1418556,1418648,1418655,1418703,1418721,1418752,1418769,1419084,1419719,1419726,1419755,1419781,1419796,1420120,1420124,1420149,1420184,1420644,1420685-1420686,1420975,1421288,1421323,1421851,1421912,1421953,1422135,1422549,1422594,1422712,1422855,1422937,1422943,1422980,1423353,1423933,1425360,1425366,1425771-1425772,1425775,1425777,1425874,1426827,1426850,1426877,1426879,1426975,1426988,1426992,1427546,1428184,1428280,1428916,1429228,1429559,1429561,1429564,1429582,1430575,1430814,1430869,1433001,1433613,1433682,1433861,1433988,1435178,1435811,1436058,1436401,1439083,1439106,1439114,1439404,1439623,1442309,1442320,1442326,1442412,1442759,1442865,1447993,1448171,1448453,1451478,1451484,1451633,1451849,1451905,1451921,1452128,1452195,1452259,145228
 1,1452551,1452911,1452949,1452954,1453022,1453574,1453604,1453875-1453876,1453963,1453981,1454386,1454414-1454415,1454888,1457437,1457450,1457471,1457504,1457520-1457521,1457610,1457995,1458003-1458004,1458020,1458285,1458447,1458456,1462266,1462269,1462643,1463044-1463047,1463052,1463056,1463455,1463736,1463750,1463754,1464675,1464721,1464762,1465115-1465116,1465190,1467765,1468581,1470183,1470679,1470940,1471449,1475878,1476604,1476621,1476642,1476644-1476645,1476652,1476680,1477094,1477530,1478382,1478748,1479117,1479216,1479222,1479411,1479528,1479905,1479966,1480046,1480627,1481197,1481302,1481306,1481396-1481397,1481891,1482041,1482075,1482170,1482555,1482859,1482996,1483005,1483027,1483190,1484343,1484398,1484832,1484910,1484914,1485409,1485668,1486490,1487528,1487530,1488158,1488164,1488296,1488471,1488492,1488644,1490493,1490507,1490550,1490761,1490994,1491155,1491221,1491234,1491458,1491479,1491538,1491564,1491724,1492663,1492710,1492782,1493330,1493921,1493925,1494536,149
 5501,1496194,1496338,1496429,1496709,1497371,1497588,1498880,1499679,1500323,1500345,1500362,1500423,1500437,1500483,1500519,1501294,1501369,1501399,1501913,1502665,1502772,1503680,1503866,1503990-1503991,1504276,1506474,1506714,1509872,1509983,1510084-1510085,1510098,1510588,1510707,1511093,1513492,1513508,1514039,1514064,1514214-1514215,1514255,1514267,1514617,1515050,1515162,1515403,1515411,1515420,1517025,1517045,1517175,1517366,1517386,1517388,1518265,1518269,1519475,1520368,1520445,1520760,1520908,1521909,1523235,1523239,1523281,1523387,1524101,1524158,1524192,1524368,1524388,1524770,1525276,1525280-1525281,1525931,1526168,1526189,1526647,1526666,1527008,1527220,1527291,1527294-1527295,1527509,1527925-1527926,1528143,1528718,1529014,1529277,1529449,1529559,1529988,1529991,1530793,1531340,1531370,1531505,1531672,1531961-1531962,1532746,1532816,1533065,1533224,1534321,1534754,1534890,1534892,1536310,1537535,1538490,1540051-1540052,1541181,1541270,1541368,1542338,1542379,1542533,
 1542562,1542615,1543020,1543147,1543149,1543174,1544381,1544774,1544784,1544812,1544820,1545286,1545292,1545325,1545364,1545408,1545411,1546692-1546693,1546730,1546759-1546760,1546801,1546804-1546805,1546835-1546836,1547845,1550061,1550302,1550307,1551685,1551714,1551802,1552130,1552227,1553204,1553824,1554161,1554168,1554170,1554175-1554176,1554179,1554181,1554184,1554188,1554192,1554195,1554276,1554281,1554300-1554301,1554994-1554995,1555240,1555259,1555266,1555423-1555424,1555463-1555464,1555467,1555555,1555569,1556206,1556428,1556911-1556912,1556914,1556937,1557317,1557617,1558483,1559351,1559828,1560367,1560546,1560679,1560689,1560729,1560977,1560979,1561137,1561262,1561385,1561660,1561923,1562472,1563193,1563379,1563381,1563417-1563418,1563420,1564052,1564437,1564475,1564756,1564760,1565081,1565711,1568404,1569615,1570288,1570598,1571369,1572092,1572198,1572543,1572561,1572611,1572630,1572655,1572663,1572668-1572671,1572896,1572905,1572911,1572967,1573224,1573229,1573626,15741
 51,1575400,1576233,1576741,1578760,1578762,1580568,1583005,1583007-1583008,1583027,1583175,1583191,1584098,1584430,1584434,1584572,1584653,1584658,1584665,1584703,1584878,1584884,1584896,1585054,1585072,1585090,1585435,1585609,1585824,1585918-1585919,1586745,1586827,1587036,1587040,1587053,1587255,1587594,1587607,1587639,1587654,1588054,1588065,1588213,1588330,1588427,1588519,1588527,1588704,1588851,1588853,1588868,1589413,1590437,1590509,1591143,1591320,1591322,1591328,1591390,1591394,1591401,1591472,1591508,1592032,1592037,1592500,1592511,1592514,1592529,1592615,1592632,1593745,1594625,1594643,1594648,1595305,1595321,1595426,1597182,1597349,1597352,1597639,1597642,1598107,1598946,1599535,1601076,1601184-1601185,1601274,1601291,1601624,1601630,1601919,1601995,1602338,1602978,1602989,1603027,1603029,1603122,1603156,1603915,1604382,1604461,1604631,1605207,1605827,1605829,1607960,1608284,1608785,1608999,1609914,1609936,1609938,1610207,1610311,1610353,1610366,1610491,1610652,1610674,16
 11165,1611169,1611244,1611600,1611871,1611978,1612068,1615026,1615289,1617018,1618401,1618541,1619297,1619383,1619444,1619483,1619835,1620324,1620461,1620932,1621367,1621372,1621417,1621453,1621806,1622450,1624234,1624349,1625196,1625952,1626050,1626978,1628104,1628918-1628919,1628924,1628950,1629235,1629239,1629244,1629250,1629372,1629440-1629441,1629485,1629507-1629508,1629519,1629577,1629652,1629916,1631885,1632454,1632740,1632742,1633730-1633731,1633793,1634120,1634237,1634425,1634736,1634836,1635510,1635558,1635644-1635645,1635762,1637112,1638072-1638073,1638879,1639614,1640031,1640036,1640040,1640042,1640331,1641077,1641095,1641376,1642099,1642484,1642499,1642847,1642868,1643034,1643284,1643537,1643825,1644245,1646282,1646724,1647035,1648201,1648394,1648433,1648719,1648840,1649001,1649043,1649632,1649966,1650047,1650061,1650309-1650310,1650320,1651088,1652829,1652929,1652931,1652955,1652982,1652985,1652989,1653941,1653978,1653997,1656225,1656669,1657256,1657261,1657636,1657638
 ,1657685,1657881,1657897,1658760,1658765,1661067,1661258,1661448,1661464,1661486,1662245-1662246,1663017,1663647,1664071,1664133,1664205,1664299,1664709,1665215,1665218,1665625,1665643,1665721,1666297,1666361,1666363,1666468,1666618,1666998,1667385-1667386,1668532,1668535,1668553,1669130,1669289,1669292,1670434,1671364,1671396-1671397,1671918,1672289,1672453,1672466,1672480,1672483,1672564,1672757,1672985,1672989,1673113,1673155,1673368,1673455,1673769,1674056,1674538,1674542,1674606,1674632,1674697,1675103,1675410,1675533,1676085,1676654,1676709,1676842,1677096,1677143-1677146,1677149,1677151,1677153-1677156,1677159,1677339,1677462,1677702,1677830,1677832,1677834-1677835,1678763,1679032,1679181-1679182,1679192,1679428,1679432,1679470,1679620,1679712,1680276,1680895,1680900,1680942,1681037,1681424,1681440,1681685,1681694,1681795,1682482,1682816,1682819,1682907,1682923,1682937,1682979,1682988,1683044,1683047,1683123,1683881,1683884,1684057,1684171,1684900,1685069,1685339,1685345,1685
 347,1685349-1685350,1685650,1685659,1685779,1686085,1686853,1686856,1687539,1687680,1687980,1688274,1688331,1688339-1688341,1688343,1688399,1688474-1688475,1688536,1688538,1688660,1689325,1689605,1689694,1689698,1690120,1690137,1690248,1691374,1691582,1691592,1691819,1691908,1692285,1692432,1692486,1692516,1693792,1693918-1693919,1693963,1694903,1694936,1694950-1694951,1695170,1695727,1695874,1695885,1695920,1696105,1696264,1696266,1696279,1696428,1696442,1696565,1696592,1696607,1696755,1696881,1697013,1697015,1697051,1697323,1697339,1697370,1697389,1697446,1697543,1697634,1697855,1698023,1698103,1698107,1698116,1698133,1698330,1700271,1700275,1700317-1700322,1700326,1700328,1700330-1700332,1700334,1700336,1700338,1700418,1700514,1700777,1700851,1700917,1700925,1700968,1701005,1701145,1701178,1701204,1701347,1701436,1701545,1701717,1702643,1702919,1703152,1703417,1703642,1703807,1703813,1703822,1703871,1703902,1703952,1704099,1704241,1704262,1704797,1704799,1704826,1705099,1705134,1
 705194,1705217,1705257,1705749,1705776,1705823,1705826,1705828,1705833,1705983,1706275,1706627,1706635,1706637,1706640,1706918,1706942,1706989,1707002,1707230-1707231,1707497,1707519,1707591,1707626-1707627,1707640,1707831,1707883,1707889,1708107,1709008,1709587,1709596,1709602,1709995,1710095,1710105,1710231,1710380,1710391,1710419,1710572,1710583,1710723,1711479,1711553,1711648,1711728,1711902,1712382,1713040,1713209,1713937,1715023,1715255,1715273,1715567-1715568,1715570-1715572,1715576,1715581-1715585,1715886,1716211,1716388,1716460,1716487,1716660,1716940,1717063,1717086,1717639,1717816,1717934,1717958,1717975,1717985,1718314,1718338,1718400,1718514,1718556,1718569,1718598,1719016,1719018,1719189-1719190,1719252,1719254-1719255,1719257,1719967,1720129,1720996,1721313,1721685,1721899,1722137,1722154,1722177,1722195,1722229,1722320,1722328,1722334,1722350-1722351,1722358,1722377,1722572,1722701,1723122,1723143,1723284,1723295,1723567,1723953,1724847,1724857,1724879,1724992-172499
 3,1724995,1725018,1725031,1725090,1725120,1725149,1725325,1725328,1725387,1725392,1725394-1725395,1725445,1725468,1725485,1725489,1725498-1725499,1725516,1725523,1725545,1725567,1725581,1725602,1725822,1725940,1725967,1726009,1726026,1726038,1726049,1726051-1726052,1726055,1726086,1726167,1726233,1726798,1726881,1726888,1727071,1727111,1727317,1727544,1727573,1727603,1727842,1728326,1728804,1729208,1729374,1729376,1729826,1729847,1729929-1729931,1729960,1730297,1730640,1730723,1730865,1731929,1732228,1732252,1732353,1732369,1732716,1732954,1732986,1733056,1733064,1733068,1733088-1733089,1733275,1733523,1733537,1733691,1734006,1734125,1734239,1734294,1734412,1734561,1734807,1734817,1734947,1734955,1734989,1735088,1735159,1735337,1735608-1735609,1735611,1735668,1735786,1735931,1735935,1735942,1735952,1736156,1736243,1736250,1736463,1736681,1736686,1737006,1737014,1737020-1737021,1737102,1737114,1737125,1737254,1737256,1737265,1737447,1737449,1737451,1737476,1738217,1738331,1738333,173
 8563,1739008,1739146,1739151,1739193,1739303,1739312,1739738,1739932,1740075,1740084,1740108,1740110,1740155,1740735,1741045,1741065,1741112,1741115,1741268,1741310,1741392,1741414,1741446,1741461,1741557,1741564,1741596,1741621,1741648,1741934,1742005,1742135,1742260,1742359,1742444-1742447,1742460,1742791-1742792,1743335,1743517,1743699,1743788,1743816,1744203-1744204,1744206,1744283,1744415,1744421,1744458-1744459,1744712,1744751,1744767,1744778,1744980,1745034,1745175,1745767,1745835,1746207,1746647,1746988,1747170,1747531,1747550,1747735,1747808,1747810,1747946,1748047,1748155,1748368,1748448,1748531,1748653,1748888,1749151,1749401,1749404,1749505,1749658-1749659,1749676,1749678,1749695,1749924-1749925,1750043,1750218,1750335,1750392,1750407,1750412,1750416,1750420,1750474,1750494,1750507-1750508,1750553,1750567,1750750,1750779,1750854-1750855,1750947,1750955,1750960,1751970,1752087,1752096,1752145,1752347,1752415,1753167,1753224,1753228-1753229,1753257,1753315-1753316,1753498,
 1753541,1753592,1753594,1753777,1754129,1754391,1754399,1754414,1754534,1755323,1756038,1756611,1756844,1756846,1756852-1756853,1757010-1757011,1757524,1757534,1757540,1757662-1757663,1757985,1758003,1758083,1758307-1758311,1758446,1758558,1759984,1760018,1761434,1761477,1761479,1761548,1762517,1762703,1763158,1763246,1763613,1764005,1764040,1764236,1764243,1764255,1765318,1765328,1765357,1765420,1766097,1766129,1766308,1766424,1766691,1766851,1766857,1767128,1767180-1767181,1767553,1767564,1767803

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/CHANGES?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/CHANGES [utf-8] Fri Nov  4 14:20:16 2016
@@ -2,6 +2,9 @@
 
 Changes with Apache 2.4.24
 
+  *) core, http: Extend HttpProtocol with an option to enforce stricter HTTP
+     conformance or to only log the found problems. [Stefan Fritsch]
+
   *) core: Correctly parse an IPv6 literal host specification in an absolute
      URL in the request line. [Stefan Fritsch]
 

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/include/ap_mmn.h?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/include/ap_mmn.h Fri Nov  4 14:20:16 2016
@@ -488,6 +488,8 @@
  * 20120211.66 (2.4.24-dev) Rename ap_proxy_check_backend() to
  *                          ap_proxy_check_connection().
  * 20120211.67 (2.5.0-dev)  Add http09_enable to core_server_config
+ *                          Add http_conformance to core_server_config,
+ *                          add ap_has_cntrl()
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/include/http_core.h?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/include/http_core.h (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/include/http_core.h Fri Nov  4 14:20:16 2016
@@ -731,6 +731,11 @@ typedef struct {
 #define AP_HTTP09_DISABLE 2
     char http09_enable;
 
+#define AP_HTTP_CONFORMANCE_UNSET     0
+#define AP_HTTP_CONFORMANCE_LIBERAL   1
+#define AP_HTTP_CONFORMANCE_STRICT    2
+#define AP_HTTP_CONFORMANCE_LOGONLY   4
+    char http_conformance;
 } core_server_config;
 
 /* for AddOutputFiltersByType in core.c */

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/include/httpd.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/include/httpd.h?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/include/httpd.h (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/include/httpd.h Fri Nov  4 14:20:16 2016
@@ -2317,6 +2317,15 @@ AP_DECLARE(char *) ap_get_exec_line(apr_
                                     const char *cmd,
                                     const char * const *argv);
 
+/**
+ * Check if string contains a control character
+ * @param str the string to check
+ * @param srclen length of the data
+ * @return 1 if yes, 0 if no control characters
+ */
+AP_DECLARE(int) ap_has_cntrl(const char *str)
+                AP_FN_ATTR_NONNULL_ALL;
+
 #define AP_NORESTART APR_OS_START_USEERR + 1
 
 /**

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/modules/http/http_filters.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/modules/http/http_filters.c?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/modules/http/http_filters.c (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/modules/http/http_filters.c Fri Nov  4 14:20:16 2016
@@ -668,14 +668,91 @@ apr_status_t ap_http_filter(ap_filter_t
     return APR_SUCCESS;
 }
 
+struct check_header_ctx {
+    request_rec *r;
+    int error;
+};
+
+/* check a single header, to be used with apr_table_do() */
+static int check_header(void *arg, const char *name, const char *val)
+{
+    struct check_header_ctx *ctx = arg;
+    if (name[0] == '\0') {
+        ctx->error = 1;
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02428)
+                      "Empty response header name, aborting request");
+        return 0;
+    }
+    if (ap_has_cntrl(name)) {
+        ctx->error = 1;
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02429)
+                      "Response header name '%s' contains control "
+                      "characters, aborting request",
+                      name);
+        return 0;
+    }
+    if (ap_has_cntrl(val)) {
+        ctx->error = 1;
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, ctx->r, APLOGNO(02430)
+                      "Response header '%s' contains control characters, "
+                      "aborting request: %s",
+                      name, val);
+        return 0;
+    }
+    return 1;
+}
+
+/**
+ * Check headers for HTTP conformance
+ * @return 1 if ok, 0 if bad
+ */
+static APR_INLINE int check_headers(request_rec *r)
+{
+    const char *loc;
+    struct check_header_ctx ctx = { r, 0 };
+
+    apr_table_do(check_header, &ctx, r->headers_out, NULL);
+    if (ctx.error)
+        return 0; /* problem has been logged by check_header() */
+
+    if ((loc = apr_table_get(r->headers_out, "Location")) != NULL) {
+        const char *scheme_end = ap_strchr_c(loc, ':');
+        const char *s = loc;
+
+        /*
+         * Check that the URI has a valid scheme and is absolute
+         * XXX Should we do a full uri parse here?
+         */
+        if (scheme_end == NULL || scheme_end == loc)
+            goto bad;
+
+        do {
+            if ((!apr_isalnum(*s) && *s != '.' && *s != '+' && *s != '-')
+                || !apr_isascii(*s) ) {
+                goto bad;
+            }
+        } while (++s < scheme_end);
+
+        if (scheme_end[1] != '/' || scheme_end[2] != '/')
+            goto bad;
+    }
+
+    return 1;
+
+bad:
+    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02431)
+                  "Bad Location header in response: '%s', aborting request",
+                  loc);
+    return 0;
+}
+
 typedef struct header_struct {
     apr_pool_t *pool;
     apr_bucket_brigade *bb;
 } header_struct;
 
 /* Send a single HTTP header field to the client.  Note that this function
- * is used in calls to table_do(), so their interfaces are co-dependent.
- * In other words, don't change this one without checking table_do in alloc.c.
+ * is used in calls to apr_table_do(), so don't change its interface.
  * It returns true unless there was a write error of some kind.
  */
 static int form_header_field(header_struct *h,
@@ -1175,6 +1252,7 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
     header_filter_ctx *ctx = f->ctx;
     const char *ctype;
     ap_bucket_error *eb = NULL;
+    core_server_config *conf;
 
     AP_DEBUG_ASSERT(!r->main);
 
@@ -1230,6 +1308,15 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
                                            r->headers_out);
     }
 
+    conf = ap_get_core_module_config(r->server->module_config);
+    if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
+        int ok = check_headers(r);
+        if (!ok && !(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
+            ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
+            return AP_FILTER_ERROR;
+        }
+    }
+
     /*
      * Remove the 'Vary' header field if the client can't handle it.
      * Since this will have nasty effects on HTTP/1.1 caches, force

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/core.c?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/server/core.c (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/server/core.c Fri Nov  4 14:20:16 2016
@@ -522,6 +522,9 @@ static void *merge_core_server_configs(a
     if (virt->http09_enable != AP_HTTP09_UNSET)
         conf->http09_enable = virt->http09_enable;
 
+    if (virt->http_conformance != AP_HTTP_CONFORMANCE_UNSET)
+        conf->http_conformance = virt->http_conformance;
+
     /* no action for virt->accf_map, not allowed per-vhost */
 
     if (virt->protocol)
@@ -3911,10 +3914,27 @@ static const char *set_http_protocol(cmd
         else if (strcmp(arg, "1.0") == 0)
             conf->http09_enable = AP_HTTP09_DISABLE;
         else
-            return "HttpProtocol min must be one of '0.9' and '1.0'";
-	return NULL;
+            return "HttpProtocol 'min' must be one of '0.9' and '1.0'";
+        return NULL;
+    }
+
+    if (strcmp(arg, "strict") == 0)
+        conf->http_conformance = AP_HTTP_CONFORMANCE_STRICT;
+    else if (strcmp(arg, "strict,log-only") == 0)
+        conf->http_conformance = AP_HTTP_CONFORMANCE_STRICT|
+                                 AP_HTTP_CONFORMANCE_LOGONLY;
+    else if (strcmp(arg, "liberal") == 0)
+        conf->http_conformance = AP_HTTP_CONFORMANCE_LIBERAL;
+    else
+        return "HttpProtocol accepts 'min=0.9', 'min=1.0', 'liberal', "
+               "'strict', 'strict,log-only'";
+
+    if ((conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) &&
+        (conf->http_conformance & AP_HTTP_CONFORMANCE_LIBERAL)) {
+        return "HttpProtocol 'strict' and 'liberal' are mutually exclusive";
     }
-    return "HttpProtocol must be min=0.9|1.0";
+
+    return NULL;
 }
 
 static const char *set_http_method(cmd_parms *cmd, void *conf, const char *arg)
@@ -4450,8 +4470,9 @@ AP_INIT_ITERATE("Protocols", set_protoco
 AP_INIT_TAKE1("ProtocolsHonorOrder", set_protocols_honor_order, NULL, RSRC_CONF,
               "'off' (default) or 'on' to respect given order of protocols, "
               "by default the client specified order determines selection"),
-AP_INIT_TAKE1("HttpProtocol", set_http_protocol, NULL, RSRC_CONF,
-              "'min=0.9' (default) or 'min=1.0' to allow/deny HTTP/0.9"),
+AP_INIT_ITERATE("HttpProtocol", set_http_protocol, NULL, RSRC_CONF,
+              "'min=0.9' (default) or 'min=1.0' to allow/deny HTTP/0.9; "
+              "'liberal', 'strict', 'strict,log-only'"),
 AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
                 "Registers non-standard HTTP methods"),
 { NULL }

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/protocol.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/protocol.c?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/server/protocol.c (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/server/protocol.c Fri Nov  4 14:20:16 2016
@@ -562,6 +562,9 @@ static int read_request_line(request_rec
     char http[5];
     apr_size_t len;
     int num_blank_lines = DEFAULT_LIMIT_BLANK_LINES;
+    core_server_config *conf = ap_get_core_module_config(r->server->module_config);
+    int strict = conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT;
+    int enforce_strict = !(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY);
 
     /* Read past empty lines until we get a real request line,
      * a read error, the connection closes (EOF), or we timeout.
@@ -648,8 +651,6 @@ static int read_request_line(request_rec
         pro = ll;
         len = strlen(ll);
     } else {
-        core_server_config *conf;
-        conf = ap_get_core_module_config(r->server->module_config);
         r->assbackwards = 1;
         pro = "HTTP/0.9";
         len = 8;
@@ -674,12 +675,59 @@ static int read_request_line(request_rec
         && apr_isdigit(pro[7])) {
         r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0');
     }
-    else if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor)
-             && (strcasecmp("http", http) == 0)
-             && (minor < HTTP_VERSION(1, 0)) ) /* don't allow HTTP/0.1000 */
-        r->proto_num = HTTP_VERSION(major, minor);
-    else
-        r->proto_num = HTTP_VERSION(1, 0);
+    else {
+        if (strict) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02418)
+                          "Invalid protocol '%s'", r->protocol);
+            if (enforce_strict) {
+                r->status = HTTP_BAD_REQUEST;
+                return 0;
+            }
+        }
+        if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor)
+            && (strcasecmp("http", http) == 0)
+            && (minor < HTTP_VERSION(1, 0)) ) { /* don't allow HTTP/0.1000 */
+            r->proto_num = HTTP_VERSION(major, minor);
+        }
+        else {
+            r->proto_num = HTTP_VERSION(1, 0);
+        }
+    }
+
+    if (strict) {
+        int err = 0;
+        if (ap_has_cntrl(r->the_request)) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02420)
+                          "Request line must not contain control characters");
+            err = HTTP_BAD_REQUEST;
+        }
+        if (r->parsed_uri.fragment) {
+            /* RFC3986 3.5: no fragment */
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02421)
+                          "URI must not contain a fragment");
+            err = HTTP_BAD_REQUEST;
+        }
+        else if (r->parsed_uri.user || r->parsed_uri.password) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02422)
+                          "URI must not contain a username/password");
+            err = HTTP_BAD_REQUEST;
+        }
+        else if (r->method_number == M_INVALID) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02423)
+                          "Invalid HTTP method string: %s", r->method);
+            err = HTTP_NOT_IMPLEMENTED;
+        }
+        else if (r->assbackwards == 0 && r->proto_num < HTTP_VERSION(1, 0)) {
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02424)
+                          "HTTP/0.x does not take a protocol");
+            err = HTTP_BAD_REQUEST;
+        }
+
+        if (err && enforce_strict) {
+            r->status = err;
+            return 0;
+        }
+    }
 
     return 1;
 }
@@ -723,6 +771,7 @@ AP_DECLARE(void) ap_get_mime_headers_cor
     apr_size_t len;
     int fields_read = 0;
     char *tmp_field;
+    core_server_config *conf = ap_get_core_module_config(r->server->module_config);
 
     /*
      * Read header lines until we get the empty separator line, a read error,
@@ -876,6 +925,33 @@ AP_DECLARE(void) ap_get_mime_headers_cor
                     *tmp_field-- = '\0';
                 }
 
+                if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
+                    int err = 0;
+
+                    if (*last_field == '\0') {
+                        err = HTTP_BAD_REQUEST;
+                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02425)
+                                      "Empty request header field name not allowed");
+                    }
+                    else if (ap_has_cntrl(last_field)) {
+                        err = HTTP_BAD_REQUEST;
+                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02426)
+                                      "[HTTP strict] Request header field name contains "
+                                      "control character: %.*s",
+                                      (int)LOG_NAME_MAX_LEN, last_field);
+                    }
+                    else if (ap_has_cntrl(value)) {
+                        err = HTTP_BAD_REQUEST;
+                        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02427)
+                                      "Request header field '%.*s' contains"
+                                      "control character", (int)LOG_NAME_MAX_LEN,
+                                      last_field);
+                    }
+                    if (err && !(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
+                        r->status = err;
+                        return;
+                    }
+                }
                 apr_table_addn(r->headers_in, last_field, value);
 
                 /* reset the alloc_len so that we'll allocate a new
@@ -925,7 +1001,7 @@ request_rec *ap_read_request(conn_rec *c
     request_rec *r;
     apr_pool_t *p;
     const char *expect;
-    int access_status = HTTP_OK;
+    int access_status;
     apr_bucket_brigade *tmp_bb;
     apr_socket_t *csd;
     apr_interval_time_t cur_timeout;
@@ -984,9 +1060,11 @@ request_rec *ap_read_request(conn_rec *c
 
     /* Get the request... */
     if (!read_request_line(r, tmp_bb)) {
-        if (r->status == HTTP_REQUEST_URI_TOO_LARGE
-            || r->status == HTTP_BAD_REQUEST
-            || r->status == HTTP_VERSION_NOT_SUPPORTED) {
+        switch (r->status) {
+        case HTTP_REQUEST_URI_TOO_LARGE:
+        case HTTP_BAD_REQUEST:
+        case HTTP_VERSION_NOT_SUPPORTED:
+        case HTTP_NOT_IMPLEMENTED:
             if (r->status == HTTP_REQUEST_URI_TOO_LARGE) {
                 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00565)
                               "request failed: client's request-line exceeds LimitRequestLine (longer than %d)",
@@ -1004,19 +1082,17 @@ request_rec *ap_read_request(conn_rec *c
             r = NULL;
             apr_brigade_destroy(tmp_bb);
             goto traceout;
-        }
-        else if (r->status == HTTP_REQUEST_TIME_OUT) {
+        case HTTP_REQUEST_TIME_OUT:
             ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, NULL);
-            if (!r->connection->keepalives) {
+            if (!r->connection->keepalives)
                 ap_run_log_transaction(r);
-            }
             apr_brigade_destroy(tmp_bb);
             goto traceout;
+        default:
+            apr_brigade_destroy(tmp_bb);
+            r = NULL;
+            goto traceout;
         }
-
-        apr_brigade_destroy(tmp_bb);
-        r = NULL;
-        goto traceout;
     }
 
     /* We may have been in keep_alive_timeout mode, so toggle back
@@ -1101,6 +1177,7 @@ request_rec *ap_read_request(conn_rec *c
      * now read. may update status.
      */
     ap_update_vhost_from_headers(r);
+    access_status = r->status;
 
     /* Toggle to the Host:-based vhost's timeout mode to fetch the
      * request body and send the response body, if needed.

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/util.c?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/server/util.c (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/server/util.c Fri Nov  4 14:20:16 2016
@@ -2189,6 +2189,16 @@ AP_DECLARE(void) ap_bin2hex(const void *
     *dest = '\0';
 }
 
+AP_DECLARE(int) ap_has_cntrl(const char *str)
+{
+    while (*str) {
+        if (apr_iscntrl(*str))
+            return 1;
+        str++;
+    }
+    return 0;
+}
+
 AP_DECLARE(int) ap_is_directory(apr_pool_t *p, const char *path)
 {
     apr_finfo_t finfo;

Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c?rev=1768036&r1=1768035&r2=1768036&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c (original)
+++ httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c Fri Nov  4 14:20:16 2016
@@ -747,6 +747,59 @@ static apr_status_t fix_hostname_non_v6(
     return APR_SUCCESS;
 }
 
+/*
+ * If strict mode ever becomes the default, this should be folded into
+ * fix_hostname_non_v6()
+ */
+static apr_status_t strict_hostname_check(request_rec *r, char *host,
+                                          int logonly)
+{
+    char *ch;
+    int is_dotted_decimal = 1, leading_zeroes = 0, dots = 0;
+
+    for (ch = host; *ch; ch++) {
+        if (!apr_isascii(*ch)) {
+            goto bad;
+        }
+        else if (apr_isalpha(*ch) || *ch == '-') {
+            is_dotted_decimal = 0;
+        }
+        else if (ch[0] == '.') {
+            dots++;
+            if (ch[1] == '0' && apr_isdigit(ch[2]))
+                leading_zeroes = 1;
+        }
+        else if (!apr_isdigit(*ch)) {
+           /* also takes care of multiple Host headers by denying commas */
+            goto bad;
+        }
+    }
+    if (is_dotted_decimal) {
+        if (host[0] == '.' || (host[0] == '0' && apr_isdigit(host[1])))
+            leading_zeroes = 1;
+        if (leading_zeroes || dots != 3) {
+            /* RFC 3986 7.4 */
+            goto bad;
+        }
+    }
+    else {
+        /* The top-level domain must start with a letter (RFC 1123 2.1) */
+        while (ch > host && *ch != '.')
+            ch--;
+        if (ch[0] == '.' && ch[1] != '\0' && !apr_isalpha(ch[1]))
+            goto bad;
+    }
+    return APR_SUCCESS;
+
+bad:
+    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02415)
+                  "[strict] Invalid host name '%s'%s%.6s",
+                  host, *ch ? ", problem near: " : "", ch);
+    if (logonly)
+        return APR_SUCCESS;
+    return APR_EINVAL;
+}
+
 /* Lowercase and remove any trailing dot and/or :port from the hostname,
  * and check that it is sane.
  *
@@ -760,22 +813,23 @@ static apr_status_t fix_hostname_non_v6(
  * Instead we just check for filesystem metacharacters: directory
  * separators / and \ and sequences of more than one dot.
  */
-static void fix_hostname(request_rec *r, const char *host_header)
+static int fix_hostname(request_rec *r, const char *host_header,
+                        unsigned http_conformance)
 {
     const char *src;
     char *host, *scope_id;
     apr_port_t port;
     apr_status_t rv;
     const char *c;
+    int is_v6literal = 0;
+    int strict = http_conformance & AP_HTTP_CONFORMANCE_STRICT;
+    int strict_logonly = http_conformance & AP_HTTP_CONFORMANCE_LOGONLY;
 
     src = host_header ? host_header : r->hostname;
 
-    /* According to RFC 2616, Host header field CAN be blank.
-     * XXX But only 'if the requested URI does not include an Internet host
-     * XXX name'. Can this happen?
-     */
+    /* According to RFC 2616, Host header field CAN be blank */
     if (!*src) {
-        return;
+        return is_v6literal;
     }
 
     /* apr_parse_addr_port will interpret a bare integer as a port
@@ -784,8 +838,16 @@ static void fix_hostname(request_rec *r,
     for (c = src; apr_isdigit(*c); ++c);
     if (!*c) {
         /* pure integer */
+        if (strict) {
+            /* RFC 3986 7.4 */
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02416)
+                         "[strict] purely numeric host names not allowed: %s",
+                         src);
+            if (!strict_logonly)
+                goto bad_nolog;
+        }
         r->hostname = src;
-        return;
+        return is_v6literal;
     }
 
     if (host_header) {
@@ -802,9 +864,7 @@ static void fix_hostname(request_rec *r,
             r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
         }
         if (host_header[0] == '[')
-            rv = fix_hostname_v6_literal(r, host);
-        else
-            rv = fix_hostname_non_v6(r, host);
+            is_v6literal = 1;
     }
     else {
         /*
@@ -813,24 +873,32 @@ static void fix_hostname(request_rec *r,
          */
         host = apr_pstrdup(r->pool, r->hostname);
         if (ap_strchr(host, ':') != NULL)
-            rv = fix_hostname_v6_literal(r, host);
-        else
-            rv = fix_hostname_non_v6(r, host);
+            is_v6literal = 1;
+    }
+
+    if (is_v6literal) {
+        rv = fix_hostname_v6_literal(r, host);
+    }
+    else {
+        rv = fix_hostname_non_v6(r, host);
+        if (strict && rv == APR_SUCCESS)
+            rv = strict_hostname_check(r, host, strict_logonly);
     }
     if (rv != APR_SUCCESS)
         goto bad;
+
     r->hostname = host;
-    return;
+    return is_v6literal;
 
 bad:
-    r->status = HTTP_BAD_REQUEST;
     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550)
                   "Client sent malformed Host header: %s",
-                  r->hostname);
-    return;
+                  src);
+bad_nolog:
+    r->status = HTTP_BAD_REQUEST;
+    return is_v6literal;
 }
 
-
 /* return 1 if host matches ServerName or ServerAliases */
 static int matches_aliases(server_rec *s, const char *host)
 {
@@ -1040,23 +1108,79 @@ static void check_serverpath(request_rec
     }
 }
 
+static APR_INLINE const char *construct_host_header(request_rec *r,
+                                                    int is_v6literal)
+{
+    struct iovec iov[5];
+    apr_size_t nvec = 0;
+    /*
+     * We cannot use ap_get_server_name/port here, because we must
+     * ignore UseCanonicalName/Port.
+     */
+    if (is_v6literal) {
+        iov[nvec].iov_base = "[";
+        iov[nvec].iov_len = 1;
+        nvec++;
+    }
+    iov[nvec].iov_base = (void *)r->hostname;
+    iov[nvec].iov_len = strlen(r->hostname);
+    nvec++;
+    if (is_v6literal) {
+        iov[nvec].iov_base = "]";
+        iov[nvec].iov_len = 1;
+        nvec++;
+    }
+    if (r->parsed_uri.port_str) {
+        iov[nvec].iov_base = ":";
+        iov[nvec].iov_len = 1;
+        nvec++;
+        iov[nvec].iov_base = r->parsed_uri.port_str;
+        iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
+        nvec++;
+    }
+    return apr_pstrcatv(r->pool, iov, nvec, NULL);
+}
 
 AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
 {
-    const char *host_header;
+    core_server_config *conf = ap_get_core_module_config(r->server->module_config);
+    const char *host_header = apr_table_get(r->headers_in, "Host");
+    int is_v6literal, have_hostname_from_url = 0;
 
     if (r->hostname) {
         /*
          * If there was a host part in the Request-URI, ignore the 'Host'
          * header.
          */
-        fix_hostname(r, NULL);
+        have_hostname_from_url = 1;
+        is_v6literal = fix_hostname(r, NULL, conf->http_conformance);
     }
-    else if ((host_header = apr_table_get(r->headers_in, "Host")) != NULL ) {
-        fix_hostname(r, host_header);
+    else if (host_header != NULL) {
+        is_v6literal = fix_hostname(r, host_header, conf->http_conformance);
     }
     if (r->status != HTTP_OK)
         return;
+
+    if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
+        /*
+         * If we have both hostname from an absoluteURI and a Host header,
+         * we must ignore the Host header (RFC 2616 5.2).
+         * To enforce this, we reset the Host header to the value from the
+         * request line.
+         */
+        if (have_hostname_from_url && host_header != NULL) {
+            const char *info = "Would replace";
+            const char *new = construct_host_header(r, is_v6literal);
+            if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
+                apr_table_set(r->headers_in, "Host", r->hostname);
+                info = "Replacing";
+            }
+            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
+                          "%s Host header '%s' with host from request uri: "
+                          "'%s'", info, host_header, new);
+        }
+    }
+
     /* check if we tucked away a name_chain */
     if (r->connection->vhost_lookup_data) {
         if (r->hostname)



Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Fri, Nov 4, 2016 at 11:40 AM, William A Rowe Jr <wr...@rowe-clan.net>
wrote:

>
> Give me about 24 hours to complete all this work, end of day today
> is my most optimistic timetable. Then we can discuss the resulting
> delta as a single unit/backport vote.  Because of a huge number of
> intervening commits to the relevant source files, mixing modern code
> changes based on nearly-4-year-old work in trunk is something of
> a nightmare (as we observed just syncing 2.2 to the state of the
> fixes already in 2.4.) I'll be starting a 2.2.current -> 2.4.current branch
> next, so the combination of that plus this trunk branch should get us
> to a parsing/strict observation shortly.
>

(If you do spot something amiss, you can quickly check against /trunk/
to see if the defect has been addressed already, then it will likely be
caught in my exhaustive backport list.)

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Fri, Nov 4, 2016 at 12:46 PM, Jacob Champion <ch...@gmail.com>
wrote:

> [spec discussion]
>
> On 11/04/2016 09:40 AM, William A Rowe Jr wrote:
>
>> On Fri, Nov 4, 2016 at 9:47 AM, Eric Covener <covener@gmail.com
>> <ma...@gmail.com>> wrote:
>>
>>> There is even an example with no scheme:
>>>
>>>         Location: /People.html#tim
>>>
>>
>> Not valid as a request (fragment not allowed)
>>
>
> ...but what does that have to do with the Location header? This is a valid
> and useful Location header value. (Clients won't send the fragment during
> the redirect; they'll save it to use during later presentation of the
> resource.)


Yup, this is an interesting point/question. Location header value !=
Request line URI value.

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Jacob Champion <ch...@gmail.com>.
[spec discussion]

On 11/04/2016 09:40 AM, William A Rowe Jr wrote:
> On Fri, Nov 4, 2016 at 9:47 AM, Eric Covener <covener@gmail.com
> <ma...@gmail.com>> wrote:
>> There is even an example with no scheme:
>>
>>         Location: /People.html#tim
>
> Not valid as a request (fragment not allowed)

...but what does that have to do with the Location header? This is a 
valid and useful Location header value. (Clients won't send the fragment 
during the redirect; they'll save it to use during later presentation of 
the resource.)

--Jacob

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Fri, Nov 4, 2016 at 9:47 AM, Eric Covener <co...@gmail.com> wrote:

> On Fri, Nov 4, 2016 at 10:20 AM,  <wr...@apache.org> wrote:
> >  * that the Location response header (if present) has a valid scheme and
> is
> >    absolute
>
> Too strict?
>
> https://tools.ietf.org/html/rfc7231#section-7.1.2
>
>    The "Location" header field is used in some responses to refer to a
>    specific resource in relation to the response.  The type of
>    relationship is defined by the combination of request method and
>    status code semantics.
>
>      Location = URI-reference
>
>    The field value consists of a single URI-reference.  When it has the
>    form of a relative reference ([RFC3986], Section 4.2), the final
>    value is computed by resolving it against the effective request URI
>    ([RFC3986], Section 5).
>
> There is even an example with no scheme:
>
>      Location: /People.html#tim
>

Not valid as a request (fragment not allowed)

Beyond this, you may want to pend questions since there is a *very*
long list of backports to get this fork in sync with httpd-2.x trunk.
Much of the initial code has been re-thought and will take me the
better part of the day to sequentially merge. For small groups of
simple patches without much issue, I'm collapsing them (with credits
and multiple rev no's) - especially where the 'next patch' undoes some
of the changes in the prior patch and momentary flaw can be ignored.

I still have some lingering questions, but this will get you the full
picture
of where the change came from when reviewing the overall delta between
2.4.now and 2.4.next.

Give me about 24 hours to complete all this work, end of day today
is my most optimistic timetable. Then we can discuss the resulting
delta as a single unit/backport vote.  Because of a huge number of
intervening commits to the relevant source files, mixing modern code
changes based on nearly-4-year-old work in trunk is something of
a nightmare (as we observed just syncing 2.2 to the state of the
fixes already in 2.4.) I'll be starting a 2.2.current -> 2.4.current branch
next, so the combination of that plus this trunk branch should get us
to a parsing/strict observation shortly.

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Nick Kew <ni...@apache.org>.
On Fri, 2016-11-04 at 10:47 -0400, Eric Covener wrote:

> Too strict?

Be conservative in what you send.  An Absolute URL
is never going to be the wrong thing to send.

> https://tools.ietf.org/html/rfc7231#section-7.1.2

Another change from the HTTP RFCs we learned, where
Location MUST be absolute.

Though in practice, there was a lot of confusion,
with the CGI spec - and hence serverside apps -
permitting the relative semantics.  Seems recent
HTTP came into line with CGI on this one.

-- 
Nick Kew


Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Eric Covener <co...@gmail.com>.
On Fri, Nov 4, 2016 at 10:20 AM,  <wr...@apache.org> wrote:
>  * that the Location response header (if present) has a valid scheme and is
>    absolute

Too strict?

https://tools.ietf.org/html/rfc7231#section-7.1.2

   The "Location" header field is used in some responses to refer to a
   specific resource in relation to the response.  The type of
   relationship is defined by the combination of request method and
   status code semantics.

     Location = URI-reference

   The field value consists of a single URI-reference.  When it has the
   form of a relative reference ([RFC3986], Section 4.2), the final
   value is computed by resolving it against the effective request URI
   ([RFC3986], Section 5).


There is even an example with no scheme:


     Location: /People.html#tim

-- 
Eric Covener
covener@gmail.com

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Jacob Champion <ch...@gmail.com>.
On 11/16/2016 04:32 AM, Ruediger Pluem wrote:
> (but what has precedence in this case host or request)

The "effective request URI", as defined by Section 5.5, seems to be 
pretty clear that if the request-target is absolute, the Host header is 
irrelevant:

    If the request-target is in absolute-form, the effective request URI
    is the same as the request-target.

Then it's just up to the server admin, I think, whether to be strict 
(4xx) or lenient (replace Host with the request-target authority) for 
non-compliant requests that mismatch the two.

I seem to remember an IETF conversation about this, but I'm having 
trouble finding it now. (The one about proxies keeps coming up, but 
that's not what I'm remembering...)

--Jacob

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Nov 16, 2016 20:29, "Jacob Champion" <ch...@gmail.com> wrote:
>
> On 11/16/2016 05:01 AM, William A Rowe Jr wrote:
>>
>> We need to tolerate their presence. But we should ignore the guidance
that
>> sf originally quoted, that the URI host supersedes the Host header, it
does
>> not, they are two different entities it the proxy case
>
>
> The "different entities" interpretation made sense to me too, but after
re-reading the spec and seeing what the browsers actually do, I'm not so
sure. (I'm a relative noob when it comes to the proxy sides of the spec, so
corrections are appreciated.)
>
> From section 5.4:
>
>    A client MUST send a Host header field in all HTTP/1.1 request
>    messages.  If the target URI includes an authority component, then a
>    client MUST send a field-value for Host that is identical to that
>    authority component, excluding any userinfo subcomponent and its "@"
>    delimiter (Section 2.7.1).  If the authority component is missing or
>    undefined for the target URI, then a client MUST send a Host header
>    field with an empty field-value.
>
> That's pretty absolute, and there doesn't seem to be an exception carved
out for proxies. And in practice, after giving Chromium and Firefox a try
with a local netcat "proxy", the Host headers they send are indeed derived
from the target URI, *not* the hostname of the HTTP proxy. I'd like to see
what other browsers do as well.
>
> This would appear to prevent name-based hosting of multiple proxies and
origin servers at the same IP address, which seems strange to me, given
that the Host header would be an appropriate resolution tool in that
case... so I'm hoping there's something I'm missing.
>
> Maybe no one needs to do that? Does anyone have experience with a
client/user-agent that makes use of name-based virtual proxies?
>
> --Jacob

Doh, that's right.

This is why we had such a horrid time with unwarranted TLS SNI host headers
vs Host: headers for proxy requests through httpd:. I will need to review
all three and compare them to the effect of this new patch.

In the interim I suggest we withdraw this comparison, and bring it back up
as a post 2.4.24 change. Thoughts?

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Jacob Champion <ch...@gmail.com>.
On 11/16/2016 05:01 AM, William A Rowe Jr wrote:
> We need to tolerate their presence. But we should ignore the guidance that
> sf originally quoted, that the URI host supersedes the Host header, it does
> not, they are two different entities it the proxy case

The "different entities" interpretation made sense to me too, but after 
re-reading the spec and seeing what the browsers actually do, I'm not so 
sure. (I'm a relative noob when it comes to the proxy sides of the spec, 
so corrections are appreciated.)

 From section 5.4:

    A client MUST send a Host header field in all HTTP/1.1 request
    messages.  If the target URI includes an authority component, then a
    client MUST send a field-value for Host that is identical to that
    authority component, excluding any userinfo subcomponent and its "@"
    delimiter (Section 2.7.1).  If the authority component is missing or
    undefined for the target URI, then a client MUST send a Host header
    field with an empty field-value.

That's pretty absolute, and there doesn't seem to be an exception carved 
out for proxies. And in practice, after giving Chromium and Firefox a 
try with a local netcat "proxy", the Host headers they send are indeed 
derived from the target URI, *not* the hostname of the HTTP proxy. I'd 
like to see what other browsers do as well.

This would appear to prevent name-based hosting of multiple proxies and 
origin servers at the same IP address, which seems strange to me, given 
that the Host header would be an appropriate resolution tool in that 
case... so I'm hoping there's something I'm missing.

Maybe no one needs to do that? Does anyone have experience with a 
client/user-agent that makes use of name-based virtual proxies?

--Jacob

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Wed, Nov 16, 2016 at 1:32 PM, Ruediger Pluem <rp...@apache.org> wrote:

>
> On 11/16/2016 01:08 PM, William A Rowe Jr wrote:
> >
> > Here's why I think the whole logic is busted and the preserve
> r->hostname is
> > the right thing to do for the outer request (not a child/client request
> to any
> > backend host)...
> >
> > I believe this logic to be busted. Given this request;
> >
> > GET http://distant-host.com/ HTTP/1.1
> > Host: proxy-host
> >
> > we would now fail to evaluate the proxy-host virtual host rules.
> >
> > This seems like a breaking change to our config. mod_proxy already
> > follows this rule of RFC7230 section 5.4;
> >
> >    When a proxy receives a request with an absolute-form of
> >    request-target, the proxy MUST ignore the received Host header field
> >    (if any) and instead replace it with the host information of the
> >    request-target.  A proxy that forwards such a request MUST generate a
> >    new Host field-value based on the received request-target rather than
> >    forward the received Host field-value.
> >
> > Section 5.5 of RFC7230 has this to say;
> >
> >    Once the effective request URI has been constructed, an origin server
> >    needs to decide whether or not to provide service for that URI via
> >    the connection in which the request was received.  For example, the
> >    request might have been misdirected, deliberately or accidentally,
> >    such that the information within a received request-target or Host
> >    header field differs from the host or port upon which the connection
> >    has been made.  If the connection is from a trusted gateway, that
> >    inconsistency might be expected; otherwise, it might indicate an
> >    attempt to bypass security filters, trick the server into delivering
> >    non-public content, or poison a cache.  See Section 9 for security
> >    considerations regarding message routing.
> >
> > Section 5.3.1 states;
> >
> >    To allow for transition to the absolute-form for all requests in some
> >    future version of HTTP, a server MUST accept the absolute-form in
> >    requests, even though HTTP/1.1 clients will only send them in
> >    requests to proxies.
> >
> > It seems to me we should simply trust the Host: header and dump this
> whole
> > mess. If we want to reject requests in absolute form after the proxy
> modules
> > have had a chance to accept them, that wouldn't be a bad solution.
>
>
> Hm. I am confused now. 5.3.1 seem to state that we need to accept them in
> any
> case, even for non proxy requests. For the proxy case 5.4 seems to be
> pretty clear
> what to todo: Forget about the Host header, take it from the request.
> For the other case we can IMHO decide what we want to do accept it (but
> what has
> precedence in this case host or request) or drop / error out. I guess both
> behaviours
> can make sense. The later one as a security check, the former one if we
> are on a backend
> system and have a trusted proxy / reverse proxy aka gateway in front of us.
>

We need to tolerate their presence. But we should ignore the guidance that
sf originally quoted, that the URI host supersedes the Host header, it does
not, they are two different entities it the proxy case, and in the non-proxy
local resource case, a mismatch makes no sense in the first place.

We could reject non-proxy requests in absolute form if they were to some
local resource, but I think that is punitive. I'm not aware of any server
that
would refuse a request for http://example.com/x.html ... Host:example.com

We could reject non-proxy requests in absolute form if the URI host did
not match the specified Host: value. I'd initially wished it would, since
these are logged as 404's and typically searches for open proxies. That
confuses every new user/admin. But what about a client which resolved
the uri as submitted but then generated the Host: after some dns fixup?

Or we could continue to discard the target host specified in the local
resource uri, as we do today.

Can we get more eyeballs on this? Before backporting anything, I'd like
to eliminate this specific test altogether from the backport, or at least
refine it to be something meaningful.

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Ruediger Pluem <rp...@apache.org>.

On 11/16/2016 01:08 PM, William A Rowe Jr wrote:
> On Tue, Nov 8, 2016 at 1:39 PM, Ruediger Pluem <rpluem@apache.org <ma...@apache.org>> wrote:
> 
> 
>     On 11/04/2016 03:20 PM, wrowe@apache.org <ma...@apache.org> wrote:
>     > Author: wrowe
>     > Date: Fri Nov  4 14:20:16 2016
>     > New Revision: 1768036
>     >
>     > URL: http://svn.apache.org/viewvc?rev=1768036&view=rev <http://svn.apache.org/viewvc?rev=1768036&view=rev>
>     > Log:
>     > Add an option to enforce stricter HTTP conformance
>     >
>     > This is a first stab, the checks will likely have to be revised.
>     > For now, we check
>     >
>     >  * if the request line contains control characters
>     >  * if the request uri has fragment or username/password
>     >  * that the request method is standard or registered with RegisterHttpMethod
>     >  * that the request protocol is of the form HTTP/[1-9]+.[0-9]+,
>     >    or missing for 0.9
>     >  * if there is garbage in the request line after the protocol
>     >  * if any request header contains control characters
>     >  * if any request header has an empty name
>     >  * for the host name in the URL or Host header:
>     >    - if an IPv4 dotted decimal address: Reject octal or hex values, require
>     >      exactly four parts
>     >    - if a DNS host name: Reject non-alphanumeric characters besides '.' and
>     >      '-'. As a side effect, this rejects multiple Host headers.
>     >  * if any response header contains control characters
>     >  * if any response header has an empty name
>     >  * that the Location response header (if present) has a valid scheme and is
>     >    absolute
>     >
>     > If we have a host name both from the URL and the Host header, we replace the
>     > Host header with the value from the URL to enforce RFC conformance.
>     >
>     > There is a log-only mode, but the loglevels of the logged messages need some
>     > thought/work. Currently, the  checks for incoming data log for 'core' and the
>     > checks for outgoing data log for 'http'. Maybe we need a way to configure the
>     > loglevels separately from the core/http loglevels.
>     >
>     > change protocol number parsing in strict mode according to HTTPbis draft
>     > - only accept single digit version components
>     > - don't accept white-space after protocol specification
>     >
>     > Clean up comment, fix log tags.
>     > Submitted by: sf
>     > Backports: r1426877, r1426879, r1426988, r1426992
>     > Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c
>     > URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c?rev=1768036&r1=1768035&r2=1768036&view=diff
>     <http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c?rev=1768036&r1=1768035&r2=1768036&view=diff>
>     > ==============================================================================
>     > --- httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c (original)
>     > +++ httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c Fri Nov  4 14:20:16 2016
>     > +    if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
>     > +        /*
>     > +         * If we have both hostname from an absoluteURI and a Host header,
>     > +         * we must ignore the Host header (RFC 2616 5.2).
>     > +         * To enforce this, we reset the Host header to the value from the
>     > +         * request line.
>     > +         */
>     > +        if (have_hostname_from_url && host_header != NULL) {
>     > +            const char *info = "Would replace";
>     > +            const char *new = construct_host_header(r, is_v6literal);
>     > +            if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
>     > +                apr_table_set(r->headers_in, "Host", r->hostname);
> 
>     Hm, why don't we use "new" here instead of r->hostname
> 
>     > +                info = "Replacing";
>     > +            }
>     > +            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
>     > +                          "%s Host header '%s' with host from request uri: "
>     > +                          "'%s'", info, host_header, new);
>     > +        }
>     > +    }
> 
>  
> Good question, with LOGONLY no longer an option, all that logic got simpler.
> 
> Here's why I think the whole logic is busted and the preserve r->hostname is
> the right thing to do for the outer request (not a child/client request to any
> backend host)...
> 
> I believe this logic to be busted. Given this request;
> 
> GET http://distant-host.com/ HTTP/1.1
> Host: proxy-host
> 
> we would now fail to evaluate the proxy-host virtual host rules.
> 
> This seems like a breaking change to our config. mod_proxy already
> follows this rule of RFC7230 section 5.4;
> 
>    When a proxy receives a request with an absolute-form of
>    request-target, the proxy MUST ignore the received Host header field
>    (if any) and instead replace it with the host information of the
>    request-target.  A proxy that forwards such a request MUST generate a
>    new Host field-value based on the received request-target rather than
>    forward the received Host field-value.
> 
> Section 5.5 of RFC7230 has this to say;
> 
>    Once the effective request URI has been constructed, an origin server
>    needs to decide whether or not to provide service for that URI via
>    the connection in which the request was received.  For example, the
>    request might have been misdirected, deliberately or accidentally,
>    such that the information within a received request-target or Host
>    header field differs from the host or port upon which the connection
>    has been made.  If the connection is from a trusted gateway, that
>    inconsistency might be expected; otherwise, it might indicate an
>    attempt to bypass security filters, trick the server into delivering
>    non-public content, or poison a cache.  See Section 9 for security
>    considerations regarding message routing.
> 
> Section 5.3.1 states;
> 
>    To allow for transition to the absolute-form for all requests in some
>    future version of HTTP, a server MUST accept the absolute-form in
>    requests, even though HTTP/1.1 clients will only send them in
>    requests to proxies.
> 
> It seems to me we should simply trust the Host: header and dump this whole
> mess. If we want to reject requests in absolute form after the proxy modules
> have had a chance to accept them, that wouldn't be a bad solution.
> 


Hm. I am confused now. 5.3.1 seem to state that we need to accept them in any
case, even for non proxy requests. For the proxy case 5.4 seems to be pretty clear
what to todo: Forget about the Host header, take it from the request.
For the other case we can IMHO decide what we want to do accept it (but what has
precedence in this case host or request) or drop / error out. I guess both behaviours
can make sense. The later one as a security check, the former one if we are on a backend
system and have a trusted proxy / reverse proxy aka gateway in front of us.

Regards

R�diger

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Tue, Nov 8, 2016 at 1:39 PM, Ruediger Pluem <rp...@apache.org> wrote:

>
> On 11/04/2016 03:20 PM, wrowe@apache.org wrote:
> > Author: wrowe
> > Date: Fri Nov  4 14:20:16 2016
> > New Revision: 1768036
> >
> > URL: http://svn.apache.org/viewvc?rev=1768036&view=rev
> > Log:
> > Add an option to enforce stricter HTTP conformance
> >
> > This is a first stab, the checks will likely have to be revised.
> > For now, we check
> >
> >  * if the request line contains control characters
> >  * if the request uri has fragment or username/password
> >  * that the request method is standard or registered with
> RegisterHttpMethod
> >  * that the request protocol is of the form HTTP/[1-9]+.[0-9]+,
> >    or missing for 0.9
> >  * if there is garbage in the request line after the protocol
> >  * if any request header contains control characters
> >  * if any request header has an empty name
> >  * for the host name in the URL or Host header:
> >    - if an IPv4 dotted decimal address: Reject octal or hex values,
> require
> >      exactly four parts
> >    - if a DNS host name: Reject non-alphanumeric characters besides '.'
> and
> >      '-'. As a side effect, this rejects multiple Host headers.
> >  * if any response header contains control characters
> >  * if any response header has an empty name
> >  * that the Location response header (if present) has a valid scheme and
> is
> >    absolute
> >
> > If we have a host name both from the URL and the Host header, we replace
> the
> > Host header with the value from the URL to enforce RFC conformance.
> >
> > There is a log-only mode, but the loglevels of the logged messages need
> some
> > thought/work. Currently, the  checks for incoming data log for 'core'
> and the
> > checks for outgoing data log for 'http'. Maybe we need a way to
> configure the
> > loglevels separately from the core/http loglevels.
> >
> > change protocol number parsing in strict mode according to HTTPbis draft
> > - only accept single digit version components
> > - don't accept white-space after protocol specification
> >
> > Clean up comment, fix log tags.
> > Submitted by: sf
> > Backports: r1426877, r1426879, r1426988, r1426992
> > Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c
> > URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-
> merge-http-strict/server/vhost.c?rev=1768036&r1=
> 1768035&r2=1768036&view=diff
> > ============================================================
> ==================
> > --- httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c
> (original)
> > +++ httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c Fri
> Nov  4 14:20:16 2016
> > +    if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
> > +        /*
> > +         * If we have both hostname from an absoluteURI and a Host
> header,
> > +         * we must ignore the Host header (RFC 2616 5.2).
> > +         * To enforce this, we reset the Host header to the value from
> the
> > +         * request line.
> > +         */
> > +        if (have_hostname_from_url && host_header != NULL) {
> > +            const char *info = "Would replace";
> > +            const char *new = construct_host_header(r, is_v6literal);
> > +            if (!(conf->http_conformance &
> AP_HTTP_CONFORMANCE_LOGONLY)) {
> > +                apr_table_set(r->headers_in, "Host", r->hostname);
>
> Hm, why don't we use "new" here instead of r->hostname
>
> > +                info = "Replacing";
> > +            }
> > +            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
> > +                          "%s Host header '%s' with host from request
> uri: "
> > +                          "'%s'", info, host_header, new);
> > +        }
> > +    }


Good question, with LOGONLY no longer an option, all that logic got simpler.

Here's why I think the whole logic is busted and the preserve r->hostname is
the right thing to do for the outer request (not a child/client request to
any
backend host)...

I believe this logic to be busted. Given this request;

GET http://distant-host.com/ HTTP/1.1
Host: proxy-host

we would now fail to evaluate the proxy-host virtual host rules.

This seems like a breaking change to our config. mod_proxy already
follows this rule of RFC7230 section 5.4;

   When a proxy receives a request with an absolute-form of
   request-target, the proxy MUST ignore the received Host header field
   (if any) and instead replace it with the host information of the
   request-target.  A proxy that forwards such a request MUST generate a
   new Host field-value based on the received request-target rather than
   forward the received Host field-value.

Section 5.5 of RFC7230 has this to say;

   Once the effective request URI has been constructed, an origin server
   needs to decide whether or not to provide service for that URI via
   the connection in which the request was received.  For example, the
   request might have been misdirected, deliberately or accidentally,
   such that the information within a received request-target or Host
   header field differs from the host or port upon which the connection
   has been made.  If the connection is from a trusted gateway, that
   inconsistency might be expected; otherwise, it might indicate an
   attempt to bypass security filters, trick the server into delivering
   non-public content, or poison a cache.  See Section 9 for security
   considerations regarding message routing.

Section 5.3.1 states;

   To allow for transition to the absolute-form for all requests in some
   future version of HTTP, a server MUST accept the absolute-form in
   requests, even though HTTP/1.1 clients will only send them in
   requests to proxies.

It seems to me we should simply trust the Host: header and dump this whole
mess. If we want to reject requests in absolute form after the proxy modules
have had a chance to accept them, that wouldn't be a bad solution.

Re: svn commit: r1768036 - in /httpd/httpd/branches/2.4.x-merge-http-strict: ./ CHANGES include/ap_mmn.h include/http_core.h include/httpd.h modules/http/http_filters.c server/core.c server/protocol.c server/util.c server/vhost.c

Posted by Ruediger Pluem <rp...@apache.org>.

On 11/04/2016 03:20 PM, wrowe@apache.org wrote:
> Author: wrowe
> Date: Fri Nov  4 14:20:16 2016
> New Revision: 1768036
> 
> URL: http://svn.apache.org/viewvc?rev=1768036&view=rev
> Log:
> Add an option to enforce stricter HTTP conformance
> 
> This is a first stab, the checks will likely have to be revised.
> For now, we check
> 
>  * if the request line contains control characters
>  * if the request uri has fragment or username/password
>  * that the request method is standard or registered with RegisterHttpMethod
>  * that the request protocol is of the form HTTP/[1-9]+.[0-9]+,
>    or missing for 0.9
>  * if there is garbage in the request line after the protocol
>  * if any request header contains control characters
>  * if any request header has an empty name
>  * for the host name in the URL or Host header:
>    - if an IPv4 dotted decimal address: Reject octal or hex values, require
>      exactly four parts
>    - if a DNS host name: Reject non-alphanumeric characters besides '.' and
>      '-'. As a side effect, this rejects multiple Host headers.
>  * if any response header contains control characters
>  * if any response header has an empty name
>  * that the Location response header (if present) has a valid scheme and is
>    absolute
> 
> If we have a host name both from the URL and the Host header, we replace the
> Host header with the value from the URL to enforce RFC conformance.
> 
> There is a log-only mode, but the loglevels of the logged messages need some
> thought/work. Currently, the  checks for incoming data log for 'core' and the
> checks for outgoing data log for 'http'. Maybe we need a way to configure the
> loglevels separately from the core/http loglevels.
> 
> change protocol number parsing in strict mode according to HTTPbis draft
> - only accept single digit version components
> - don't accept white-space after protocol specification
> 
> Clean up comment, fix log tags.
> Submitted by: sf
> Backports: r1426877, r1426879, r1426988, r1426992
> 
> 

> Modified: httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c?rev=1768036&r1=1768035&r2=1768036&view=diff
> ==============================================================================
> --- httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c (original)
> +++ httpd/httpd/branches/2.4.x-merge-http-strict/server/vhost.c Fri Nov  4 14:20:16 2016

> @@ -1040,23 +1108,79 @@ static void check_serverpath(request_rec
>      }
>  }
>  
> +static APR_INLINE const char *construct_host_header(request_rec *r,
> +                                                    int is_v6literal)
> +{
> +    struct iovec iov[5];
> +    apr_size_t nvec = 0;
> +    /*
> +     * We cannot use ap_get_server_name/port here, because we must
> +     * ignore UseCanonicalName/Port.
> +     */
> +    if (is_v6literal) {
> +        iov[nvec].iov_base = "[";
> +        iov[nvec].iov_len = 1;
> +        nvec++;
> +    }
> +    iov[nvec].iov_base = (void *)r->hostname;
> +    iov[nvec].iov_len = strlen(r->hostname);
> +    nvec++;
> +    if (is_v6literal) {
> +        iov[nvec].iov_base = "]";
> +        iov[nvec].iov_len = 1;
> +        nvec++;
> +    }
> +    if (r->parsed_uri.port_str) {
> +        iov[nvec].iov_base = ":";
> +        iov[nvec].iov_len = 1;
> +        nvec++;
> +        iov[nvec].iov_base = r->parsed_uri.port_str;
> +        iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
> +        nvec++;
> +    }
> +    return apr_pstrcatv(r->pool, iov, nvec, NULL);
> +}
>  
>  AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
>  {
> -    const char *host_header;
> +    core_server_config *conf = ap_get_core_module_config(r->server->module_config);
> +    const char *host_header = apr_table_get(r->headers_in, "Host");
> +    int is_v6literal, have_hostname_from_url = 0;
>  
>      if (r->hostname) {
>          /*
>           * If there was a host part in the Request-URI, ignore the 'Host'
>           * header.
>           */
> -        fix_hostname(r, NULL);
> +        have_hostname_from_url = 1;
> +        is_v6literal = fix_hostname(r, NULL, conf->http_conformance);
>      }
> -    else if ((host_header = apr_table_get(r->headers_in, "Host")) != NULL ) {
> -        fix_hostname(r, host_header);
> +    else if (host_header != NULL) {
> +        is_v6literal = fix_hostname(r, host_header, conf->http_conformance);
>      }
>      if (r->status != HTTP_OK)
>          return;
> +
> +    if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
> +        /*
> +         * If we have both hostname from an absoluteURI and a Host header,
> +         * we must ignore the Host header (RFC 2616 5.2).
> +         * To enforce this, we reset the Host header to the value from the
> +         * request line.
> +         */
> +        if (have_hostname_from_url && host_header != NULL) {
> +            const char *info = "Would replace";
> +            const char *new = construct_host_header(r, is_v6literal);
> +            if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
> +                apr_table_set(r->headers_in, "Host", r->hostname);

Hm, why don't we use "new" here instead of r->hostname

> +                info = "Replacing";
> +            }
> +            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
> +                          "%s Host header '%s' with host from request uri: "
> +                          "'%s'", info, host_header, new);
> +        }
> +    }
> +
>      /* check if we tucked away a name_chain */
>      if (r->connection->vhost_lookup_data) {
>          if (r->hostname)
> 
> 
> 

Regards

R�diger