Exemplo n.º 1
0
        public static TConfiguration UseCodeTransformation <TConfiguration>(this TConfiguration configuration, string sourceFile, Action <ICodeTransformation> transformerAction)
            where TConfiguration : IConfiguration
        {
            ICodeTransformationAction transformation = new CodeTransformation();

            transformerAction(transformation);
            configuration.AddStep(new CodeTransformationStep(sourceFile, transformation));
            return(configuration);
        }
Exemplo n.º 2
0
        private void Run(CodeTransformation version, string[] args, MemoryStore memoryStore)
        {
            PhpArray get     = PhpArgumentParser.Parse("get", args);
            PhpArray post    = PhpArgumentParser.Parse("post", args);
            PhpArray cookies = PhpArgumentParser.Parse("cookies", args);
            PhpArray session = PhpArgumentParser.Parse("session", args);

            _evaluator.Evaluate(version, get, post, cookies, session, memoryStore);
        }
Exemplo n.º 3
0
        public void Evaluate(CodeTransformation codeTransformation, PhpArray getVariables, PhpArray postVariables, PhpArray cookieVariables, PhpArray sessionVariables, MemoryStore memoryStore)
        {
            var fullpath = Path.Combine(Directory.GetCurrentDirectory(), "main.php");

            //Context.CreateConsole() is a Peachpie runtime object, representing a PHP runtime thread.
            using (var ctx = Context.CreateConsole(string.Empty, new string[] { }))
            {
                //declare methods to store/read channel values
                ctx.DeclareFunction(FunctionNames.StoreInput, new Func <int, string, string>((id, val) => { ctx.Echo($"Stored input value for channel {id}: {val}\n"); memoryStore.Store(id, val); return(val); }));
                ctx.DeclareFunction(FunctionNames.GetInput, new Func <int, string, string>((id, val) => { var readValue = memoryStore.Get(id, codeTransformation.SecurityLevel.Level); ctx.Echo($"Get input value for channel {id}: {readValue}\n"); return(readValue); }));
                ctx.DeclareFunction(FunctionNames.StoreSanitize, new Func <int, string, string>((id, val) => { ctx.Echo($"Stored sanitized value for channel {id}: {val}\n"); memoryStore.Store(id, val); return(val); }));
                ctx.DeclareFunction(FunctionNames.GetSanitize, new Func <int, string, string>((id, val) => { var readValue = memoryStore.Get(id, codeTransformation.SecurityLevel.Level); ctx.Echo($"Get sanitized value for channel {id}: {readValue}\n"); return(readValue); }));

                ctx.DeclareFunction(FunctionNames.CaptureOutput, new Action <int, string>((id, val) => { ctx.Echo($"Captured output value for channel {id}: {val}\n"); }));
                ctx.DeclareFunction(FunctionNames.StoreOutput, new Action <int, string>((id, val) => { ctx.Echo($"Stored output value for channel {id}: {val}\n"); memoryStore.Store(id, val); }));
                ctx.DeclareFunction(FunctionNames.GetOutput, new Func <int, string>((id) => { var readValue = memoryStore.Get(id, codeTransformation.SecurityLevel.Level); ctx.Echo($"Get output value for channel {id}: {readValue}\n"); return(readValue); }));

                ctx.Get     = getVariables;
                ctx.Post    = postVariables;
                ctx.Cookie  = cookieVariables;
                ctx.Session = sessionVariables;

                var script = _provider.CreateScript(new Context.ScriptOptions()
                {
                    Context              = ctx,
                    Location             = new Location(fullpath, 0, 0),
                    EmitDebugInformation = true,
                    IsSubmission         = false,
                    AdditionalReferences = new string[] {
                        typeof(Peachpie.Library.Graphics.PhpImage).Assembly.Location,
                        typeof(Peachpie.Library.Network.CURLFunctions).Assembly.Location,
                        typeof(Peachpie.Library.MySql.MySql).Assembly.Location,
                        typeof(Peachpie.Library.XmlDom.XmlDom).Assembly.Location,
                    },
                }, codeTransformation.Code);


                //evaluate the php code
                script.Evaluate(ctx, ctx.Globals, null);
            }
        }
