background image

www.hakin9.org

hakin9 Nr 11/2007

62

Obrona

T

echnologia ta pozwala na tworzenie bo-
gatych,  atrakcyjnych  wizualnie  interfej-
sów  użytkownika,  które  mogą  pracować 

w dowolnym środowisku – w przeglądarkach in-
ternetowych, na różnych urządzeniach i na róż-
nych systemach operacyjnych (np. Apple Macin-
tosh). Podobnie jak w przypadku WPF (Windows 
Presentation  Foundation
),  technologii  prezenta-
cyjnej  stworzonej  wraz  z  .NET  Framework  3.0, 
podstawą Silverlight jest język XAML (eXtensible 
Application  Markup  Language
).  Technologia  ta, 
pomimo tego, że jest ciągle w fazie rozwojowej 
(w  chwili  obecnej  dostępne  są  dwie  wersje 
Silverlight – 1.0 RC, czyli kandydat do wersji osta-
tecznej oraz wersja 1.1 alfa), staje się coraz bar-
dziej  popularna  i  wciąż  rośnie  liczba  serwisów 
używających jej do celów prezentacji treści. Przy 
tej okazji bardzo często padają pytania o bezpie-
czeństwo aplikacji opartych o Silverlight, głównie 
ze  względu  na  obsługę  wielu  platform.  Artykuł 
ma na celu wprowadzenie i ogólne przedstawie-
nie modelu bezpieczeństwa tej technologii. 

Trudne początki, czyli wstęp 

do modelu bezpieczeństwa

Jak wiadomo, już od samego początku założe-
niem nowej technologii było stworzenie  minimal-

nego silnika do uruchamiania aplikacji opar-
tych  o  Silverlight,  czyli  de  facto  o  .NET. 
Silverlight  zawiera  bardzo  mocno  okrojoną
wersję  CLR  (Common  Language  Runtime). 
Całość  zajmuje  ok.  5  MB.  Znając  podstawy
programowania w .NET Framework oraz obję-
tość  wszystkich  bibliotek  i  powiązań,  można
się  zastanawiać,  jak  to  wszystko  działa  – 
a w szczególności, jak rozwiązane są aspekty
bezpieczeństwa.  Przecież  każdy  programista, 
który pisał bezpieczne aplikacje, musiał poz-
nać różnorodne aspekty takich narzędzi, jak 

Bezpieczeństwo 

Silverlight

Artur Żarski

stopień trudności

Podczas konferencji MIX’07, która odbyła się na początku 

maja 2007 roku w Las Vegas, została pokazana nowa technologia 

prezentacji zawartości stron WWW. Jest nią Silverlight, 

która z założenia ma działać na różnorodnych platformach.

Z artykułu dowiesz się

•  nowości w modelu bezpieczeństwa technologii 

Silverlight i jego aspektów istotnych dla progra-
misty.

Co powinieneś wiedzieć

•  czytelnik powinien mieć wiedzę na temat tworze-

nia bezpiecznych aplikacji na platformie .NET, 

•  znać  pojęcia  takie  jak  CAS,  kod  przeźroczy-

sty,  kod  krytyczny  oraz  podstawowe  elemen-
ty przestrzeni nazw System.Security.

background image

Bezpieczeństwo Silverlight

hakin9 Nr 11/2007

www.hakin9.org

63

caspol.exe i specyfikę bezpieczeń-
stwa  opartego  na  uprawnieniach 
kodu (CAS – Code Access Security). 
Bardzo dobrą informacją dla wszyst-
kich, którzy spędzili  długie  godziny 
na  rozgryzaniu  działania  tego  roz-
wiązania oraz wszystkich jego usta-
wień  jest  to,  że  dla  Silverlight  po 
prostu przestało ono istnieć. Stan-
dardowy CAS znany z pełnej wersji 
.NET został wycofany. 

W  CoreCLR  (tak  nazywa  się 

CLR w Silverlight) nie znajdziemy już 
uprawnień, poziomów zabezpieczeń 
oraz  przejść  po  stosie  zabezpie-
czeń.  Przestrzeń  nazw  System.Se-
curity
  została  bardzo  mocno  ogra-
