php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81742 open_basedir bypass in SQLite3/pdo-sqlite extension by using url encoded file
Submitted: 2022-11-28 23:06 UTC Modified: 2022-11-29 10:50 UTC
From: bawolff at gmail dot com Assigned: cmb (profile)
Status: Closed Package: SQLite related
PHP Version: master-Git-2022-11-28 (Git) OS: all
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: bawolff at gmail dot com
New email:
PHP Version: OS:

 

 [2022-11-28 23:06 UTC] bawolff at gmail dot com
Description:
------------
[I'm a bit unclear if open_basedir bypass count as security bugs, given how many warnings are on that config option]

The fix for https://bugs.php.net/bug.php?id=77967 is incorrect. This checks for file: uri's, and then checks if they meet open_basedir restrictions. However, SQLite supports hex escapes in file urls, including as a directory separator. PHP doesn't take this into account, which allows you to use relative urls to escape open_basedir to read sqlite files outside of the basedir as well as write files.

Note: for the PDO_sqlite extension (instead of sqlite3) this was incidentally fixed in a8dd009f23a. I don't think people realized that the fix fixed a pre-existing open_basedir bypass and as a result it was not backported.

Suggested fix: Probably easiest is to follow what pdo-sqlite does and just ban file: uris when open_basedir is on. Otherwise would have to decode the uri being sure to do it the same way sqlite does. I would also suggest backporting the change to pdo_sqlite to all supported versions.

Test script:
---------------
<?php
ini_set( 'open_basedir', '.' );
// Works on php master
$db = new SQLite3(':memory:');
$a = $db->query( "ATTACH 'file:..%2ffoo.php' as db2;" );

// Works prior to a8dd009f23a
$db = new PDO('sqlite::memory:');
$a = $db->exec( "ATTACH 'file:..%2ffoo.php' as db2;" );


Expected result:
----------------
I expect an error to happen.

e.g. Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 23 not authorized in test.php:4

Actual result:
--------------
foo.php is created in the parent directory.

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2022-11-29 10:50 UTC] cmb@php.net
-Status: Open +Status: Verified -Type: Security +Type: Bug -Assigned To: +Assigned To: cmb
 [2022-11-29 10:50 UTC] cmb@php.net
> I'm a bit unclear if open_basedir bypass count as security bugs

open_basedir bypasses are explicitly no security issues according
to our classification[1].  Nonetheless, thanks for reporting!

> Suggested fix: Probably easiest is to follow what pdo-sqlite
> does and just ban file: uris when open_basedir is on.

According to the discussion on the respective PDO_SQLite PR[2],
this indeed appears to be prudent; although that may break some
existing code relying on passing URL parameters.

[1] <https://wiki.php.net/security#not_a_security_issue>
[2] <https://github.com/php/php-src/pull/6610>
 [2022-11-29 11:20 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #81742: open_basedir bypass in SQLite3 by using file URI
On GitHub:  https://github.com/php/php-src/pull/10018
Patch:      https://github.com/php/php-src/pull/10018.patch
 [2022-12-06 15:02 UTC] git@php.net
Automatic comment on behalf of cmb69
Revision: https://github.com/php/php-src/commit/2f6b9e6c639c37405e45094bd9c8f2f3b3f377d3
Log: Fix #81742: open_basedir bypass in SQLite3 by using file URI
 [2022-12-06 15:02 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 10:01:29 2024 UTC