Exemplo n.º 4
0
        public TransformationResult Transform(string content, IPolicy policy)
        {
            var result = new TransformationResult();

            var sourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
            var nodesFactory = new BasicNodesFactory(sourceUnit);
            var errors       = new PhpErrorSink();

            sourceUnit.Parse(nodesFactory, errors);
            GlobalCode ast = sourceUnit.Ast;

            if (errors.Count != 0)
            {
                ReportErrors(errors, result, content);
                return(result); // AST is null or invalid
            }

            //collect channel information from source code
            var provider          = SourceTokenProviderFactory.CreateEmptyProvider();
            var collectorComposer = new PhpTokenComposer(provider);
            var collector         = new PhpChannelCollector(policy, new TreeContext(ast), collectorComposer, provider);

            collector.VisitElement(ast);
            result.InputChannels.AddRange(collector.InputChannels);
            result.OutputChannels.AddRange(collector.OutputChannels);
            result.SanitizeChannels.AddRange(collector.SanitizeChannels);

            //if there are no output or input channels found in the code, it makes no sense to transform it
            if (result.OutputChannels.Count == 0 || result.InputChannels.Count == 0)
            {
                return(result);
            }

            var levels = collector.GetDistinctSecurityLevels().OrderByDescending(sl => sl.Level);

            //append a sanitize transformation if there are sanitize channels
            var lowestInputLevel = result.InputChannels.Min(sc => sc.Label.Level);

            if (result.SanitizeChannels.Any())
            {
                var sanSourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
                var sanNodesFactory = new BasicNodesFactory(sourceUnit);
                var sanErrors       = new PhpErrorSink();
                sanSourceUnit.Parse(sanNodesFactory, sanErrors);
                GlobalCode sanAst = sanSourceUnit.Ast;
                if (sanErrors.Count != 0)
                {
                    return(result); // AST is null or invalid
                }

                var pSanitize = new CodeTransformation();
                pSanitize.Kind          = TransformationKind.Sanitize;
                pSanitize.SecurityLevel = new SecurityLevel()
                {
                    Level = lowestInputLevel - 1, Name = "PS"
                };
                var composer = new PhpTokenComposer(provider);
                var rewriter = new PhpChannelRewriter(new TreeContext(sanAst), composer, provider, nodesFactory, policy, collector.InputChannels, collector.OutputChannels, collector.SanitizeChannels, pSanitize.SecurityLevel);
                rewriter.VisitElement(sanAst);
                pSanitize.Code = composer.Code.ToString();

                result.CodeTransformations.Add(pSanitize);
            }

            //create code version for each security level
            foreach (var level in levels)
            {
                var levelSourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
                var levelNodesFactory = new BasicNodesFactory(levelSourceUnit);
                var levelerrors       = new PhpErrorSink();
                levelSourceUnit.Parse(nodesFactory, levelerrors);
                GlobalCode levelAst = levelSourceUnit.Ast;
                if (levelerrors.Count != 0)
                {
                    return(result); // AST is null or invalid
                }


                var version = new CodeTransformation();
                version.Kind          = TransformationKind.Default;
                version.SecurityLevel = level;
                var composer = new PhpTokenComposer(provider);
                var rewriter = new PhpChannelRewriter(new TreeContext(levelAst), composer, provider, levelNodesFactory, policy, collector.InputChannels, collector.OutputChannels, collector.SanitizeChannels, level);
                rewriter.VisitElement(levelAst);
                version.Code = composer.Code.ToString();


                result.CodeTransformations.Add(version);
            }

            //create P version
            var poSourceUnit   = new CodeSourceUnit(content, filename, System.Text.Encoding.UTF8, Lexer.LexicalStates.INITIAL, LanguageFeatures.Php71Set);
            var poNodesFactory = new BasicNodesFactory(poSourceUnit);
            var poErrors       = new PhpErrorSink();

            poSourceUnit.Parse(poNodesFactory, poErrors);
            GlobalCode poAst = poSourceUnit.Ast;

            var po = new CodeTransformation();

            po.Kind = TransformationKind.Original;
            var poComposer = new PhpTokenComposer(provider);

            po.SecurityLevel = new SecurityLevel()
            {
                Level = lowestInputLevel, Name = "P'"
            };
            var poRewriter = new PhpChannelRewriter(new TreeContext(poAst), poComposer, provider, poNodesFactory, policy, collector.InputChannels, collector.OutputChannels, collector.SanitizeChannels, po.SecurityLevel, isOriginalProgram: true);

            poRewriter.VisitElement(poAst);
            po.Code = poComposer.Code.ToString();
            result.CodeTransformations.Add(po);

            return(result);
        }