niczona.  Wnikliwi  programiści,  któ-
rzy wykonają dekompilację biblioteki 
mscorlib.dll, zauważą jednak, że kla-
sa 

SecurityPermission

  nadal  istnie-

je. O co więc chodzi? Jeśli nasza bi-
blioteka  zawiera  jakiś  niesprawdzo-
ny kod, wtedy kompilator wywoła fla-
gę 

RequestMinimum

  dla  właściwości 

SkipVerification

.

Model  bezpieczeństwa  w  Co-

reCLR,  który  musi  zastąpić  CAS, 
może zostać opisany następująco:

•  każdy  kod  użytkownika,  który 

uruchamiany  jest  w  CoreCLR, 
jest zupełnie przeźroczysty,

•  kod platformy (charakterystycz-

ny  dla  danego  systemu  opera-
cyjnego)  może  zawierać  dwa 
rodzaje kodu: przeźroczysty i kry-
tyczny.  Jest  on  odpowiedzialny 
za  umożliwienie  uruchomienia 
przeźroczystego  kodu  w  taki 
sposób, aby miał on bezpieczny
dostęp do różnych usług syste-
mowych.

Reasumując,  oznacza  to,  że  w  mo-
delu bezpieczeństwa CoreCLR apli-
kacje  Silverlight  nie  mogą  zawierać 
kodu,  który  nie  jest  zweryfikowany 
i mogą wywoływać tylko i wyłącznie 

metody API, które są przeźroczyste 
lub krytyczne. 

Zagłębiamy się 

w szczegóły

No dobrze, ale czym właściwie jest 
kod przeźroczysty? Jest to taki kod, 
który nie może wykonać żadnej ak-
cji  skutkującej  odwołaniem  do  sto-
su  uprawnień.  A  dokładniej,  prze-
źroczysty  kod  nie  może  w  żaden 
sposób  spowodować  sprawdzenia 
zabezpieczeń,  które  zakończy  się 
sukcesem  (może  natomiast  zakoń-
czyć  się  niepowodzeniem).  Przeci-
wieństwem jest kod krytyczny, któ-
rego biblioteki mogą zawierać kom-
binacje kodu krytycznego i przeźro-
czystego.  Pojedyncze  metody  mo-
gą  być  przeźroczyste  lub  krytycz-
ne, jednak nie mogą łączyć obu ro-
dzajów kodu. 

Ograniczenia  dla  kodu  przeźro-

czystego:

•  nie może wykorzystywać atrybu-

tu LinkDemand,

•  nie  może  wywoływać  Assert 

w CAS,

•  nie  może  zawierać  nieweryfiko-

walnego kodu,

•  nie  może  wywoływać  natywne-

go kodu przy użyciu P/Invoke lub 
COM Interop,

•  nie  może  zapewniać  dostępu 

do  kodu  krytycznego  lub  da-
nych tam, gdzie nie jest to po-
trzebne.

Na  początku  tekstu  mówiliśmy,  że 
w Silverlight nie ma CAS, więc o co 
chodzi w pierwszych dwóch ograni-
czeniach?  Przecież  bez  Code  Ac-
cess  Security
  nie  można  wywołać 
Assert,  a  nawet  zwykłego  LinkDe-
mand
. Póki nie mamy koncepcji żą-
dań  w  Silverlight,  którego  mecha-
nizm  wywołania  nie  jest  właściwy, 
zamiast  tego  wywołujemy  wyjątek 

klasy 

MethodAccessException

 – o ile 

kod  przeźroczysty  próbuje  złamać 
ustalone  zasady.  Najbardziej  inte-
resujące jest ostatnie ograniczenie. 
W  przypadku,  gdy  kod  przeźro-
czysty  próbuje  bezpośrednio  wy-
wołać  kod  krytyczny,  to  wywołany 
będzie wyjątek klasy 

MethodAccess-

Exception

.  Niemniej  jednak  więk-

