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
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
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 11:01:29 2024 UTC