Fossil SCM
Add an authorizer to the raw-SQL entry box. This authorizer is not strictly necessary for security. It is just another layer of defense.
Commit
98f29f24cd4349ddaa276cea05d231d28351a7bf
Parent
6b22a464d7ff59a…
1 file changed
+27
+27
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -1614,10 +1614,33 @@ | ||
| 1614 | 1614 | @ take effect. </p> |
| 1615 | 1615 | style_footer(); |
| 1616 | 1616 | db_end_transaction(0); |
| 1617 | 1617 | } |
| 1618 | 1618 | |
| 1619 | +/* | |
| 1620 | +** Prevent the RAW SQL feature from being used to ATTACH a different | |
| 1621 | +** database and query it. | |
| 1622 | +** | |
| 1623 | +** Actually, the RAW SQL feature only does a single statement per request. | |
| 1624 | +** So it is not possible to ATTACH and then do a separate query. This | |
| 1625 | +** routine is not strictly necessary, therefore. But it does not hurt | |
| 1626 | +** to be paranoid. | |
| 1627 | +*/ | |
| 1628 | +int raw_sql_query_authorizer( | |
| 1629 | + void *pError, | |
| 1630 | + int code, | |
| 1631 | + const char *zArg1, | |
| 1632 | + const char *zArg2, | |
| 1633 | + const char *zArg3, | |
| 1634 | + const char *zArg4 | |
| 1635 | +){ | |
| 1636 | + if( code==SQLITE_ATTACH ){ | |
| 1637 | + return SQLITE_DENY; | |
| 1638 | + } | |
| 1639 | + return SQLITE_OK; | |
| 1640 | +} | |
| 1641 | + | |
| 1619 | 1642 | |
| 1620 | 1643 | /* |
| 1621 | 1644 | ** WEBPAGE: admin_sql |
| 1622 | 1645 | ** |
| 1623 | 1646 | ** Run raw SQL commands against the database file using the web interface. |
| @@ -1632,10 +1655,13 @@ | ||
| 1632 | 1655 | db_begin_transaction(); |
| 1633 | 1656 | style_header("Raw SQL Commands"); |
| 1634 | 1657 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
| 1635 | 1658 | @ run by this page. You can do serious and irrepairable damage to the |
| 1636 | 1659 | @ repository. Proceed with extreme caution.</p> |
| 1660 | + @ | |
| 1661 | + @ <p>Only a the first statement in the entry box will be run. | |
| 1662 | + @ Any subsequent statements will be silently ignored.</p> | |
| 1637 | 1663 | @ |
| 1638 | 1664 | @ <p>Database names:<ul><li>repository → %s(db_name("repository")) |
| 1639 | 1665 | if( g.configOpen ){ |
| 1640 | 1666 | @ <li>config → %s(db_name("configdb")) |
| 1641 | 1667 | } |
| @@ -1671,10 +1697,11 @@ | ||
| 1671 | 1697 | int nCol; |
| 1672 | 1698 | int nRow = 0; |
| 1673 | 1699 | int i; |
| 1674 | 1700 | @ <hr /> |
| 1675 | 1701 | login_verify_csrf_secret(); |
| 1702 | + sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0); | |
| 1676 | 1703 | rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail); |
| 1677 | 1704 | if( rc!=SQLITE_OK ){ |
| 1678 | 1705 | @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> |
| 1679 | 1706 | sqlite3_finalize(pStmt); |
| 1680 | 1707 | }else if( pStmt==0 ){ |
| 1681 | 1708 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1614,10 +1614,33 @@ | |
| 1614 | @ take effect. </p> |
| 1615 | style_footer(); |
| 1616 | db_end_transaction(0); |
| 1617 | } |
| 1618 | |
| 1619 | |
| 1620 | /* |
| 1621 | ** WEBPAGE: admin_sql |
| 1622 | ** |
| 1623 | ** Run raw SQL commands against the database file using the web interface. |
| @@ -1632,10 +1655,13 @@ | |
| 1632 | db_begin_transaction(); |
| 1633 | style_header("Raw SQL Commands"); |
| 1634 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
| 1635 | @ run by this page. You can do serious and irrepairable damage to the |
| 1636 | @ repository. Proceed with extreme caution.</p> |
| 1637 | @ |
| 1638 | @ <p>Database names:<ul><li>repository → %s(db_name("repository")) |
| 1639 | if( g.configOpen ){ |
| 1640 | @ <li>config → %s(db_name("configdb")) |
| 1641 | } |
| @@ -1671,10 +1697,11 @@ | |
| 1671 | int nCol; |
| 1672 | int nRow = 0; |
| 1673 | int i; |
| 1674 | @ <hr /> |
| 1675 | login_verify_csrf_secret(); |
| 1676 | rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail); |
| 1677 | if( rc!=SQLITE_OK ){ |
| 1678 | @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> |
| 1679 | sqlite3_finalize(pStmt); |
| 1680 | }else if( pStmt==0 ){ |
| 1681 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -1614,10 +1614,33 @@ | |
| 1614 | @ take effect. </p> |
| 1615 | style_footer(); |
| 1616 | db_end_transaction(0); |
| 1617 | } |
| 1618 | |
| 1619 | /* |
| 1620 | ** Prevent the RAW SQL feature from being used to ATTACH a different |
| 1621 | ** database and query it. |
| 1622 | ** |
| 1623 | ** Actually, the RAW SQL feature only does a single statement per request. |
| 1624 | ** So it is not possible to ATTACH and then do a separate query. This |
| 1625 | ** routine is not strictly necessary, therefore. But it does not hurt |
| 1626 | ** to be paranoid. |
| 1627 | */ |
| 1628 | int raw_sql_query_authorizer( |
| 1629 | void *pError, |
| 1630 | int code, |
| 1631 | const char *zArg1, |
| 1632 | const char *zArg2, |
| 1633 | const char *zArg3, |
| 1634 | const char *zArg4 |
| 1635 | ){ |
| 1636 | if( code==SQLITE_ATTACH ){ |
| 1637 | return SQLITE_DENY; |
| 1638 | } |
| 1639 | return SQLITE_OK; |
| 1640 | } |
| 1641 | |
| 1642 | |
| 1643 | /* |
| 1644 | ** WEBPAGE: admin_sql |
| 1645 | ** |
| 1646 | ** Run raw SQL commands against the database file using the web interface. |
| @@ -1632,10 +1655,13 @@ | |
| 1655 | db_begin_transaction(); |
| 1656 | style_header("Raw SQL Commands"); |
| 1657 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be |
| 1658 | @ run by this page. You can do serious and irrepairable damage to the |
| 1659 | @ repository. Proceed with extreme caution.</p> |
| 1660 | @ |
| 1661 | @ <p>Only a the first statement in the entry box will be run. |
| 1662 | @ Any subsequent statements will be silently ignored.</p> |
| 1663 | @ |
| 1664 | @ <p>Database names:<ul><li>repository → %s(db_name("repository")) |
| 1665 | if( g.configOpen ){ |
| 1666 | @ <li>config → %s(db_name("configdb")) |
| 1667 | } |
| @@ -1671,10 +1697,11 @@ | |
| 1697 | int nCol; |
| 1698 | int nRow = 0; |
| 1699 | int i; |
| 1700 | @ <hr /> |
| 1701 | login_verify_csrf_secret(); |
| 1702 | sqlite3_set_authorizer(g.db, raw_sql_query_authorizer, 0); |
| 1703 | rc = sqlite3_prepare_v2(g.db, zQ, -1, &pStmt, &zTail); |
| 1704 | if( rc!=SQLITE_OK ){ |
| 1705 | @ <div class="generalError">%h(sqlite3_errmsg(g.db))</div> |
| 1706 | sqlite3_finalize(pStmt); |
| 1707 | }else if( pStmt==0 ){ |
| 1708 |