szość  z  interesujących  nas  usług 
wymaga  implementacji  jako  kod 
krytyczny  (np.  dostęp  do  systemu 
plików).  Jeśli  mamy  do  czynienia 
z takim właśnie przypadkiem, to jak 
Silverlight może uzyskać dostęp do 
tego typu usług?

Wspominałem wcześniej o tym, 

że  dostęp  do  plików  oraz  wszelkie 
operacje  wejścia/wyjścia  powinny
być  implementowane  jako  bezpie-
czny kod. Aby mieć możliwość trwa-
łego  przechowywania  danych,  mu-
simy posiadać jakąś warstwę dla ko-
du krytycznego, który będzie mógł
być  wywoływany.  W  Silverlight  tą
krytyczną  warstwą  jest 

Isolated-

Storage

.  Kiedy  aplikacja  Silverlight 

wywołuje 

IsolatedStorage

,  wtedy 

API  sprawdza  żądanie,  aby  mieć 
pewność,  że  aplikacja  żąda  prawi-
dłowego  pliku  i  że  nie  jest  prze-
kroczony  dla  niej  tzw.  przydział 
(ang. quote). Jest to analogiczne do 
modelu  wywołań  w  systemie  ope-
racyjnym (patrz Tabela 1).

Podobnie  jak  aplikacje  urucha-

miane  na  MacOS  i  Windows  nie 
mogą  odwoływać  się  bezpośred-
nio do jądra systemu operacyjnego 
bez przejścia przez powłokę wywo-
łań  systemowych,  tak  też  aplikacje 
Silverlight  nie  mogą  bezpośrednio 
wywoływać  krytycznego  kodu  bez 
przejścia  przez  bezpieczną  powło-
kę krytyczną. W Silverlight cały kod 
jest standardowo przeźroczysty (i to 
odróżnia go od CLR w wersji desk-
top,  gdzie  cały  kod  z  definicji  jest 
krytyczny). 

Tabela 1. 

Przykłady zastosowania IsolatedStorage

System operacyjny

CoreCLR

Przykład IsolatedStorage 

Kod w trybie użytkownika

Kod przeźroczysty

Aplikacja Silverlight 

Wywołanie systemowe

Bezpieczne krytyczne API

System.IO.IsolatedStorage

Kod jądra

Krytyczne API

System.IO.FileStream

background image

hakin9 Nr 11/2007

www.hakin9.org

Obrona

64

Kod  platformy  może  być  prze-

źroczysty,  krytyczny  oraz  bezpie-
czny krytyczny (ang. safe critical). 
CoreCLR  automatycznie  wykryje 
kod  platformy,  wiedząc,  skąd  ła-
dowana  jest  biblioteka  (bibliote-
ki  platformy  muszą  być  ładowane 
z  katalogu,  w  którym  jest  zainsta-
lowany  Silverlight)  oraz  poprzez 
sprawdzenie  klucza  publicznego, 
którym  ta  biblioteka  została  pod-
pisana. Tylko i wyłącznie biblioteki 
podpisane  specyficznym  kluczem, 
którym podpisuje je Microsoft, bę-
dą  traktowane  jako  biblioteki  plat-
formy. 

Jeśli  metoda  w  bibliotece  plat-

formy jest opisana atrybutem 

Secu

rityCriticalAttribute

, oznacza to, 

że zawiera ona kod krytyczny. Kod 
przeźroczysty  nie  może  wywołać 

żadnej  metody  kodu  krytycznego 
–  nawet,  jeśli  jest  ona  publiczna.
Każda  próba  złamania  tej  reguły
spowoduje  wywołanie  wyjątku 

Me-

thodAccessException

.

Listing  1.  pokazuje  konstruktor 

dla klasy FileStream w Silverlight 1.1. 
Jest on krytyczny (widać to w linii 5), 
ponieważ  został  opisany  atrybutem 

SecurityCriticalAttribute.

Podobnie  jest  z  każdą  metodą 

w  klasie  Marshal  –  są  one  również 
krytyczne, dopóki będą opisane atry-
butem 

SecurityCriticalAttribute

 (li-

nia 4 na Listingu 2).

Każda metoda w bibliotece plat-

formy  oznaczona  atrybutem

  Securi

