@@ -448,4 +448,64 @@ rows = (outer_cardinality * inner_cardinality) * selectivity
448
448
449
449
</sect1>
450
450
451
+ <sect1 id="planner-stats-security">
452
+ <title>Planner Statistics and Security</title>
453
+
454
+ <para>
455
+ Access to the table <structname>pg_statistic</structname> is restricted to
456
+ superusers, so that ordinary users cannot learn about the contents of the
457
+ tables of other users from it. Some selectivity estimation functions will
458
+ use a user-provided operator (either the operator appearing in the query or
459
+ a related operator) to analyze the stored statistics. For example, in order
460
+ to determine whether a stored most common value is applicable, the
461
+ selectivity estimator will have to run the appropriate <literal>=</literal>
462
+ operator to compare the constant in the query to the stored value.
463
+ Thus the data in <structname>pg_statistic</structname> is potentially
464
+ passed to user-defined operators. An appropriately crafted operator can
465
+ intentionally leak the passed operands (for example, by logging them
466
+ or writing them to a different table), or accidentally leak them by showing
467
+ their values in error messages, in either case possibly exposing data from
468
+ <structname>pg_statistic</structname> to a user who should not be able to
469
+ see it.
470
+ </para>
471
+
472
+ <para>
473
+ In order to prevent this, the following applies to all built-in selectivity
474
+ estimation functions. When planning a query, in order to be able to use
475
+ stored statistics, the current user must either
476
+ have <literal>SELECT</literal> privilege on the table or the involved
477
+ columns, or the operator used must be <literal>LEAKPROOF</literal> (more
478
+ accurately, the function that the operator is based on). If not, then the
479
+ selectivity estimator will behave as if no statistics are available, and
480
+ the planner will proceed with default or fall-back assumptions.
481
+ </para>
482
+
483
+ <para>
484
+ If a user does not have the required privilege on the table or columns,
485
+ then in many cases the query will ultimately receive a permission-denied
486
+ error, in which case this mechanism is invisible in practice. But if the
487
+ user is reading from a security-barrier view, then the planner might wish
488
+ to check the statistics of an underlying table that is otherwise
489
+ inaccessible to the user. In that case, the operator should be leak-proof
490
+ or the statistics will not be used. There is no direct feedback about
491
+ that, except that the plan might be suboptimal. If one suspects that this
492
+ is the case, one could try running the query as a more privileged user,
493
+ to see if a different plan results.
494
+ </para>
495
+
496
+ <para>
497
+ This restriction applies only to cases where the planner would need to
498
+ execute a user-defined operator on one or more values
499
+ from <structname>pg_statistic</structname>. Thus the planner is permitted
500
+ to use generic statistical information, such as the fraction of null values
501
+ or the number of distinct values in a column, regardless of access
502
+ privileges.
503
+ </para>
504
+
505
+ <para>
506
+ Selectivity estimation functions contained in third-party extensions that
507
+ potentially operate on statistics with user-defined operators should follow
508
+ the same security rules. Consult the PostgreSQL source code for guidance.
509
+ </para>
510
+ </sect1>
451
511
</chapter>