Error on 'add post' (partial trust callers?)

Mar 22, 2009 at 6:17 PM
I seem to have somewhat successfully deployed Oxite to a medium-trust shared host (GoDaddy shared hosting) running inside of a virtual directory (I host a few sites there). I setup a sql server 2005 database with the oxite tables (via the setup script) and changed the web.config connection string. Site runs (www.robrobbins.info), I can login with the admin user I created, however when I try to 'add a post' I get the following error:

Security Exception

Description: The application attempted to perform an operation not allowed by the security policy.  To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Exception Details: System.Security.SecurityException: That assembly does not allow partially trusted callers.

Source Error:

Line 2:  <%@ Import Namespace="Oxite.Mvc.Extensions" %>
Line 3:      <form method="post" action="">
Line 4:          <div class="avatar"><%=Html.Gravatar("48") %></div>
Line 5:  	    <h2 class="title">
Line 6:  	        <label for="post_title"><%=Model.Localize("Title")%></label><%=Html.ValidationMessage("Post.Title", Model.Localize("Title isn't valid.")) %>

Mar 23, 2009 at 4:22 AM
Did some more experimenting, I can run the project from my local machine (logged into the remote database on my server[godaddy]) and run the site fine, add and edit posts etc..However once compiled and copied to the shared server environment
I get the security exceptions regularly. Now, after creating new posts from the local machine (to the remote DB) the site won't open when navigated to :

funny thing is this:
www.robrobbins.info (security error) "That assembly does not allow partially trusted callers"
www.robrobbins.info/About (opens fine, no error).

Should there be a use of AllowPartiallyTrustedCallersAttribute?




Coordinator
Mar 23, 2009 at 9:00 AM
I honestly have no idea what that Gravatar extension method would cause for that error to happen.

Oxite requires Medium Trust + the Reflection Permission to run, but again, not sure what that Gravatar extenion method would have to do with it.  Is the server your hosted on running .NET 3.5 SP 1?

Does GoDaddy support have anything to say about it since this is a production environment issue?
Mar 23, 2009 at 5:03 PM
Yes on the 3.5 and sp1, my account is also using IIS7.

I think the answer may lie with the reflection permission, that I will pursue today, anyone else have this issue?

Coordinator
Mar 23, 2009 at 5:38 PM
Reflection permissions are required for our LINQ to SQL data provider so anyone that doesn't have them won't be able to run Oxite.  Some providers seem to allow it by default, some don't.  You might try asking them to turn it on for you if it's not on already.
Mar 24, 2009 at 5:50 PM
Still following up with godaddy. Erik, would using the AllowPartiallyTrustedCallersAttribute fix this? If I placed this on the assemblyinfo.cs would this work or only produce more errors? I'm away from my
desk all day and will have to try this tomorrow...I may just need to move away from GoDaddy.

Coordinator
Mar 24, 2009 at 7:02 PM
To be honest, I have no idea if that would help or hurt.  I don't know much about it.  You could try.  It's not like getting worse will hurt too much.  :)

I'd be interested to hear what GoDaddy comes back with, but if you have to move, I know DiscountASP .NET and Server Intellect work fine with Oxite and I'm sure there are others.
Mar 24, 2009 at 8:19 PM
GoDaddy came back with an absolute no on reflection permission. Tomorrow I am going to attempt the mod's with the allowPartialTrustCallers attribute. I think that if Oxite is going to
attempt to position itself into the mainstream this issue is a must-fix. The cost rises drastically when looking at discount asp.net and server intellect. I thought discount asp.net
may be an alternative but just by adding ms sql (05 or 08) to your account doubles the price! no thanks.

Anyway, I'll post tomorrow my results...