tySafeCriticalAttribute

  jest  oczy-

wiście  bezpieczna  krytyczna  (safe 
critical
). Kod aplikacji może wywoły-
wać te metody, dopóki kod przeźro-

czysty  może  wywoływać  bezpiecz-
ny  kod  krytyczny.  Przykładem  kry-
tycznego  API  jest  metoda  Isolated-
StorageFileStream.Write
  (linia  6  na 
Listingu 3). 

Ciekawostką jest fakt, że atrybut 

SecuritySafeCriticalAttribute

  jest 

w rzeczywistości połączeniem dwóch
atrybutów z pełnej wersji .NET: 

Secur

ityCriticalAttribute

 oraz 

SecurityT

reatAsSafeAttribute

.

Potrzeba  jawnego  określania 

metod  atrybutami  SecurityCritical 
oraz 

SecurityTreatAsSafe

  stała  się 

powszechna,  dlatego  też  stworzo-
no  atrybut 

SecuritySafeCritical

Dzięki  stosowaniu  tego  atrybutu 
skracamy  czas  pisania  aplikacji, 
a dodatkowo zmniejszamy wielkość 
metadanych.  Jeśli  metoda  nie  po-
siada ani atrybutu 

SecurityCritical

ani  atrybutu 

SecuritySafeCritical

wtedy  musi  być  ona  przeźroczy-
sta. Jeśli metoda jest widoczna dla 
kodu aplikacji, oznacza to, że apli-
kacja  ma  możliwość  wywołania 
jej  –  ponieważ  przeźroczysty  kod 
ma  zawsze  możliwość  wywołania
innego transparentnego kodu. 

Dokładnie  tak  samo  jest  w  sy-

tuacji,  w  której  aplikacja  Silverlight 
chciałaby  być  sprytna  i  opisać  się 
jednym z atrybutów 

SecurityCritical

 

lub 

SecuritySafeCritical

. W tym mo-

mencie  nie  wydarzy  się  nic,  ponie-
waż CLR wie, że kod aplikacji musi 
być przeźroczysty. 

Bardzo  ważnym  jest  fakt,  że  re-

guły te nie zastępują standardowych 
reguł dostępu (PublicPrivateInter-
nal
),  ale  je  dopełniają.  Dlatego  też 
kod  aplikacji  nie  może  wywoływać 
wewnętrznych metod w bibliotekach 
systemowych  –  nawet,  jeśli  są  one 
przeźroczyste.

Tabela  2.  pokazuje  wszystkie  te 

zależności. 

Dziedziczenie

Na koniec jeszcze kilka słów na te-
mat  dziedziczenia  w  Silverlight.  Na 
początek  określmy  jednak  logicz-
ny  porządek  pomiędzy  poziomami 
transparentności:

• 

przeźroczysty (aplikacja i platfor-
ma),

Listing 1. 

Przykład konstruktora dla klasy FileStream

1

   .

method

 

public

 

hidebysig

 

specialname

 

rtspecialname

 

2

           

instance

 

void

  .

ctor

(

string

 

path

,

3

                                

valuetype

 

System

.

IO

.

FileMode

 

mode

)

 

cil

 

managed

4

   

{

5

 .

custom

 

instance

 

void

 

System

.

Security

.

SecurityCriticalAttribute

::

.

ctor

()

 

=

 

(

 

01

 

00

 

00

 

00

 

)

 

6

 

7

     // ...

8

   

}

Listing 2. 

Przykład metody w klasie Marshal

1

 .

class

 

public

 

abstract

 

auto

 

ansi

 

sealed

 

beforefieldinit

 

System

.

Runtime

.

Inte

ropServices

.

Marshal

2

        

extends

 

System

.

Object

3

 

{

4

   .

custom

 

instance

 

void

 

System

.

Security

.

SecurityCriticalAttribute

::

.

ctor

()

 

=

 

(

 

01

 

00

 

00

 

00

 

)

 

5

 

6

   // ...

7

 

}

 // 

end

 

of

 

class

 

System

.

Runtime

.

InteropServices

.

Marshal

Listing 3. 

