-
Notifications
You must be signed in to change notification settings - Fork 1
/
Safe.pm.html
211 lines (199 loc) · 9.2 KB
/
Safe.pm.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DBIx::Safe - Safer access to your database through a DBI database handle</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body style="background-color: white">
<p><a name="__index__"></a></p>
<!-- INDEX BEGIN -->
<ul>
<li><a href="#name">NAME</a></li>
<li><a href="#version">VERSION</a></li>
<li><a href="#synopsis">SYNOPSIS</a></li>
<li><a href="#description">DESCRIPTION</a></li>
<ul>
<li><a href="#deciding_what_statements_to_allow">Deciding what statements to allow</a></li>
<li><a href="#deciding_what_attributes_to_allow">Deciding what attributes to allow</a></li>
<li><a href="#methods">Methods</a></li>
<ul>
<li><a href="#new__"><code>new()</code></a></li>
<li><a href="#allow_command__"><code>allow_command()</code></a></li>
<li><a href="#unallow_command__"><code>unallow_command()</code></a></li>
<li><a href="#allow_regex__"><code>allow_regex()</code></a></li>
<li><a href="#unallow_regex__"><code>unallow_regex()</code></a></li>
<li><a href="#deny_regex__"><code>deny_regex()</code></a></li>
<li><a href="#undeny_regex__">undeny <code>regex()</code></a></li>
<li><a href="#allow_attribute__"><code>allow_attribute()</code></a></li>
<li><a href="#unallow_attribute__"><code>unallow_attribute()</code></a></li>
</ul>
<li><a href="#testing">Testing</a></li>
<li><a href="#supported_databases">Supported Databases</a></li>
</ul>
<li><a href="#website">WEBSITE</a></li>
<li><a href="#development">DEVELOPMENT</a></li>
<li><a href="#bugs">BUGS</a></li>
<li><a href="#author">AUTHOR</a></li>
<li><a href="#license_and_copyright">LICENSE AND COPYRIGHT</a></li>
</ul>
<!-- INDEX END -->
<hr />
<p>
</p>
<hr />
<h1><a name="name">NAME</a></h1>
<p>DBIx::Safe - Safer access to your database through a DBI database handle</p>
<p>
</p>
<hr />
<h1><a name="version">VERSION</a></h1>
<p>This documents version 1.2.5 of the DBIx::Safe module</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
use DBIx::Safe;</pre>
<pre>
$dbh = DBI->connect($dbn, $user, $pass, {AutoCommit => 0});</pre>
<pre>
my $safedbh = DBIx::Safe->new({ dbh => $dbh });</pre>
<pre>
$safedbh->allow_command('SELECT INSERT UPDATE');</pre>
<pre>
$safedbh->allow_regex(qr{LOCK TABLE \w+ IN EXCLUSIVE MODE});</pre>
<pre>
$safedbh->deny_regex(qr{LOCK TABLE pg_});</pre>
<pre>
$safedbh->allow_attribute('PrintError RaiseError');</pre>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>The purpose of this module is to give controlled, limited access to an application,
rather than simply passing it a raw database handle through DBI. DBIx::Safe acts as
a wrapper to the database, by only allowing through the commands you tell it to. It
filters all things related to the database handle - methods and attributes.</p>
<p>The typical usage is for your application to create a database handle via a normal
DBI call to new(), then pass that to DBIx::Safe->new(), which will return you a
DBIx::Safe object. After specifying exactly what is and what is not allowed, you can
pass the object to the untrusted application. The object will act very similar to a
DBI database handle, and in most cases can be used interchangeably.</p>
<p>By default, nothing is allowed to run at all. There are many things you can control.
You can specify which SQL commands are allowed, by indicating the first word in the
SQL statement (e.g. 'SELECT'). You can specify which database methods are allowed to
run (e.g. 'ping'). You can specify a regular expression that allows matching SQL
statements to run (e.g. 'qr{SET TIMEZONE}'). You can specify a regular expression
that is NOT allowed to run (e.g. qr(UPDATE xxx}). Finally, you can indicate which
database attributes are allowed to be read and changed (e.g. 'PrintError'). For all
of the above, there are matching methods to remove them as well.</p>
<p>
</p>
<h2><a name="deciding_what_statements_to_allow">Deciding what statements to allow</a></h2>
<p>Anytime a statement is sent to the server via the DBIx::Safe database handle, it is first
examined to see if it is allowed to run or not. There are three major checks that occur
when a statement is sent. First, the initial word of the statement, known as the command,
is extracted. Next, the entire statement is checked against the list of denied regular expressions.
Next, the command is checked against the list of allowed commands. If there is no match,
the statement is checked against the list of allowed regular expressions.</p>
<p>Each DBD may implement additional or slightly different checks. For example, if using
Postgres, no semi-colons are allowed unless the command is one of SELECT, INSERT,
UPDATE, or DELETE, to prevent multiple commands from running. (The four listed commands
can be checked in another way for multiple commands, so they are allowed to have
semicolons).</p>
<p>
</p>
<h2><a name="deciding_what_attributes_to_allow">Deciding what attributes to allow</a></h2>
<p>Database handle attributes are controlled by a single list of allowed keys. If the
key is allowed, the underlying database handle value is returned or changed (or both).
Note that the attribute "AutoCommit" is never allowed to be changed.</p>
<p>
</p>
<h2><a name="methods">Methods</a></h2>
<p>
</p>
<h3><a name="new__"><code>new()</code></a></h3>
<p>Creates a new DBIx::Safe object. Requires a mandatory "dbh" argument containing an active database
handle. Optional arguments are "allow_command", "allow_regex", "deny_regex", and "allow_attribute".</p>
<p>
</p>
<h3><a name="allow_command__"><code>allow_command()</code></a></h3>
<p>Specifies which commands are allowed to be used. Can be a whitespace-separated list of words in a string,
or an arrayref of such strings. Returns the current list of allowed commands. Duplicate commands will
throw an error.</p>
<p>
</p>
<h3><a name="unallow_command__"><code>unallow_command()</code></a></h3>
<p>Same as allow_command, but will remove words from the list.</p>
<p>
</p>
<h3><a name="allow_regex__"><code>allow_regex()</code></a></h3>
<p>Specifies regular expressions which are allowed to run. Argument must be a regular expression,
or an arrayref of regular expressions. Returns the current list.</p>
<p>
</p>
<h3><a name="unallow_regex__"><code>unallow_regex()</code></a></h3>
<p>Same as allow_regex, but will remove regexes from the list.</p>
<p>
</p>
<h3><a name="deny_regex__"><code>deny_regex()</code></a></h3>
<p>Specifies regular expressions which are NOT allowed to run. Arguments and return the same as allow_regex().</p>
<p>
</p>
<h3><a name="undeny_regex__">undeny <code>regex()</code></a></h3>
<p>Same as deny_regex, but will remove regexes from the list.</p>
<p>
</p>
<h3><a name="allow_attribute__"><code>allow_attribute()</code></a></h3>
<p>Specifies database handle attributes that are allowed to be changed. By default, nothing can be read.
Argument is a whitespace-separated list of words in a string, or an arrayref of such strings. Returns
the current list.</p>
<p>
</p>
<h3><a name="unallow_attribute__"><code>unallow_attribute()</code></a></h3>
<p>Same as allow_attributes, but removes attributes from the list.</p>
<p>
</p>
<h2><a name="testing">Testing</a></h2>
<p>DBIx::Safe has a very comprehensive test suite, so please use it! The only thing you should need is a
database connection, by setting the environment variables DBI_DSN and DBI_USER (and DBI_PASS if needed).</p>
<p>You can optionally run the module through Perl::Critic by setting the TEST_AUTHOR environment variable.
You will need to have the modules Perl::Critic and Test::Perl::Critic installed.</p>
<p>Please report any test failures to the author or <a href="mailto:[email protected].">[email protected].</a></p>
<p>
</p>
<h2><a name="supported_databases">Supported Databases</a></h2>
<p>Due to the difficulty of ensuring safe access to the database, each type of database must be specifically
written into DBIx::Safe. Current databases supported are: Postgres (DBD::Pg).</p>
<p>
</p>
<hr />
<h1><a name="website">WEBSITE</a></h1>
<p>The latest version and other information about DBIx::Safe can be found at:
<a href="http://bucardo.org/dbix_safe/">http://bucardo.org/dbix_safe/</a></p>
<p>
</p>
<hr />
<h1><a name="development">DEVELOPMENT</a></h1>
<p>The latest development version can be checked out by using git:</p>
<pre>
git clone <a href="http://bucardo.org/dbixsafe.git/">http://bucardo.org/dbixsafe.git/</a></pre>
<p>
</p>
<hr />
<h1><a name="bugs">BUGS</a></h1>
<p>Bugs should be reported to the author or <a href="mailto:[email protected].">[email protected].</a></p>
<p>
</p>
<hr />
<h1><a name="author">AUTHOR</a></h1>
<p>Greg Sabino Mullane <<a href="mailto:[email protected]">[email protected]</a>></p>
<p>
</p>
<hr />
<h1><a name="license_and_copyright">LICENSE AND COPYRIGHT</a></h1>
<p>Copyright 2006-2021 Greg Sabino Mullane <<a href="mailto:[email protected]">[email protected]</a>>.</p>
<p>This software is free to use under the PostgreSQL License: see the LICENSE file for details.</p>
</body>
</html>