Mar 24, 2009 at 8:56 PM
I am running oxite on webhost4life and it is less than 10 bucks a month.  You MAY even be able to do it on their 5 bucks a month plan, but I'm not sure.  I had to ask that my application be run in integrated pipeline mode, but that's about it.  That was more because of MVC and less of anything to do with Oxite.
Mar 24, 2009 at 9:37 PM
You know I looked at your post and meant to email you, I will probably contact them tomorrow, I just developed a site for a guy
who hosts there. I really liked the live text chat feature, handy...
Mar 24, 2009 at 9:43 PM
Ok, now I HAVE to tell the whole story.  ;)

I uploaded my slightly modified oxite site.  Crashed.  I logged into webhost4life and got on the chat with them.  As it turned out changing my application to run with the right app pool etc., was not something that person was allowed to do so they helped me submit a ticket to go to the advanced support guys and within an hour I was all set.

The price is right (my opinion), speed is decent, support so far has really been great.  I suspect over the course of the year and I half I've worked with them I've submitted more than 10 tickets for various things and have always got a prompt reply.  Best host I've worked with for cheap.
Mar 26, 2009 at 5:19 PM
I didn't have success yesterday with decorating the assemblyinfo.cs files with the 'AllowPartiallyTrustedCallers' attribute. I looked at perhaps adding it at the class level, but I noticed that if the
attribute existed in ANY class in the solution (this per each of the 5 sections in the solution) placing it in the assemblyinfo.cs results in an error stating that you have the attribute twice. Therefore
I am assuming, possibly erroneously, that placing the attribute in every class would be no more effective than placing it once in the assemblyinfo. Anybody? Anyway, that raised to me the question
'perhaps this error is arising from an assembly outside of the compiled OxiteSite being called by a partially trusted caller (inside of the compiled site)'. An assembly in the server GAC maybe? Am I
wrong there? Something I do not have access to decorate with the AllowPartiallyTrustedCallers attribute?

On to another host then, barring a breakthrough, I contacted webhost4life and discountASP.net...nosajis what was that app pool mod you had to make? so I can know ahead of time, wh4l is
probably where I'm going.

rob.r
Coordinator
Mar 26, 2009 at 9:08 PM
If they have ASP.NET MVC installed on your server then you're getting that from the GAC.  Otherwise, it's loading from your bin dir.  I wouldn't think MVC would be the problem here though.  Other than MVC and .NET 3.5, Oxite is self contained.
Mar 26, 2009 at 9:12 PM
Rob, they called it integrated application pool mode
Apr 5, 2009 at 6:39 PM
Did anyone get this thing running on GoDaddy?   I have the same error when trying to add a post.
Oct 4, 2009 at 1:45 PM
Edited Oct 5, 2009 at 6:48 AM

I have this running on a Godaddy medium trust level account. The problem is in the AntiXSSLibrary. Rebuilding the library with [assembly: System.Security.AllowPartiallyTrustedCallers()] in the Assembly.info didn't work for me. But the next steps did solve my problem:

