#SharePoint 2010 – Enumerate and Deactivate Anonymous access using PowerShell


Acest articol se aplică site-urilor de SharePoint 2010 publicate în Internet care au cerințe de securitate diferite în structură lor.

Una din problemele de securitate în contextul implementărilor complexe este legată de modul de acces la diferite site-uri. Se întâmplă adeseori ca în contextul relaxării securității pentru portalurile de SharePoint publicate în Internet, să ne confruntăm cu un abuz de acces anonim la nivelul anumitor site-uri sau subsite-uri, fapt care poate duce la repudierea în public a unor informații sensibile.

 

Picture1

În diagrama de mai sus site-ul Home are configurat acces anonim, site-urile cu albastru nu au acces anonim iar cele cu roșu au securitate individuală și configurat accesul anonim.

Dacă un anonim accesează adresa: http://home/Site3/ i se vor solicita datele de conectare. În cazul în care apelează http://home/site3/Site32/ nu i se mai cer datele de autentificare pentru a vizualiza pagina. Site-urile 321 și 322 pot avea acces anonim prin moștenire de la site-ul părinte Site32.

Propunerea principală a acestui articol este aceea de inventariere periodică a securității infrastructurii SharePoint în sensul depistării anumitor site-uri web cu conținut sensibil accesibil anonimilor.

În mod clasic pentru a enumera structura unei ferme de SharePoint putem folosi comanda:

stsadm -o enumallwebs > C:\ScriptsOutput\AllSubWebs.xml

care ne permite să exportăm în format XML toată structura din toate bazele de date. Această comandă nu extrage însă și starea de acces în mod anonim la site-ul Web. În aceste condiții trebuie să utilizăm comenzile Powershell specifice SharePoint pentru a putea extrage starea anonimilor.

