Commit 5246aaa
fix(extensions): validate ignore before --force removal; reject symlinked ancestors in config restore
Three review-driven hardening fixes to the keep-config reinstall, adopting the
repo's own safe-write contract (shared_infra) instead of leaf-only guards:
1. Validate the source ignore file BEFORE the --force self.remove(). It was
loaded only after removal, so a malformed/invalid-UTF-8 ignore file uninstalled
a working extension (files + registry entry) before validation raised. Moved
the single _load_extensionignore call above the force-removal block.
2. Reject a symlinked ANCESTOR of the config destination. _atomic_restore_config's
mkstemp(dir=dest.parent)+os.replace operated inside dest.parent, so if dest_dir
was swapped to a symlink after copytree, config bytes (secrets) were created in
and replaced into the external target. It now calls the repo's
shared_infra._ensure_safe_shared_directory to refuse any symlinked ancestor
under the project root before writing.
3. Rollback no longer merges through a symlinked/partial dir. It reset dest_dir
with rmtree(ignore_errors=True) then copytree(dirs_exist_ok=True), which could
follow a symlink. It now resets via a new _reset_dir (unlink a symlink / rmtree
a real dir, surfacing failures) and recreates dest_dir under a verified
non-symlink ancestor chain before copying; a rejected ancestor leaves the
durable backup on disk.
Tests: --force reinstall with a malformed ignore leaves the extension installed
(fails before: it was removed); a symlinked dest_dir is refused and never
receives config bytes, rollback recreating a real dir (skipped without symlink
privilege, runs on CI). Existing reinstall/keep-config tests unchanged (341 pass).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 6d8cd19 commit 5246aaa
2 files changed
Lines changed: 169 additions & 35 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1344 | 1344 | | |
1345 | 1345 | | |
1346 | 1346 | | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
| 1357 | + | |
| 1358 | + | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
1347 | 1362 | | |
1348 | | - | |
| 1363 | + | |
1349 | 1364 | | |
1350 | | - | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
| 1369 | + | |
| 1370 | + | |
| 1371 | + | |
| 1372 | + | |
| 1373 | + | |
| 1374 | + | |
| 1375 | + | |
| 1376 | + | |
| 1377 | + | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + | |
| 1382 | + | |
| 1383 | + | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
| 1392 | + | |
1351 | 1393 | | |
1352 | | - | |
1353 | | - | |
1354 | | - | |
1355 | | - | |
1356 | | - | |
1357 | | - | |
1358 | | - | |
1359 | | - | |
1360 | | - | |
1361 | 1394 | | |
1362 | | - | |
1363 | | - | |
| 1395 | + | |
| 1396 | + | |
1364 | 1397 | | |
1365 | 1398 | | |
1366 | 1399 | | |
| |||
1448 | 1481 | | |
1449 | 1482 | | |
1450 | 1483 | | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
1451 | 1491 | | |
1452 | 1492 | | |
1453 | 1493 | | |
| |||
1499 | 1539 | | |
1500 | 1540 | | |
1501 | 1541 | | |
1502 | | - | |
1503 | | - | |
1504 | | - | |
1505 | | - | |
1506 | | - | |
| 1542 | + | |
| 1543 | + | |
| 1544 | + | |
1507 | 1545 | | |
1508 | 1546 | | |
1509 | | - | |
1510 | | - | |
1511 | | - | |
1512 | | - | |
1513 | | - | |
1514 | | - | |
1515 | | - | |
1516 | | - | |
| 1547 | + | |
| 1548 | + | |
| 1549 | + | |
| 1550 | + | |
| 1551 | + | |
| 1552 | + | |
| 1553 | + | |
1517 | 1554 | | |
1518 | 1555 | | |
1519 | 1556 | | |
| |||
1534 | 1571 | | |
1535 | 1572 | | |
1536 | 1573 | | |
1537 | | - | |
1538 | | - | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
1539 | 1581 | | |
1540 | 1582 | | |
1541 | | - | |
1542 | | - | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
1543 | 1591 | | |
1544 | 1592 | | |
1545 | | - | |
1546 | | - | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
1547 | 1597 | | |
1548 | 1598 | | |
1549 | 1599 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1768 | 1768 | | |
1769 | 1769 | | |
1770 | 1770 | | |
1771 | | - | |
| 1771 | + | |
1772 | 1772 | | |
1773 | 1773 | | |
1774 | | - | |
| 1774 | + | |
1775 | 1775 | | |
1776 | 1776 | | |
1777 | | - | |
| 1777 | + | |
1778 | 1778 | | |
1779 | 1779 | | |
1780 | 1780 | | |
| |||
1786 | 1786 | | |
1787 | 1787 | | |
1788 | 1788 | | |
| 1789 | + | |
| 1790 | + | |
| 1791 | + | |
| 1792 | + | |
| 1793 | + | |
| 1794 | + | |
| 1795 | + | |
| 1796 | + | |
| 1797 | + | |
| 1798 | + | |
| 1799 | + | |
| 1800 | + | |
| 1801 | + | |
| 1802 | + | |
| 1803 | + | |
| 1804 | + | |
| 1805 | + | |
| 1806 | + | |
| 1807 | + | |
| 1808 | + | |
| 1809 | + | |
| 1810 | + | |
| 1811 | + | |
| 1812 | + | |
| 1813 | + | |
| 1814 | + | |
| 1815 | + | |
| 1816 | + | |
| 1817 | + | |
| 1818 | + | |
| 1819 | + | |
| 1820 | + | |
| 1821 | + | |
| 1822 | + | |
| 1823 | + | |
| 1824 | + | |
| 1825 | + | |
| 1826 | + | |
| 1827 | + | |
| 1828 | + | |
| 1829 | + | |
| 1830 | + | |
| 1831 | + | |
| 1832 | + | |
| 1833 | + | |
| 1834 | + | |
| 1835 | + | |
| 1836 | + | |
| 1837 | + | |
| 1838 | + | |
| 1839 | + | |
| 1840 | + | |
| 1841 | + | |
| 1842 | + | |
| 1843 | + | |
| 1844 | + | |
| 1845 | + | |
| 1846 | + | |
| 1847 | + | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
| 1851 | + | |
| 1852 | + | |
| 1853 | + | |
| 1854 | + | |
| 1855 | + | |
| 1856 | + | |
| 1857 | + | |
| 1858 | + | |
| 1859 | + | |
| 1860 | + | |
| 1861 | + | |
| 1862 | + | |
| 1863 | + | |
| 1864 | + | |
| 1865 | + | |
| 1866 | + | |
| 1867 | + | |
| 1868 | + | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
| 1872 | + | |
1789 | 1873 | | |
1790 | 1874 | | |
1791 | 1875 | | |
| |||
0 commit comments