001    package railo.runtime.security;
002    
003    import java.util.Iterator;
004    import java.util.Map.Entry;
005    
006    import railo.runtime.type.Collection.Key;
007    import railo.runtime.type.Struct;
008    
009    /**
010     * Script-protect to remove cross-attacks from strings
011     */
012    public final class ScriptProtect {
013            
014            public static final String[] invalids=new String[]{
015                    "object", "embed", "script", "applet", "meta", "iframe"
016            };
017            
018            /**
019             * translate all strig values of the struct i script-protected form
020             * @param sct Struct to translate its values
021             */
022            public static void translate(Struct sct) {
023                    Iterator<Entry<Key, Object>> it = sct.entryIterator();
024                    Entry<Key, Object> e;
025                    Object value;
026                    while(it.hasNext()) {
027                            e = it.next();
028                            value=e.getValue(); 
029                            if(value instanceof String) {
030                                    sct.setEL(e.getKey(),translate((String)value));
031                            }
032                    }
033            }
034            
035            /**
036             * translate string to script-protected form
037             * @param str
038             * @return translated String
039             */
040            public static String translate(String str) {
041                    // TODO do-while machen und StringBuffer 
042                    int index,last=0,endIndex;
043                    StringBuffer sb=null;
044                    String tagName;
045                    while((index=str.indexOf('<',last))!=-1) {
046                            // read tagname
047                            int len=str.length();
048                            char c;
049                            for(endIndex=index+1;endIndex<len;endIndex++) {
050                                    c=str.charAt(endIndex);
051                                    if((c<'a' || c>'z') && (c<'A' || c>'Z'))break;
052                            }
053                            tagName=str.substring(index+1,endIndex);
054    
055                            if(compareTagName(tagName)) {
056                                    if(sb==null) {
057                                            sb=new StringBuffer();
058                                            last=0;
059                                    }
060                                    sb.append(str.substring(last,index+1));
061                                    sb.append("invalidTag");
062                                    last=endIndex;
063                            }
064                            else if(sb!=null) {
065                                    sb.append(str.substring(last,index+1));
066                                    last=index+1;
067                            }
068                            else last=index+1;
069                            
070                    }
071                    if(sb!=null) {
072                            if(last!=str.length())sb.append(str.substring(last));
073                            return sb.toString(); 
074                    }
075                    return str;
076            }
077            
078            
079            private static boolean compareTagName(String tagName) {
080                    for(int i=0;i<invalids.length;i++) {
081                            if(invalids[i].equalsIgnoreCase(tagName)) return true;
082                    }
083                    return false;
084            }
085    
086            /**
087             * @param args
088             */
089            public static void main(String[] args) {
090                    System.out.println(translate("<hell <script><script susi=1><scriptsrc><> how are you <br />object <object ddd"));
091    
092            }
093    }