În articolul lui Brian Beach [1] observăm că există 3 stări ale accesului anonim la un subweb SharePoint: 

  • fără acces anonim: valoarea 0
  • Acces anonim cu configurație implicită de acces la liste și biblioteci: valoarea 1.
  • Acces anonim la întregul site web: valoarea 2.
    Dar pentru a enumera toate site-urile avem nevoie de ceva mai mult. Articolul [3] lui Craig Trulove mi-a salvat destul de multă muncă, pentru că mi-a oferit posibilitatea de a identifica rapid o structură asemănătoare celei extrase de comanda stsadm și care să conțină și starea de acces a anonimilor la site.
    În scriptul de mai jos la linia 89 extrag în structura XML a infrastructurii valoarea parametrului de acces anonim. Copiați codul și salvați-l într-un fișier PS1.
   1: # Autor: Craig Trulove

   2: # WebPage: http://www.craigtothepoint.com/Lists/Posts/Post.aspx?ID=11 

   3: # Modified: Valy Greavu, valygreavu.com

   4:  

   5: #Region Function Definition: EnumAllWebs

   6: function EnumAllWebs

   7: {

   8:     param

   9:     (

  10:         [string]$DatabaseName,

  11:         [string]$DatabaseServer

  12:     )

  13:     #Region Function Definition: FindSiteTemplateReference

  14:     # Checks to see if the specified template is installed in the farm

  15:     # Returns null if template is not found, returns the template if it is

  16:     function FindSiteTemplateReference

  17:     {

  18:         param

  19:         (

  20:             [int]$lcid,

  21:             [string]$TemplateName

  22:         )

  23:         foreach ($template in $templates)

  24:         {

  25:             if (($template.LCID -eq $lcid) -and ($template.Name -eq $TemplateName))

  26:             {

  27:                 return $template

  28:             }

  29:         }

  30:         return $null

  31:     }

  32:     #EndRegion Function Definition: FindSiteTemplateReference

  33:     #Region Function Definition: ProcessOneContentDatabase

  34:     # Runs for each database

  35:     function ProcessOneContentDatabase

  36:     {

  37:         param

  38:         (

  39:             [System.Xml.XmlTextWriter]$writer,

  40:             [Microsoft.SharePoint.Administration.SPContentDatabase]$db

  41:         )

  42:         #Region Function Definition: OutputSiteXml

  43:         # Generates the XML for each site

  44:         function OutputSiteXml

  45:         {

  46:             param

  47:             (

  48:                 [System.Xml.XmlTextWriter]$writer,

  49:                 [Microsoft.SharePoint.SPSite]$site

  50:             )

  51:             $writer.WriteStartElement("Site")

  52:             $writer.WriteAttributeString("Id", $site.ID)

  53:             $writer.WriteAttributeString("OwnerLogin", $site.Owner.LoginName)

  54:             # Check if it is a host header site collection

  55:             if ($site.HostHeaderIsSiteName)

  56:             {

  57:                 $writer.WriteAttributeString("HostHeader", $site.HostName)

  58:             }

  59:             if ($site.AllWebs.Count -gt 0)

  60:             {

  61:                 $writer.WriteStartElement("Webs")

  62:                 $writer.WriteAttributeString("Count", $site.AllWebs.Count)

  63:                 foreach ($web in $site.AllWebs)

  64:                 {

  65:                     try

  66:                     {

  67:                         $reference = FindSiteTemplateReference -lcid $web.Language -TemplateName "$($web.WebTemplate)#$($web.Configuration)"

  68:                         # Check if web template is properly installed

  69:                         if ($reference -eq $null)

  70:                         {

  71:                             $str = "Unknown"

  72:                         }

  73:                         elseif ($web.Configuration -eq -1)

  74:                         {

  75:                             $str = [string]::Empty

  76:                         }

  77:                         else

  78:                         {

  79:                             $str = "$($web.WebTemplate)#$($web.Configuration)"

  80:                         }

  81:                         $writer.WriteStartElement("Web")

  82:                         $writer.WriteAttributeString("Id", $web.ID)

  83:                         $writer.WriteAttributeString("Url", $web.Url)

  84:                         # Extract AnonymousState 

  85:                         # AnonymousState determines if anonymous users have access to the site collection as follows:

  86:                         # A "0" disables anonymous access. In other words, anonymous users have no access to a Web site.

  87:                         # A "1" allows default anonymous access. This specifies that anonymous users can access lists and libraries if the lists and libraries allow anonymous access.

  88:                         # A "2" specifies that anonymous users can access the entire Web site.

  89:                         $writer.WriteAttributeString("Anonymmous", $web.AnonymousState)

  90:                         # Handle cases where str var not set or set to empty string

  91:                         if (($str -ne $null) -and ($str -ne [string]::Empty))

  92:                         {

  93:                             $writer.WriteAttributeString("TemplateName", $str);

  94:                         }

  95:                         if ($web.Configuration -ne -1)

  96:                         {

  97:                             $writer.WriteAttributeString("TemplateId", $web.WebTemplate);

  98:                         }

  99:                       $writer.WriteEndElement()

 100:                     }

 101:                     catch [Exception]

 102:                     {

 103:                     }

 104:                     finally

 105:                     {

 106:                         $web.Dispose()

 107:                     }

 108:                 }

 109:                 # End element for webs

 110:                 $writer.WriteEndElement()

 111:             }

 112:             # End element for site

 113:             $writer.WriteEndElement()

 114:         }

 115:         #EndRegion Function Definition: OutputSiteXml

 116:         $writer.WriteStartElement("Database")

 117:         $writer.WriteAttributeString("SiteCount", $db.CurrentSiteCount)

 118:         $writer.WriteAttributeString("Name", $db.Name)

 119:         $writer.WriteAttributeString("DataSource", $db.ServiceInstance.NormalizedDataSource)

 120:         # Only process sites if any exist

 121:         if ($db.Sites.Count -gt 0)

 122:         {

 123:             $writer.WriteStartElement("Sites")

 124:             foreach ($site in $db.Sites)

 125:             {

 126:                 try

 127:                 {

 128:                     OutputSiteXml -writer $writer -site $site

 129:                 }

 130:                 catch [Exception]

 131:                 {

 132:                 }

 133:                 finally

 134:                 {

 135:                     $site.Dispose()

 136:                 }

 137:             }

 138:             # End element for sites

 139:             $writer.WriteEndElement()

 140:         }

 141:         #End element for database

 142:         $writer.WriteEndElement()

 143:     }

 144:     #EndRegion Function Definition: ProcessOneContentDatabase

 145:     

 146:     # Create bool vars for passing to sub functions

 147:     $local = Get-SPFarm

 148:     $services = New-Object Microsoft.SharePoint.Administration.SPWebServiceCollection $local

 149:     $cs = [Microsoft.SharePoint.Administration.SPWebService]::ContentService

 150:     $templates = Get-SPWebTemplate

 151:     $StringWriter = New-Object System.IO.StringWriter

 152:     $writer = New-Object System.XMl.XmlTextWriter $StringWriter

 153:     $writer.Formatting = "indented"

 154:     $writer.WriteStartElement("Databases")

 155:     # if database was specifed process only that database

 156:     if ($DatabaseName)

 157:     {

 158:         # if databaseserver was not specified use default

 159:         if ($DatabaseServer -eq $null) { $DatabaseServer = $cs.DefaultDatabaseInstance.DisplayName }

 160:         $db = Get-SPContentDatabase -DatabaseName $DatabaseName -DatabaseServer $DatabaseServer

 161:         # Process database

 162:         ProcessOneContentDatabase -writer $writer -db $db 

 163:     }

 164:     # otherwise process all databases

 165:     else

 166:     {

 167:         foreach ($service in $services)

 168:         {

 169:             foreach ($application in $service.WebApplications)

 170:             {

 171:                 foreach ($database2 in $application.ContentDatabases)

 172:                 {

 173:                     # Process database

 174:                     ProcessOneContentDatabase -writer $writer -db $database2

 175:                 }

 176:             }

 177:         }

 178:     }

 179:     # End element for databases

 180:     $writer.WriteEndElement()

 181:     # Return output as string

 182:     $StringWriter.ToString()

 183:     $StringWriter.Flush()

 184:     $writer.Flush()

 185: }

 186: #EndRegion Function Definition: EnumAllWebs

 187: # Call function

 188: enumallwebs