1) I delete the reference to the Library from my Oxite project.
2) I copied the used functions from AntiXSS to a new class in my Oxite project (see code below)
3) Change using Microsoft.Security.Application in StringExtensions to: using
Oxite.Security.Application
4) Rebuild and publish my Oxite Solutions.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Oxite.Security.Application
{
    public sealed class AntiXss
    {
        private AntiXss() { }
        #region HTMLEncode - string input
        ///---------------------------------------------------------------------
        /// <summary>
        /// Encodes input strings for use in HTML.
        /// </summary>
        /// <param name="input">String to be encoded</param>
        /// <returns>
        ///     Encoded string for use in HTML.
        /// </returns>
        /// <remarks>
        /// This function encodes all but known safe characters.  Characters are encoded using  &amp;#DECIMAL; notation.
        /// <newpara/>
        /// Safe characters include:
        /// <list type="table">
        /// <item><term>a-z</term><description>Lower case alphabet</description></item>
        /// <item><term>A-Z</term><description>Upper case alphabet</description></item>
        /// <item><term>0-9</term><description>Numbers</description></item>
        /// <item><term>,</term><description>Comma</description></item>
        /// <item><term>.</term><description>Period</description></item>
        /// <item><term>-</term><description>Dash</description></item>
        /// <item><term>_</term><description>Underscore</description></item>
        /// <item><term> </term><description>Space</description></item>
        /// <item><term> </term><description>Other International character ranges</description></item>
        /// </list>
        /// <newpara/>
        /// Example inputs and their related encoded outputs:
        /// <list type="table">
        /// <item><term>alert('XSS Attack!');</term><description>alert&#40;&#39;XSS Attack&#33;&#39;&#41;&#59;</description></item>
        /// <item><term>user@contoso.com</term><description>user&#64;contoso.com</description></item>
        /// <item><term>Anti-Cross Site Scripting Library</term><description>Anti-Cross Site Scripting Library</description></item>
        /// </list></remarks>
        ///---------------------------------------------------------------------
        public static string HtmlEncode(string input)
        {
            if (String.IsNullOrEmpty(input))
                return string.Empty;

            // Use a new char array.
            int len = 0;
            int tLen = input.Length;
            char[] returnMe = new char[tLen * 8];
            char[] thisChar;
            int thisCharID;
            for (int i = 0; i < tLen; i++)
            {
                thisCharID = (int)input[i];

                if (WhitelistCodes[thisCharID] != null)
                {
                    // character needs to be encoded
                    thisChar = WhitelistCodes[thisCharID];
                    returnMe[len++] = '&';
                    returnMe[len++] = '#';
                    for (int j = 0; j < thisChar.Length; j++)
                    {
                        returnMe[len++] = thisChar[j];
                    }
                    returnMe[len++] = ';';
                }
                else
                {
                    // character does not need encoding
                    returnMe[len++] = input[i];
                }
            }
            return new String(returnMe, 0, len);
        }
        #endregion

        #region HTMLAttributeEncode_Method
        ///---------------------------------------------------------------------
        /// <summary>
        /// Encodes input strings for use in HTML attributes.
        /// </summary>
        /// <param name="input">String to be encoded</param>
        /// <returns>
        ///     Encoded string for use in HTML attributes.
        /// </returns>
        /// <remarks>
        /// This function encodes all but known safe characters.  Characters are encoded using  &amp;#DECIMAL; notation.
        /// <newpara/>
        /// Safe characters include:
        /// <list type="table">
        /// <item><term>a-z</term><description>Lower case alphabet</description></item>
        /// <item><term>A-Z</term><description>Upper case alphabet</description></item>
        /// <item><term>0-9</term><description>Numbers</description></item>
        /// <item><term>,</term><description>Comma</description></item>
        /// <item><term>.</term><description>Period</description></item>
        /// <item><term>-</term><description>Dash</description></item>
        /// <item><term>_</term><description>Underscore</description></item>
        /// <item><term> </term><description>Other International character ranges</description></item>
        /// </list>
        /// <newpara/>
        /// Example inputs and encoded outputs:
        /// <list type="table">
        /// <item><term>alert('XSS Attack!');</term><description>alert&#40;&#39;XSS&#32;Attack&#33;&#39;&#41;&#59;</description></item>
        /// <item><term>user@contoso.com</term><description>user&#64;contoso.com</description></item>
        /// <item><term>Anti-Cross Site Scripting Library</term><description>Anti-Cross&#32;Site&#32;Scripting&#32;Library</description></item>
        /// </list></remarks>
        ///---------------------------------------------------------------------
        public static string HtmlAttributeEncode(string input)
        {
            if (String.IsNullOrEmpty(input))
                return string.Empty;

            // Use a new char array.
            int len = 0;
            int tLen = input.Length;
            char[] returnMe = new char[tLen * 8]; // worst case length scenario
            char[] thisChar;
            int thisCharID;
            for (int i = 0; i < tLen; i++)
            {
                thisCharID = (int)input[i];
                if ((WhitelistCodes[thisCharID] != null)
                    || (thisCharID == 32)   //escaping space for HTMLAttribute Encoding
                    )
                {
                    // character needs to be encoded
                    thisChar = WhitelistCodes[thisCharID];

                    returnMe[len++] = '&';
                    returnMe[len++] = '#';
                    if (thisCharID == 32)
                    {
                        returnMe[len++] = '3';
                        returnMe[len++] = '2';
                    }
                    else
                    {
                        for (int j = 0; j < thisChar.Length; j++)
                        {
                            returnMe[len++] = thisChar[j];
                        }
                    }
                    returnMe[len++] = ';';
                }
                else
                {
                    // character does not need encoding
                    returnMe[len++] = input[i];
                }
            }
            return new String(returnMe, 0, len);
        }

        #endregion

        private static char[][] WhitelistCodes = InitWhitelistCodes();

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.Int32.ToString"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        private static char[][] InitWhitelistCodes()
        {
            char[][] allCharacters = new char[65536][];
            char[] thisChar;
            for (int i = 0; i < allCharacters.Length; i++)
            {
                if (
                    (i >= 97 && i <= 122) ||        // a-z
                    (i >= 65 && i <= 90) ||         // A-Z
                    (i >= 48 && i <= 57) ||         // 0-9
                    i == 32 ||                      // space
                    i == 46 ||                      // .
                    i == 44 ||                      // ,
                    i == 45 ||                      // -
                    i == 95 ||                      // _
                    (i >= 256 && i <= 591) ||       // Latin,Extended-A,Latin Extended-B        
                    (i >= 880 && i <= 2047) ||      // Greek and Coptic,Cyrillic,Cyrillic Supplement,Armenian,Hebrew,Arabic,Syriac,Arabic,Supplement,Thaana,NKo
                    (i >= 2304 && i <= 6319) ||     // Devanagari,Bengali,Gurmukhi,Gujarati,Oriya,Tamil,Telugu,Kannada,Malayalam,Sinhala,Thai,Lao,Tibetan,Myanmar,eorgian,Hangul Jamo,Ethiopic,Ethiopic Supplement,Cherokee,Unified Canadian Aboriginal Syllabics,Ogham,Runic,Tagalog,Hanunoo,Buhid,Tagbanwa,Khmer,Mongolian   
                    (i >= 6400 && i <= 6687) ||     // Limbu, Tai Le, New Tai Lue, Khmer, Symbols, Buginese
                    (i >= 6912 && i <= 7039) ||     // Balinese         
                    (i >= 7680 && i <= 8191) ||     // Latin Extended Additional, Greek Extended        
                    (i >= 11264 && i <= 11743) ||   // Glagolitic, Latin Extended-C, Coptic, Georgian Supplement, Tifinagh, Ethiopic Extended    
                    (i >= 12352 && i <= 12591) ||   // Hiragana, Katakana, Bopomofo       
                    (i >= 12688 && i <= 12735) ||   // Kanbun, Bopomofo Extended        
                    (i >= 12784 && i <= 12799) ||   // Katakana, Phonetic Extensions         
                    (i >= 40960 && i <= 42191) ||   // Yi Syllables, Yi Radicals        
                    (i >= 42784 && i <= 43055) ||   // Latin Extended-D, Syloti, Nagri        
                    (i >= 43072 && i <= 43135) ||   // Phags-pa         
                    (i >= 44032 && i <= 55215) ||   // Hangul Syllables 
                    (i >= 19968 && i <= 40899)      // Mixed japanese/chinese/korean
                )
                {
                    allCharacters[i] = null;
                }
                else
                {
                    string iString = i.ToString();
                    int iStringLen = iString.Length;
                    thisChar = new char[iStringLen];     // everything else
                    for (int j = 0; j < iStringLen; j++)
                    {
                        thisChar[j] = iString[j];
                    }
                    allCharacters[i] = thisChar;
                }
            }
            return allCharacters;
        }
    }
}