Metoda IsolatedStorageFileStream.Write.

1

   .

method

 

public

 

hidebysig

 

virtual

 

instance

 

void

 

2

           

Write

(

uint8

[]

 

buffer

,

3

                 

int32

 

offset

,

4

                 

int32

 

count

)

 

cil

 

managed

5

   

{

6

     .

custom

 

instance

 

void

 

System

.

Security

.

SecuritySafeCriticalAttribute

::

.

ctor

()

 

=

 

(

 

01

 

00

 

00

 

00

 

)

 

7

 

8

     // ...

9

   

}

background image

Bezpieczeństwo Silverlight

hakin9 Nr 11/2007

www.hakin9.org

65

• 

bezpieczny krytyczny (tylko plat-
forma),

• 

krytyczny (tylko platforma).

Ale jak się to ma do dziedziczenia? 
Otóż kolejność ta jest bardzo istot-
na, kiedy chcemy określić czy da-
na  klasa  może  pochodzić  z  kla-
sy rodzica. Każda klasa może po-
chodzić z innej, ale tylko i wyłącz-
nie z takiej, która jest na takim sa-
mym lub wyższym poziomie hierar-
chii.  Nie  może  ona  nigdy  pocho-
dzić z niższej klasy bazowej w hie-
rarchii.  Oznacza  to,  że  klasy  kry-
tyczne  mogą  pochodzić  z  innych 
dowolnego typu, podczas gdy kla-
sy  transparentne  mogą  pochodzić 
tylko i wyłącznie z innych transpa-
rentnych.

Kolejną istotną kwestią jest moż-

liwość  przeciążania  metod  wirtu-
alnych podczas dziedziczenia. Kie-
dy chcemy przeciążać metody, war-
to  je  wcześniej  pogrupować  we-
dług różnych poziomów bezpieczeń-
stwa:

• 

przeźroczysty  oraz  bezpieczny 
krytyczny kod,

• 

kod krytyczny.

Po pogrupowaniu metod w taki wła-
śnie  sposób  zauważyć  można,  że 
kod  przeźroczysty  ma  dostęp  do 
wszystkiego, podczas gdy kod kry-
tyczny ma dostęp do grupy z pozio-
mu drugiego. Te same reguły sto-
suje się podczas implementacji in-
terfejsów. Wszystkie te reguły dzie-
dziczenia można opisać za pomo-
cą następujących zasad:

• 

typy  mogą  pochodzić  tylko  z  ty-
pów bazowych, które są przeźro-
czyste,

• 

tylko przeźroczyste lub bezpiecz-
ne  krytyczne  metody  mogą  być 
nadpisywane,

• 

tylko transparentne lub krytycz-
ne-bezpieczne metody interfej-
su mogą być implementowane.

Podsumowanie 

Jak  widać,  model  bezpieczeństwa 
Silverlight znacznie odbiega od tego, 
który znamy z pełnej wersji .NET Fra-
mework. Został on znacznie uprosz-
czony,  dzięki  czemu  jest  łatwiejszy 
w implementacji. Ważne jest, aby pro-
gramista zwracał uwagę na wszyst-
kie wymienione kwestie. l

Tabela 2. 

Zależności przy stosowaniu różnych atrybutów i możliwość 

wywoływania metod

Atrybut 

bezpieczeństwa

Rodzaj

Możliwość 

wywołania 

przez kod 

aplikacji

(jeśli metoda 

jest widoczna)

Kod aplikacji 

-

Przeźroczysty

Tak

Platforma

None

Przeźroczysty

Tak

Platforma

SecuritySafe
Critical

Bezpieczny 
krytyczny

Tak

Platforma

SecurityCritical

Krytyczny

Nie

O autorze

Autor jest pracownikiem firmy Microsoft. Na co dzień zajmuje się m. in. tworze-
niem rozwiązań w oparciu o SQL Server w różnych aspektach – bazy relacyjne, 
usługi integracyjne, usługi analityczne. Jest certyfikowanym administratorem baz 
danych (MCDBA). W wolnych chwilach pasjonat fotografii. 
Kontakt z autorem: arturz@microsoft.com