Execuția:

.\enumallsubwebs.ps1 > C:\ScriptsOutput\AllSubWebs.xml

crează fișierul AllSubWebs.xml pe care-l putem deschide și analiza cu Excel.

Coloanele care ne interesează sunt:

    Scriptul lui Craig conține o mică eroare care împiedică enumerarea corectă a site-urilor corespondente bazei de date MySite, dar de obicei această aplicație web nu se configurează pentru acces anonim.
    Fișierul XML deschis în Excel îl putem filtra pentru a identifica site-urile cu acces anonim, a le evalua în sensul dacă ele corespund politicilor instituției de acces. În cazul în care dorim să dezactivăm accesul anonim pentru anumite site-uri putem să compunem în Excel comenzile de dezactivare care trebuie să fie de felul următor:
       1: # Preluare într-o variabilă PowerShell a valorii curente a site-ului care are activat acces anonim

       2: $Web = Get-SPWeb http://home/site3/Site32/ 

       3: # Dezactivarea accesului anonim.

       4: $Web.AnonymousState = 0

       5:  

Operațiunea se repetă pentru toate site-urile ale căror acces anonim trebuie să fie dezactivat.

Succes!

Referințe:

Anunțuri

2 gânduri despre “#SharePoint 2010 – Enumerate and Deactivate Anonymous access using PowerShell

  1. Pingback: Sharepoint Updates November-28-2011 | SDavara's Sharepoint Knowledge Center

  2. va rugam un ajutor in instalarea sharepoint 2010; problema este
    ca la instalare , dupa introducerea key-ului, nu apare optiunea de
    a alege intre standalone si server farm ci trece direct la alegerea directorului de instalare (?!)

    Apreciază

Lasă un răspuns

Completează mai jos detaliile tale sau dă clic pe un icon pentru a te autentifica:

Logo WordPress.com

Comentezi folosind contul tău WordPress.com. Dezautentificare / Schimbă )

Poză Twitter

Comentezi folosind contul tău Twitter. Dezautentificare / Schimbă )

Fotografie Facebook

Comentezi folosind contul tău Facebook. Dezautentificare / Schimbă )

Fotografie Google+

Comentezi folosind contul tău Google+. Dezautentificare / Schimbă )

Conectare la %s