├── PHPAnalysis-parser
├── src
│ ├── parsed.xml
│ ├── config.yml
│ ├── test.php
│ ├── Main.php
│ ├── commands
│ │ ├── GreetCommand.php
│ │ ├── ScanCommand.php
│ │ └── CountCommand.php
│ └── YamlConfigLoader.php
└── composer.json
├── PHPAnalysis
├── PHPAnalysis
│ ├── FunctionSpecs
│ │ ├── JSONSpecifications
│ │ │ ├── Sources.json
│ │ │ ├── CondSanitizers.json
│ │ │ └── XSSSinks.json
│ │ ├── WPSpecifications
│ │ │ └── wpSQLSanitizers.json
│ │ └── StoredSQLProviders
│ │ │ └── databaseProviders.json
│ ├── Utils
│ │ ├── IMergeable.cs
│ │ ├── IDeepCloneable.cs
│ │ ├── Extensions
│ │ │ ├── EnumerableExtensions.cs
│ │ │ ├── ScopeEnumExtensions.cs
│ │ │ ├── EventExtensions.cs
│ │ │ ├── VariableStorageExtensions.cs
│ │ │ ├── IImmutableExtentions.cs
│ │ │ └── CollectionExtensions.cs
│ │ ├── Exceptions
│ │ │ └── ConfigurationParseException.cs
│ │ ├── QueueUtils.cs
│ │ ├── XmlHelpers
│ │ │ ├── GlobalNode.cs
│ │ │ ├── Case.cs
│ │ │ ├── ExprVarNode.cs
│ │ │ ├── AstNode.cs
│ │ │ ├── For.cs
│ │ │ ├── Conditional.cs
│ │ │ ├── AstNodeInfo.cs
│ │ │ ├── BreakContinue.cs
│ │ │ └── ScalarNode.cs
│ │ ├── Preconditions.cs
│ │ └── ImmutableDictionaryComparer.cs
│ ├── Analysis
│ │ ├── CFG
│ │ │ ├── Taint
│ │ │ │ ├── IConstructRepository.cs
│ │ │ │ ├── IBlockAnalyzer.cs
│ │ │ │ ├── SQLITaint.cs
│ │ │ │ ├── MixedTaint.cs
│ │ │ │ ├── XSSTaint.cs
│ │ │ │ ├── IBlockAnalyzerComponent.cs
│ │ │ │ ├── AnalysisStacks.cs
│ │ │ │ ├── TaintHandlerTaintSet.cs
│ │ │ │ ├── ExpressionInfo.cs
│ │ │ │ ├── StringAnalysis.cs
│ │ │ │ └── ISinkAnalyzer.cs
│ │ │ ├── Traversal
│ │ │ │ ├── IWorklist.cs
│ │ │ │ ├── BackwardTraversal.cs
│ │ │ │ ├── ForwardTraversal.cs
│ │ │ │ └── ITraversalTechnique.cs
│ │ │ ├── ICFGAnalysis.cs
│ │ │ ├── FunctionAndMethodAnalyzerFactory.cs
│ │ │ ├── FunctionSummary.cs
│ │ │ ├── QueueWorklist.cs
│ │ │ ├── VariableInfoComposer.cs
│ │ │ ├── PrioritizedCompositeAnalysis.cs
│ │ │ ├── CFGASTNodeVisitor.cs
│ │ │ └── CFGPruner.cs
│ │ ├── ITaintProvider.cs
│ │ ├── IVulnerabilityReporter.cs
│ │ ├── IAnalysisStartingListener.cs
│ │ ├── IVulnerabilityStorage.cs
│ │ ├── CompositeVulneribilityReporter.cs
│ │ ├── PHPDefinitions
│ │ │ └── Source.cs
│ │ └── AST
│ │ │ ├── MetricVisitor.cs
│ │ │ └── IncludeResolver.cs
│ ├── Data
│ │ ├── AnalysisScope.cs
│ │ ├── VariableScope.cs
│ │ ├── CFG
│ │ │ ├── AbstractScope.cs
│ │ │ ├── LoopScope.cs
│ │ │ ├── SwitchScope.cs
│ │ │ ├── EdgeTag.cs
│ │ │ ├── IfScope.cs
│ │ │ ├── CFGBlock.cs
│ │ │ └── ScopeHandler.cs
│ │ ├── VariableTaint.cs
│ │ ├── PHP
│ │ │ ├── ClosureUse.cs
│ │ │ ├── Property.cs
│ │ │ ├── Interface.cs
│ │ │ ├── Class.cs
│ │ │ ├── Closure.cs
│ │ │ ├── FunctionCall.cs
│ │ │ └── Parameter.cs
│ │ ├── Project.cs
│ │ ├── StackSet.cs
│ │ ├── File.cs
│ │ ├── QueueSet.cs
│ │ └── VariableTreeDimension.cs
│ ├── IO
│ │ └── Cmd
│ │ │ ├── ProgressIndicator.cs
│ │ │ ├── BatsFlyingAnimation.cs
│ │ │ ├── ProgressIndicatorFactory.cs
│ │ │ ├── ExecutiveDeskToyAnimation.cs
│ │ │ ├── AnimationIndicator.cs
│ │ │ ├── BarIndicator.cs
│ │ │ └── BikeGuyRidingAnimation.cs
│ ├── App.config
│ ├── CodeFile.cs
│ ├── Parsing
│ │ ├── AstTraversing
│ │ │ ├── IXmlVisitor.cs
│ │ │ ├── IXmlTraverser.cs
│ │ │ ├── XmlTraverseEventArgs.cs
│ │ │ └── ASTPrinter.cs
│ │ ├── ParseResult.cs
│ │ ├── ProjectParser.cs
│ │ ├── XmlHelper.cs
│ │ └── FileParser.cs
│ ├── packages.config
│ ├── config.yml
│ ├── Configuration
│ │ ├── ComponentConfiguration.cs
│ │ ├── GraphConfiguration.cs
│ │ ├── FuncSpecConfiguration.cs
│ │ ├── PHPConfiguration.cs
│ │ └── Config.cs
│ ├── config-template.yml
│ ├── Components
│ │ ├── ComponentContainer.cs
│ │ └── ComponentImporter.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── Arguments.cs
│ └── Provider
│ │ └── Keys.cs
├── PHPAnalysis.PluginInterface
│ ├── Class1.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── PHPAnalysis.PluginInterface.csproj
├── PHPAnalysis.Tests
│ ├── TestSettings.cs
│ ├── packages.config
│ ├── app.config
│ ├── TestUtils
│ │ ├── TypeExtensions.cs
│ │ ├── PHPParseUtils.cs
│ │ ├── TempFileManager.cs
│ │ └── GraphAssertions.cs
│ ├── ConfigDependentTests.cs
│ ├── Data
│ │ └── AstConstantsTests.cs
│ ├── Analysis
│ │ ├── CFG
│ │ │ ├── ExpressionInfoTests.cs
│ │ │ └── CFGTraverserTests.cs
│ │ ├── AST
│ │ │ └── IncludeResolvertTests.cs
│ │ └── ReachDefTests.cs
│ ├── Parsing
│ │ ├── CFGCreator_SkipElements_Tests.cs
│ │ ├── CFGCreator_Case_Tests.cs
│ │ ├── CFGCreator_If_Tests.cs
│ │ └── CFGCreator_ClassTests.cs
│ ├── Utils
│ │ └── XmlHelpers
│ │ │ └── ScalarNodeTests.cs
│ └── Properties
│ │ └── AssemblyInfo.cs
├── PHPAnalysis.sln.DotSettings
├── WordPress.Plugin
│ ├── GotoCounter.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── WpTaintProvider.cs
│ └── WordPress.Plugin.csproj
├── FileWriter.Plugin
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── FileWriter.Plugin.csproj
└── PHPAnalysis.sln
├── LICENSE
├── .gitattributes
└── README.md
/PHPAnalysis-parser/src/parsed.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/config.yml:
--------------------------------------------------------------------------------
1 | #
2 | php_extensions: [.php, .php3, .php4, .php5, .inc]
3 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/FunctionSpecs/JSONSpecifications/Sources.json:
--------------------------------------------------------------------------------
1 | {
2 | "SourceFuncs":[
3 | ]
4 | }
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/test.php:
--------------------------------------------------------------------------------
1 |
4 | {
5 | T Merge(T other);
6 | }
7 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/IConstructRepository.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Analysis.CFG
2 | {
3 | public interface IConstructRepository
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/AnalysisScope.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Data
2 | {
3 | public enum AnalysisScope
4 | {
5 | File = 0,
6 | Function = 1
7 | }
8 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/ProgressIndicator.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.IO.Cmd
2 | {
3 | internal abstract class ProgressIndicator
4 | {
5 | public abstract void Step();
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/ITaintProvider.cs:
--------------------------------------------------------------------------------
1 | using PHPAnalysis.Data;
2 |
3 | namespace PHPAnalysis.Analysis
4 | {
5 | public interface ITaintProvider
6 | {
7 | ImmutableVariableStorage GetTaint();
8 | }
9 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/IDeepCloneable.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Utils
2 | {
3 | public interface IDeepCloneable
4 | {
5 | T DeepClone();
6 | }
7 |
8 | public interface IShallowCloneable
9 | {
10 | T ShallowClone();
11 | }
12 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/VariableScope.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Data
2 | {
3 | public enum VariableScope
4 | {
5 | Unknown = 0,
6 | SuperGlobal = 1,
7 | File = 2,
8 | Function = 3,
9 | Class = 4,
10 | Instance = 5
11 | }
12 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.PluginInterface/Class1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace PHPAnalysis.PluginInterface
8 | {
9 | public class Class1
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/IBlockAnalyzer.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 | using PHPAnalysis.Data;
3 |
4 | namespace PHPAnalysis.Analysis.CFG.Taint
5 | {
6 | public interface IBlockAnalyzer
7 | {
8 | ImmutableVariableStorage Analyze(XmlNode node, ImmutableVariableStorage knownTaint);
9 | }
10 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/CodeFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace PHPAnalysis
8 | {
9 | public sealed class CodeFile
10 | {
11 | public string Filename { get; set; }
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/AbstractScope.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Data.CFG
2 | {
3 | abstract class AbstractScope
4 | {
5 | public CFGBlock EntryBlock { get; set; }
6 | public CFGBlock EndBlock { get; set; }
7 |
8 | protected AbstractScope()
9 | {
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/SQLITaint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.Analysis.CFG
4 | {
5 | [Flags]
6 | public enum SQLITaint
7 | {
8 | None = 0,
9 | SQL_SQ = 1,
10 | SQL_DQ = 2,
11 | SQL_NoQ = 4,
12 | SQL_ALL = SQL_SQ | SQL_DQ | SQL_NoQ
13 | }
14 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/MixedTaint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis
4 | {
5 | [Flags]
6 | public enum MixedStatus
7 | {
8 | XSSSQL_UNSAFE = 0,
9 | XSS_SAFE_ONLY = 1,
10 | SQL_SAFE_ONLY = 2,
11 | XSSSQL_SAFE = XSS_SAFE_ONLY | SQL_SAFE_ONLY
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/TestSettings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace PHPAnalysis.Tests
8 | {
9 | public static class TestSettings
10 | {
11 | public const string ConfigFile = "config.yml";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/XSSTaint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.Analysis.CFG
4 | {
5 | [Flags]
6 | public enum XSSTaint
7 | {
8 | None = 0,
9 | XSS_JS = 1,
10 | XSS_HTML = 2,
11 | XSS_SQ = 4,
12 | XSS_AllQ = 8,
13 | XSS_ALL = XSS_JS | XSS_HTML | XSS_SQ | XSS_AllQ
14 | }
15 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Traversal/IWorklist.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace PHPAnalysis.Analysis.CFG.Traversal
4 | {
5 | public interface IWorklist
6 | {
7 | bool Any();
8 |
9 | void Add(T elem);
10 |
11 | T GetNext();
12 |
13 | bool Contains(T elem, IEqualityComparer comparer = null);
14 | }
15 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Extensions/EnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace PHPAnalysis.Utils
5 | {
6 | public static class EnumerableExtensions
7 | {
8 | public static bool IsEmpty(this IEnumerable collection)
9 | {
10 | return !collection.Any();
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Extensions/ScopeEnumExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Data
2 | {
3 | public static class ScopeEnumExtensions
4 | {
5 | public static VariableScope ToVariableScope(this AnalysisScope analysisScope)
6 | {
7 | return analysisScope == AnalysisScope.File ? VariableScope.File : VariableScope.Function;
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/ICFGAnalysis.cs:
--------------------------------------------------------------------------------
1 | using PHPAnalysis.Data.CFG;
2 | using QuickGraph;
3 |
4 | namespace PHPAnalysis.Analysis.CFG
5 | {
6 | public interface ICFGAnalysis
7 | {
8 | void Initialize(CFGBlock cfgBlock);
9 | bool Analyze(TaggedEdge edge);
10 |
11 | bool Analyze2(CFGBlock block, IBidirectionalGraph> graph);
12 | }
13 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/AstTraversing/IXmlVisitor.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Parsing.AstTraversing
2 | {
3 | public interface IXmlVisitor
4 | {
5 | void TraverseStart(object sender, XmlStartTraverseEventArgs e);
6 | void EnteringNode(object sender, XmlTraverseEventArgs e);
7 | void LeavingNode(object sender, XmlTraverseEventArgs e);
8 | void TraverseEnd(object sender, XmlEndTraverseEventArgs e);
9 | }
10 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/IVulnerabilityReporter.cs:
--------------------------------------------------------------------------------
1 | using PHPAnalysis.Analysis.PHPDefinitions;
2 |
3 | namespace PHPAnalysis.Analysis
4 | {
5 | public interface IVulnerabilityReporter
6 | {
7 | void ReportVulnerability(IVulnerabilityInfo vulnerabilityInfo);
8 | void ReportStoredVulnerability(IVulnerabilityInfo[] vulnerabilityPathInfos);
9 | void RegisterFunctionsHandler(FunctionsHandler functionsHandler);
10 | }
11 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Exceptions/ConfigurationParseException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.Utils.Exceptions
4 | {
5 | public sealed class ConfigurationParseException : Exception
6 | {
7 | public ConfigurationParseException() { }
8 | public ConfigurationParseException(string message) : base(message) { }
9 |
10 | public ConfigurationParseException(string message, Exception inner) : base(message, inner) { }
11 | }
12 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PHPAnalysis-parser/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MAV/PHPAnalyzer",
3 | "description": "description_text",
4 | "minimum-stability": "dev",
5 | "license": "proprietary",
6 | "authors": [
7 | {
8 | "name": "MAV",
9 | "email": "mvej10@student.aau.dk"
10 | }
11 | ],
12 | "require": {
13 | "symfony/console": "~3.0@dev",
14 | "symfony/finder": "~3.0@dev",
15 | "nikic/php-parser": "~1.1@dev",
16 | "symfony/config": "~3.0@dev"
17 | },
18 | "autoload": {
19 | "classmap": ["src/"]
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/VariableTaint.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Immutable;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using PHPAnalysis.Analysis.CFG;
8 | using PHPAnalysis.Utils;
9 |
10 | namespace PHPAnalysis.Data
11 | {
12 | public abstract class VariableTaint : IMergeable
13 | {
14 | public abstract VariableTaint NoTaint { get; }
15 |
16 | public abstract VariableTaint Merge(VariableTaint other);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/QueueUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace PHPAnalysis.Utils
4 | {
5 | public static class QueueUtils
6 | {
7 | public static void EnqueueAll(this Queue queue, IEnumerable newElements)
8 | {
9 | Preconditions.NotNull(queue, "queue");
10 | Preconditions.NotNull(newElements, "newElements");
11 |
12 | foreach (var element in newElements)
13 | {
14 | queue.Enqueue(element);
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/AstTraversing/IXmlTraverser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml;
3 |
4 | namespace PHPAnalysis.Parsing.AstTraversing
5 | {
6 | public interface IXmlTraverser
7 | {
8 | event EventHandler OnTraverseStart;
9 | event EventHandler OnEnteringNode;
10 | event EventHandler OnLeavingNode;
11 | event EventHandler OnTraverseEnd;
12 |
13 | void AddVisitor(IXmlVisitor visitor);
14 |
15 | void Traverse(XmlNode node);
16 | }
17 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/TestUtils/TypeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 |
6 | namespace PHPAnalysis.Tests.Data
7 | {
8 | internal static class TypeExtensions
9 | {
10 | public static IEnumerable GetConstants(this Type type)
11 | {
12 | const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
13 | return type.GetFields(bindingFlags)
14 | .Where(info => info.IsLiteral && !info.IsInitOnly);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/LoopScope.cs:
--------------------------------------------------------------------------------
1 | using PHPAnalysis.Utils;
2 |
3 | namespace PHPAnalysis.Data.CFG
4 | {
5 | internal sealed class LoopScope : AbstractScope
6 | {
7 | public CFGBlock LoopConditionBlock { get; set; }
8 | public CFGBlock LoopBodyStartBlock { get; set; }
9 | public CFGBlock LoopUpdateBlock { get; set; }
10 | public CFGBlock ContinueDestination { get; set; }
11 |
12 | public LoopScope(CFGBlock entryBlock)
13 | {
14 | Preconditions.NotNull(entryBlock, "entryBlock");
15 |
16 | this.EntryBlock = entryBlock;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/ConfigDependentTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using PHPAnalysis.Analysis.PHPDefinitions;
3 | using PHPAnalysis.Configuration;
4 |
5 | namespace PHPAnalysis.Tests.Analysis
6 | {
7 | public abstract class ConfigDependentTests
8 | {
9 | protected Config Config;
10 |
11 | [OneTimeSetUp]
12 | public void FixtureSetUp()
13 | {
14 | Config = Config.ReadConfiguration(TestSettings.ConfigFile);
15 | }
16 |
17 | [OneTimeTearDown]
18 | public void FixtureTearDown()
19 | {
20 | Config = null;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/ClosureUse.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 | using PHPAnalysis.Utils;
3 |
4 | namespace PHPAnalysis.Data.PHP
5 | {
6 | public sealed class ClosureUse
7 | {
8 | public XmlNode AstNode { get; private set; }
9 | public string Name { get; set; }
10 |
11 | public bool ByReference { get; set; }
12 |
13 | public ClosureUse(XmlNode node)
14 | {
15 | Preconditions.NotNull(node, "node");
16 |
17 | this.AstNode = node;
18 | }
19 |
20 | public override string ToString()
21 | {
22 | return string.Format("{0}{1}", ByReference ? "&" : "", Name);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Extensions/EventExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.Utils
4 | {
5 | internal static class EventExtensions
6 | {
7 | public static void RaiseEvent(this EventHandler myEvent, object sender, T e)
8 | where T : EventArgs
9 | {
10 | if (myEvent != null)
11 | {
12 | myEvent(sender, e);
13 | }
14 | }
15 |
16 | public static void RaiseEvent(this EventHandler myEvent, object sender, EventArgs e)
17 | {
18 | if (myEvent != null)
19 | {
20 | myEvent(sender, e);
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/ParseResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 |
8 | namespace PHPAnalysis.Parsing
9 | {
10 | public sealed class ParseResult
11 | {
12 | private readonly Dictionary _parsedFiles = new Dictionary();
13 | public IDictionary ParsedFiles { get { return this._parsedFiles; } }
14 |
15 | private readonly List _filesFailedToParse = new List();
16 | public IList FilesThatFailedToParse { get { return this._filesFailedToParse; } }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/Main.php:
--------------------------------------------------------------------------------
1 | addCommands($commands);
22 |
23 | $application->run();
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/SwitchScope.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Xml;
3 |
4 | namespace PHPAnalysis.Data.CFG
5 | {
6 | internal sealed class SwitchScope : AbstractScope
7 | {
8 | public CFGBlock SwitchStartNode
9 | {
10 | get { return EntryBlock; }
11 | private set { EntryBlock = value; }
12 | }
13 |
14 | public CFGBlock CurrentCondition { get; set; }
15 | public CFGBlock DefaultBlock { get; set; }
16 | public CFGBlock DefaultTrueBlock { get; set; }
17 |
18 | public SwitchScope(CFGBlock switchConditionNode, CFGBlock endNode)
19 | {
20 | EntryBlock = switchConditionNode;
21 | EndBlock = endNode;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/IBlockAnalyzerComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Xml;
5 | using PHPAnalysis.Data;
6 |
7 | namespace PHPAnalysis.Analysis.CFG.Taint
8 | {
9 | public interface IBlockAnalyzerComponent
10 | {
11 | Func FunctionMethodAnalyzerFactory { get; set; }
12 |
13 | ExpressionInfo Analyze(XmlNode node, ExpressionInfo exprInfo, IVariableStorage currentStorage, IVulnerabilityStorage vulnStorage);
14 |
15 | ExpressionInfo AnalyzeFunctionCall(XmlNode node, ExpressionInfo exprInfo, IVariableStorage varStorage, IVulnerabilityStorage vulnStorage, IDictionary argumentInfos, AnalysisStacks analysisStacks);
16 | }
17 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.sln.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
3 | PHP
4 | SQL
5 | XML
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/Project.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using PHPAnalysis.Data.PHP;
3 | using YamlDotNet.Serialization.ObjectFactories;
4 |
5 | namespace PHPAnalysis.Data
6 | {
7 | public sealed class Project
8 | {
9 | public List Files { get; private set; }
10 |
11 | public List Classes { get; private set; }
12 |
13 | public List Functions { get; private set; }
14 |
15 | public List Interfaces { get; private set; }
16 |
17 | public KeyValuePair Constants { get; private set; }
18 |
19 | public Project()
20 | {
21 | Files = new List();
22 | Classes = new List();
23 | Functions = new List();
24 | Interfaces = new List();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/Property.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 |
3 | namespace PHPAnalysis.Data.PHP
4 | {
5 | public sealed class Property
6 | {
7 | public XmlNode AstNode { get; private set; }
8 |
9 | public int StartLine { get; set; }
10 |
11 | public int EndLine { get; set; }
12 |
13 | public AstConstants.VisibilityModifiers VisibilityModifiers { get; set; }
14 |
15 | public string Name { get; set;}
16 |
17 | public bool HasDefault { get; set; }
18 |
19 | public Property(XmlNode astNode)
20 | {
21 | AstNode = astNode;
22 | }
23 |
24 | public override string ToString()
25 | {
26 | return string.Format("{0} {1} {2};",
27 | VisibilityModifiers,
28 | Name,
29 | HasDefault ? " = " : "");
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Traversal/BackwardTraversal.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using PHPAnalysis.Data.CFG;
4 | using QuickGraph;
5 |
6 | namespace PHPAnalysis.Analysis.CFG
7 | {
8 | public sealed class BackwardTraversal : ITraversalTechnique
9 | {
10 | public IEnumerable GetStartBlocks(IBidirectionalGraph> graph)
11 | {
12 | return graph.Vertices.Where(v => v.IsLeaf);
13 | }
14 |
15 | public IEnumerable> NextEdges(IBidirectionalGraph> graph, CFGBlock block)
16 | {
17 | return graph.InEdges(block);
18 | }
19 |
20 | public CFGBlock EdgeTarget(Edge edge)
21 | {
22 | return edge.Source;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/EdgeTag.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using PHPAnalysis.Utils;
7 |
8 | namespace PHPAnalysis.Data.CFG
9 | {
10 | public enum EdgeType
11 | {
12 | Normal = 0,
13 | True,
14 | False
15 | }
16 |
17 | public class EdgeTag : IDeepCloneable
18 | {
19 | public EdgeType EdgeType { get; set;}
20 | public string EdgeData { get; set; }
21 |
22 | public EdgeTag(EdgeType type)
23 | {
24 | EdgeType = type;
25 | }
26 |
27 | public EdgeTag DeepClone()
28 | {
29 | return new EdgeTag(EdgeType) {
30 | EdgeData = this.EdgeData
31 | };
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/IfScope.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.Data.CFG
2 | {
3 | internal sealed class IfScope : AbstractScope
4 | {
5 | public CFGBlock IfConditionNode
6 | {
7 | get { return EntryBlock; }
8 | private set { EntryBlock = value; }
9 | }
10 | public CFGBlock TrueNode { get; set; }
11 | public CFGBlock FalseNode { get; set; }
12 | public CFGBlock ElseifBlock { get; set; }
13 |
14 | public IfScope(CFGBlock ifConditionNode, CFGBlock trueNode = null)
15 | {
16 | EntryBlock = ifConditionNode;
17 | this.TrueNode = trueNode;
18 | }
19 |
20 | public bool IsFalseNodeSet()
21 | {
22 | return FalseNode != null;
23 | }
24 |
25 | public bool IsTrueNodeSet()
26 | {
27 | return TrueNode != null;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/Interface.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Xml;
3 | using PHPAnalysis.Utils;
4 |
5 | namespace PHPAnalysis.Data.PHP
6 | {
7 | public sealed class Interface
8 | {
9 | public XmlNode AstNode { get; set; }
10 |
11 | public IList Methods { get; private set; }
12 |
13 | public string Name { get; set; }
14 |
15 | public int StartLine { get; set; }
16 |
17 | public int EndLine { get; set; }
18 |
19 | public Interface(XmlNode node)
20 | {
21 | Preconditions.NotNull(node, "node");
22 |
23 | this.AstNode = node;
24 | this.Methods = new List();
25 | }
26 |
27 | public override string ToString()
28 | {
29 | return string.Format("Name: {0}, StartLine: {1}, EndLine: {2}", Name, StartLine, EndLine);
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/GlobalNode.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Xml;
3 | using PHPAnalysis.Data;
4 |
5 | namespace PHPAnalysis.Utils.XmlHelpers
6 | {
7 | public static class GlobalNode
8 | {
9 | public static IEnumerable GetVariables(XmlNode node)
10 | {
11 | Preconditions.NotNull(node, "node");
12 | Preconditions.IsTrue(node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Stmt_Global,
13 | "Node has to be a global statement. It was: " + node.Name, "node");
14 |
15 | var variables = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Vars)
16 | .GetSubNode(AstConstants.Scalar + ":" + AstConstants.Scalars.Array)
17 | .GetSubnodes(AstConstants.Node + ":" + AstConstants.Nodes.Expr_Variable);
18 | return variables;
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/FunctionAndMethodAnalyzerFactory.cs:
--------------------------------------------------------------------------------
1 | using PHPAnalysis.Analysis.AST;
2 | using PHPAnalysis.Analysis.CFG.Taint;
3 | using PHPAnalysis.Data;
4 | using PHPAnalysis.Analysis.PHPDefinitions;
5 |
6 | namespace PHPAnalysis.Analysis.CFG
7 | {
8 | public sealed class FunctionAndMethodAnalyzerFactory
9 | {
10 | public bool UseSummaries { get; set; }
11 |
12 | public FunctionAndMethodAnalyzer Create(ImmutableVariableStorage variableStorage, IIncludeResolver incResolver,
13 | AnalysisStacks stacks, CustomFunctionHandler customFuncHandler,
14 | IVulnerabilityStorage vulnerabilityStorage, FunctionsHandler fh)
15 | {
16 | return new FunctionAndMethodAnalyzer(variableStorage, incResolver, stacks, customFuncHandler, vulnerabilityStorage, fh)
17 | {
18 | UseSummaries = this.UseSummaries
19 | };
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Traversal/ForwardTraversal.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using PHPAnalysis.Data;
4 | using PHPAnalysis.Data.CFG;
5 | using PHPAnalysis.Utils;
6 | using QuickGraph;
7 | using QuickGraph.Algorithms;
8 |
9 | namespace PHPAnalysis.Analysis.CFG
10 | {
11 | public sealed class ForwardTraversal : ITraversalTechnique
12 | {
13 | public IEnumerable GetStartBlocks(IBidirectionalGraph> graph)
14 | {
15 | return graph.Roots().Where(r => r.IsRoot);
16 | }
17 |
18 | public IEnumerable> NextEdges(IBidirectionalGraph> graph, CFGBlock block)
19 | {
20 | return graph.OutEdges(block);
21 | }
22 |
23 | public CFGBlock EdgeTarget(Edge edge)
24 | {
25 | return edge.Target;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/commands/GreetCommand.php:
--------------------------------------------------------------------------------
1 | setName('greet')
15 | ->setDescription('Greetings')
16 | ->addArgument('name', InputArgument::OPTIONAL, 'Who do you want to greet?');
17 | }
18 |
19 | protected function execute(InputInterface $input, OutputInterface $output) {
20 | $name = $input->getArgument('name');
21 |
22 | $text = 'Hello';
23 | if ($name) {
24 | $text = $text . ' ' . $name;
25 | }
26 |
27 | $output->writeln($text);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/BatsFlyingAnimation.cs:
--------------------------------------------------------------------------------
1 | namespace PHPAnalysis.IO.Cmd
2 | {
3 | internal class BatsFlyingAnimation : AnimationIndicator
4 | {
5 | protected override string[] Steps
6 | {
7 | get
8 | {
9 | return new[] {
10 | @" /^v^\
11 | /^v^\ /^v^\
12 | /^v^\
13 |
14 | /^v^\ ",
15 | @" \^v^/
16 | \^v^/ \^v^/
17 | \^v^/
18 |
19 | \^v^/ "
20 | };
21 |
22 | }
23 | }
24 |
25 | protected override string FinalStep
26 | {
27 | get { return Steps[1]; }
28 | }
29 |
30 | public BatsFlyingAnimation(int max = 100) : base(max)
31 | {
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/FunctionSummary.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using PHPAnalysis.Analysis.CFG.Taint;
3 | using PHPAnalysis.Utils;
4 |
5 | namespace PHPAnalysis.Analysis.CFG
6 | {
7 | public sealed class FunctionSummary
8 | {
9 | public string FunctionName { get; private set; }
10 | public ICollection ArgInfos { get; private set; }
11 |
12 | public ExpressionInfo ReturnValue { get; set; }
13 |
14 | public FunctionSummary(string functionName)
15 | {
16 | Preconditions.NotNull(functionName, "functionName");
17 |
18 | this.FunctionName = functionName;
19 | this.ArgInfos = new List();
20 | //this.GlobalElements = new Dictionary();
21 | //this.SuperglobalElements = new Dictionary();
22 | //this.ClassElements = new Dictionary();
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Data/AstConstantsTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Reflection;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using NUnit.Framework;
8 | using PHPAnalysis.Data;
9 |
10 | namespace PHPAnalysis.Tests.Data
11 | {
12 | [TestFixture]
13 | public class AstConstantsTests
14 | {
15 | [TestCase(typeof(AstConstants.Attributes))]
16 | [TestCase(typeof(AstConstants.Subnodes))]
17 | [TestCase(typeof(AstConstants.Scalars))]
18 | [TestCase(typeof(AstConstants.Nodes))]
19 | public static void AttributeConstantsHaveSameNameAsValue_CaseIgnored(Type type)
20 | {
21 | IEnumerable constants = type.GetConstants();
22 |
23 | foreach (var fieldInfo in constants)
24 | {
25 | Assert.That(fieldInfo.Name, Is.EqualTo(fieldInfo.GetValue(null)).IgnoreCase);
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/Case.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using System.Xml.Linq;
8 | using PHPAnalysis.Data;
9 |
10 | namespace PHPAnalysis.Utils.XmlHelpers
11 | {
12 | public sealed class Case
13 | {
14 | public static bool IsDefaultCase(XmlNode node)
15 | {
16 | Preconditions.NotNull(node, "node");
17 | Preconditions.IsTrue(node.LocalName == AstConstants.Nodes.Stmt_Case,
18 | "Expected a case node, but received a " + node.Name);
19 |
20 | XDocument xNode = XDocument.Parse(node.OuterXml);
21 | XNamespace nsa = AstConstants.Namespaces.SubNode;
22 |
23 | var defaultLine = xNode.Descendants(nsa + AstConstants.Subnodes.Cond)
24 | .First().Value;
25 |
26 | return defaultLine == "";
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/PHPAnalysis/WordPress.Plugin/GotoCounter.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using PHPAnalysis.Data;
3 | using PHPAnalysis.Parsing.AstTraversing;
4 |
5 | namespace WordPress.Plugin
6 | {
7 | [Export(typeof(IXmlVisitor))]
8 | public sealed class GotoCounter : IXmlVisitor
9 | {
10 | private int _gotos = 0;
11 | public void TraverseStart(object sender, XmlStartTraverseEventArgs e)
12 | {
13 | }
14 |
15 | public void EnteringNode(object sender, XmlTraverseEventArgs e)
16 | {
17 | if (e.Node.LocalName == AstConstants.Nodes.Stmt_Goto)
18 | {
19 | _gotos++;
20 | }
21 | }
22 |
23 | public void LeavingNode(object sender, XmlTraverseEventArgs e)
24 | {
25 | }
26 |
27 | public void TraverseEnd(object sender, XmlEndTraverseEventArgs e)
28 | {
29 | //System.IO.File.AppendAllText("john.txt", "GOTOs: " + _gotos);
30 |
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/YamlConfigLoader.php:
--------------------------------------------------------------------------------
1 | s.Key, s => s.Value.AssignmentClone()),
16 | immutableStorage.Globals.ToDictionary(s => s.Key, s => s.Value.AssignmentClone()),
17 | immutableStorage.Locals.ToDictionary(s => s.Key, s => s.Value.AssignmentClone()),
18 | immutableStorage.ClassVariables.ToDictionary(s => s.Key, s => s.Value.AssignmentClone()),
19 | immutableStorage.LocalAccessibleGlobals.ToDictionary(s => s.Key, s => s.Value.AssignmentClone()));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Analysis/CFG/ExpressionInfoTests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using NUnit.Framework;
3 | using PHPAnalysis.Analysis.CFG;
4 | using PHPAnalysis.Analysis.CFG.Taint;
5 |
6 | namespace PHPAnalysis.Tests.Analysis.CFG
7 | {
8 | [TestFixture]
9 | class ExpressionInfoTests
10 | {
11 | [Test]
12 | public void ExpressionInfo_Merge()
13 | {
14 | var sqliTaint = new SQLITaintSet(SQLITaint.SQL_ALL);
15 | var xsstaint = new XSSTaintSet(XSSTaint.XSS_ALL);
16 | var ts1 = new TaintSets(sqliTaint, xsstaint);
17 | var exprInfo1 = new ExpressionInfo { ExpressionTaint = ts1 };
18 | var exprInfo2 = new ExpressionInfo();
19 |
20 | var exprInfo = exprInfo2.Merge(exprInfo1);
21 |
22 | Assert.AreEqual(sqliTaint, exprInfo.ExpressionTaint.SqliTaint.Single(), "SQL Taint was not the expected");
23 | Assert.AreEqual(xsstaint, exprInfo.ExpressionTaint.XssTaint.Single(), "XSS Taint was not the expected");
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/config.yml:
--------------------------------------------------------------------------------
1 | php-settings:
2 | # Path to PHP executable
3 | PHPPath : C:/PHP/php.exe
4 |
5 | # PHP file extensions
6 | PHPExts :
7 | - .php
8 | - .php3
9 | - .php4
10 | - .php5
11 | - .phtml
12 | - .inc
13 |
14 | # Path to PHP parse project (Main.php file)
15 | PHPParsePath :
16 |
17 | graph-settings:
18 | # Path to the graphviz dot convert tool
19 | GraphvizPath : C:\Graphviz-2.38\dot.exe
20 |
21 | # Arguments to the graphviz
22 | GraphvizArguments : -Tpng -O
23 |
24 | component-settings:
25 | # Indicates whether external components should be used
26 | IncludeComponents : True
27 |
28 | # Path to external components.
29 | ComponentFolder : .\Components\
30 |
31 | func-spec-settings:
32 | # Path array to function specifications
33 | PHPSpecs:
34 | - ???\JsonSpecifications
35 | - ???\StoredSqlProviders
36 |
37 | # Path to extensions specification, can be excluded if not needed
38 | ExtensionSpecs:
39 | - ???\WPSpecifications
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/AnalysisStacks.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using PHPAnalysis.Data;
3 | using PHPAnalysis.Utils;
4 |
5 | namespace PHPAnalysis.Analysis.CFG.Taint
6 | {
7 | public sealed class AnalysisStacks
8 | {
9 | ///
10 | /// This stack should always contain the file currently being analyzed.
11 | ///
12 | public Stack IncludeStack { get; private set; }
13 | public Stack CallStack { get; private set; }
14 |
15 | private AnalysisStacks()
16 | {
17 | IncludeStack = new Stack();
18 | CallStack = new Stack();
19 | }
20 |
21 | public AnalysisStacks(File initialFile) : this()
22 | {
23 | Preconditions.NotNull(initialFile, "initialFile");
24 |
25 | IncludeStack.Push(initialFile);
26 | }
27 |
28 | public AnalysisStacks(Stack initialIncludeStack) : this()
29 | {
30 | IncludeStack = initialIncludeStack;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/ProgressIndicatorFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.IO.Cmd
4 | {
5 | internal static class ProgressIndicatorFactory
6 | {
7 | public static ProgressIndicator CreateProgressIndicator(int maxValue)
8 | {
9 | Random rand = new Random();
10 | int r = rand.Next();
11 | ProgressIndicator progrssIndicator;
12 |
13 | switch (r % 4)
14 | {
15 | case 0:
16 | progrssIndicator = new BatsFlyingAnimation(maxValue);
17 | break;
18 | case 1:
19 | progrssIndicator = new BikeGuyRidingAnimation(maxValue);
20 | break;
21 | case 2:
22 | progrssIndicator = new ExecutiveDeskToyAnimation(maxValue);
23 | break;
24 | default:
25 | progrssIndicator = new BarIndicator(maxValue);
26 | break;
27 | }
28 | return progrssIndicator;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/QueueWorklist.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using PHPAnalysis.Analysis.CFG.Traversal;
4 | using PHPAnalysis.Data;
5 | using PHPAnalysis.Data.CFG;
6 |
7 | namespace PHPAnalysis.Analysis.CFG
8 | {
9 | public sealed class QueueWorklist : IWorklist
10 | {
11 | private readonly QueueSet queue = new QueueSet();
12 | private readonly StackSet queue1 = new StackSet();
13 |
14 | public bool Any()
15 | {
16 | return queue.Any();
17 | }
18 |
19 | public void Add(CFGBlock elem)
20 | {
21 | queue.Enqueue(elem);
22 | }
23 |
24 | public CFGBlock GetNext()
25 | {
26 | return queue.Dequeue();
27 | }
28 |
29 | public bool Contains(CFGBlock elem, IEqualityComparer comparer = null)
30 | {
31 | comparer = comparer ?? EqualityComparer.Default;
32 | return queue.Contains(elem, comparer);
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/VariableInfoComposer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using PHPAnalysis.Data;
8 | using PHPAnalysis.Data.CFG;
9 | using PHPAnalysis.Utils.XmlHelpers;
10 |
11 | namespace PHPAnalysis.Analysis.CFG
12 | {
13 | public static class VariableInfoComposer
14 | {
15 | public static readonly Dictionary VarInfoStorage = new Dictionary();
16 |
17 | public static ValueInfo AnalyzeBlock(ValueInfo block)
18 | {
19 | if (block.Block.AstEntryNode == null)
20 | return null;
21 |
22 | if (VarInfoStorage.ContainsKey(block.Block))
23 | {
24 | return VarInfoStorage[block.Block];
25 | }
26 |
27 | // type, value, arraytree
28 | var astNode = block.Block.AstEntryNode;
29 |
30 | VarInfoStorage.Add(block.Block, block);
31 | return block;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/AstTraversing/XmlTraverseEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml;
3 |
4 | namespace PHPAnalysis.Parsing.AstTraversing
5 | {
6 | ///
7 | /// Event args used when visiting an individual node in the Xml tree.
8 | ///
9 | public class XmlTraverseEventArgs : EventArgs
10 | {
11 | public XmlNode Node { get; private set; }
12 | public XmlTraverseEventArgs(XmlNode node)
13 | {
14 | this.Node = node;
15 | }
16 | }
17 |
18 | ///
19 | /// Event args used right before the Xml traversal starts.
20 | ///
21 | public class XmlStartTraverseEventArgs : EventArgs
22 | {
23 | new public static readonly XmlStartTraverseEventArgs Empty = new XmlStartTraverseEventArgs();
24 | }
25 |
26 | ///
27 | /// Event args used after the Xml traversal is finished.
28 | ///
29 | public class XmlEndTraverseEventArgs : EventArgs
30 | {
31 | new public static readonly XmlEndTraverseEventArgs Empty = new XmlEndTraverseEventArgs();
32 |
33 | }
34 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Preconditions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 |
4 | namespace PHPAnalysis.Utils
5 | {
6 | internal static class Preconditions
7 | {
8 | [DebuggerHidden]
9 | public static T NotNull(T parameter, string parameterName) where T : class
10 | {
11 | if (parameter == null)
12 | {
13 | throw new ArgumentNullException(parameterName);
14 | }
15 | return parameter;
16 | }
17 |
18 | [DebuggerHidden]
19 | public static void IsTrue(bool condition, string message = "", string parameterName = "")
20 | {
21 | if ( !condition )
22 | {
23 | throw new ArgumentException(message, parameterName);
24 | }
25 | }
26 |
27 | [DebuggerHidden]
28 | public static void IsFalse(bool condition, string message = "", string parameterName = "")
29 | {
30 | if (condition)
31 | {
32 | throw new ArgumentException(message, parameterName);
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Chikila
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/TestUtils/PHPParseUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 | using PHPAnalysis.Parsing;
3 | using PHPAnalysis.Parsing.AstTraversing;
4 |
5 | namespace PHPAnalysis.Tests.TestUtils
6 | {
7 | public static class PHPParseUtils
8 | {
9 | public static XmlNode ParsePHPCode(string phpCode, string phpParser)
10 | {
11 | var fileParser = new FileParser(phpParser);
12 |
13 | using (var fileManager = new TempFileManager())
14 | {
15 | string file = fileManager.WriteContent(phpCode);
16 | var xml = fileParser.ParsePHPFile(file);
17 | return xml;
18 | }
19 | }
20 |
21 |
22 | public static T ParseAndIterate(string phpCode, string phpParser) where T : IXmlVisitor, new()
23 | {
24 | XmlNode ast = ParsePHPCode(phpCode, phpParser);
25 | var traverser = new XmlTraverser();
26 | var visitor = new T();
27 | traverser.AddVisitor(visitor);
28 | traverser.Traverse(ast.FirstChild.NextSibling);
29 | return visitor;
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Traversal/ITraversalTechnique.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using PHPAnalysis.Data.CFG;
3 | using QuickGraph;
4 |
5 | namespace PHPAnalysis.Analysis.CFG
6 | {
7 | public interface ITraversalTechnique
8 | {
9 | ///
10 | /// Returns the blocks to be used as initial blocks in the traversal.
11 | /// In a normal forward analysis, this should return the root block.
12 | ///
13 | IEnumerable GetStartBlocks(IBidirectionalGraph> graph);
14 | ///
15 | /// Return the next edges to consider in the analysis.
16 | ///
17 | IEnumerable> NextEdges(IBidirectionalGraph> graph, CFGBlock block);
18 | ///
19 | /// Returns the block of interest when looking at a specific edge.
20 | /// E.g. in a forward analysis this would be the edge target. In a backwards analysis it would be the edge source.
21 | ///
22 | CFGBlock EdgeTarget(Edge edge);
23 | }
24 | }
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/commands/ScanCommand.php:
--------------------------------------------------------------------------------
1 | setName('scan')
16 | ->setDescription('Start PHP vulnerability scanning')
17 | ->addArgument('target', InputArgument::REQUIRED, 'Target file/directory of scan.');
18 | }
19 |
20 | protected function execute(InputInterface $input, OutputInterface $output) {
21 | $target = $input->getArgument('target');
22 |
23 | if (is_dir($target)) {
24 | $output->writeln("Starting directory scan of " . $target);
25 | } else if (is_file($target)) {
26 | $output->writeln("Starting file scan of " . $target);
27 | } else {
28 | $output->writeln("Target does not seem to be a valid file or directory..");
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/CFGBlock.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Runtime.Remoting;
3 | using System.Xml;
4 |
5 | namespace PHPAnalysis.Data.CFG
6 | {
7 | public sealed class CFGBlock
8 | {
9 | public bool IsRoot { get; set; }
10 | public bool IsLeaf { get; set; }
11 | public XmlNode AstEntryNode { get; set; }
12 | public bool IsSpecialBlock { get; private set; }
13 | ///
14 | /// Specify whether this node breaks out of the existing scope before the execution
15 | /// reaches the end of the block. E.g. by reaching a break or continue statement.
16 | ///
17 | public bool BreaksOutOfScope { get; set; }
18 |
19 | public CFGBlock(bool isSpecial = false)
20 | {
21 | this.IsSpecialBlock = isSpecial;
22 | }
23 |
24 | public bool CanBeOverridden
25 | {
26 | get { return !IsSpecialBlock && AstEntryNode == null; }
27 | }
28 |
29 | public override string ToString()
30 | {
31 | return AstEntryNode == null ? base.ToString() : AstEntryNode.LocalName;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/IAnalysisStartingListener.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using PHPAnalysis.Components;
3 | using PHPAnalysis.Configuration;
4 |
5 | namespace PHPAnalysis.Analysis
6 | {
7 | public interface IAnalysisStartingListener
8 | {
9 | void AnalysisStarting(object o, AnalysisStartingEventArgs e);
10 | }
11 |
12 | public interface IAnalysisEndedListener
13 | {
14 | void AnalysisEnding(object o, AnalysisEndedEventArgs e);
15 | }
16 |
17 | public sealed class AnalysisEndedEventArgs : EventArgs
18 | {
19 | public TimeSpan TimeElapsed { get; private set; }
20 |
21 | public AnalysisEndedEventArgs(TimeSpan timeElapsed)
22 | {
23 | this.TimeElapsed = timeElapsed;
24 | }
25 | }
26 |
27 | public sealed class AnalysisStartingEventArgs : EventArgs
28 | {
29 | public Config Configuration { get; private set; }
30 | public Arguments Arguments { get; private set; }
31 |
32 | public AnalysisStartingEventArgs(Config config, Arguments arguments)
33 | {
34 | this.Configuration = config;
35 | this.Arguments = arguments;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/TestUtils/TempFileManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace PHPAnalysis.Tests
5 | {
6 | public sealed class TempFileManager : IDisposable
7 | {
8 | private readonly string _folder = Path.GetTempPath();
9 | private readonly string _file = Path.GetTempFileName();
10 |
11 | private string FilePath => Path.Combine(_folder, _file);
12 |
13 | private bool _createdFolder = false;
14 |
15 | public string WriteContent(string content)
16 | {
17 | if (!Directory.Exists(_folder))
18 | {
19 | Directory.CreateDirectory(_folder);
20 | _createdFolder = true;
21 | }
22 |
23 | File.WriteAllText(FilePath, content);
24 | return FilePath;
25 | }
26 |
27 | public void Dispose()
28 | {
29 | if (!File.Exists(FilePath)) { return; }
30 |
31 | if (_createdFolder)
32 | {
33 | Directory.Delete(_folder, true);
34 | }
35 | else
36 | {
37 | File.Delete(FilePath);
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/TestUtils/GraphAssertions.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using PHPAnalysis.Data;
3 | using QuickGraph;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using PHPAnalysis.Data.CFG;
10 |
11 | namespace PHPAnalysis.Tests.TestUtils
12 | {
13 | public static class GraphAssertions
14 | {
15 | public static void AssertOutEdges(this BidirectionalGraph> graph, CFGBlock block, int expectedOutEdges, string message = "")
16 | {
17 | IEnumerable> edges;
18 | graph.TryGetOutEdges(block, out edges);
19 |
20 | Assert.AreEqual(expectedOutEdges, edges.Count(), message);
21 | }
22 | public static void AssertInEdges(this BidirectionalGraph> graph, CFGBlock block, int expectedInEdges, string message = "")
23 | {
24 | IEnumerable> edges;
25 | graph.TryGetInEdges(block, out edges);
26 |
27 | Assert.AreEqual(expectedInEdges, edges.Count(), message);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/ExprVarNode.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 | using PHPAnalysis.Data;
3 |
4 | namespace PHPAnalysis.Utils.XmlHelpers
5 | {
6 | public static class ExprVarNode
7 | {
8 | ///
9 | /// Tries to get the variables name. This will only work if the variable name is static.
10 | /// $var : will be 'var'
11 | /// $$var : will fail.
12 | ///
13 | public static bool TryGetVariableName(XmlNode node, out string varName)
14 | {
15 | Preconditions.NotNull(node, "node");
16 | Preconditions.IsTrue(node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Expr_Variable,
17 | "Node has to be an Expression Variable. It was: " + node.Name, "node");
18 |
19 | var nameNode = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Name);
20 |
21 | if (nameNode.TryGetSubNode(AstConstants.Scalar + ":" + AstConstants.Scalars.String, out nameNode))
22 | {
23 | varName = nameNode.InnerText;
24 | return true;
25 | }
26 | varName = null;
27 | return false;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Configuration/ComponentConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using PHPAnalysis.Annotations;
7 | using PHPAnalysis.Utils;
8 |
9 | namespace PHPAnalysis.Configuration
10 | {
11 | public sealed class ComponentConfiguration
12 | {
13 | public string ComponentPath { get; private set; }
14 | public bool IncludeComponents { get; private set; }
15 |
16 | public ComponentConfiguration(string componentPath, bool includeComponents)
17 | {
18 | Preconditions.NotNull(componentPath, "componentPath");
19 |
20 | this.ComponentPath = componentPath;
21 | this.IncludeComponents = includeComponents;
22 | }
23 |
24 | public override string ToString()
25 | {
26 | var sb = new StringBuilder();
27 | sb.AppendLine("Path: " + this.ComponentPath);
28 | return sb.ToString();
29 | }
30 | }
31 |
32 | [UsedImplicitly]
33 | internal sealed class ComponentConfigurationMutable
34 | {
35 | public string ComponentFolder { get; set; }
36 | public bool IncludeComponents { get; set; }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/AstNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using System.Xml.Linq;
8 | using PHPAnalysis.Data;
9 |
10 | namespace PHPAnalysis.Utils.XmlHelpers
11 | {
12 | public static class AstNode
13 | {
14 | public static int GetStartLine(XmlNode node)
15 | {
16 | Preconditions.NotNull(node, "node");
17 | Preconditions.IsTrue(node.Prefix == AstConstants.Node, "Expected node but received a " + node.Name);
18 |
19 | return GetLine(node, AstConstants.Attributes.StartLine);
20 | }
21 |
22 | public static int GetEndLine(XmlNode node)
23 | {
24 | Preconditions.NotNull(node, "node");
25 | Preconditions.IsTrue(node.Prefix == AstConstants.Node, "Expected node but received a " + node.Name);
26 |
27 | return GetLine(node, AstConstants.Attributes.EndLine);
28 | }
29 |
30 | private static int GetLine(XmlNode node, string lineType)
31 | {
32 | var line = node.GetSubNode(AstConstants.Attribute + ":" + lineType);
33 | return Convert.ToInt32(line.InnerText);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/Class.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Xml;
3 | using PHPAnalysis.Utils;
4 |
5 | namespace PHPAnalysis.Data.PHP
6 | {
7 | public sealed class Class
8 | {
9 | public XmlNode AstNode { get; set; }
10 | public string Name { get; set; }
11 | public string File { get; set; }
12 |
13 | public IList Properties { get; private set; }
14 | public IList Methods { get; private set; }
15 |
16 | public int StartLine { get; set; }
17 | public int EndLine { get; set; }
18 |
19 | public AstConstants.VisibilityModifiers VisibilityModifiers { get; set; }
20 |
21 | public bool IsFinal
22 | {
23 | get { return (VisibilityModifiers & AstConstants.VisibilityModifiers.Final) != 0; }
24 | }
25 |
26 | public Class(XmlNode node)
27 | {
28 | Preconditions.NotNull(node, "node");
29 |
30 | this.AstNode = node;
31 | this.Methods = new List();
32 | this.Properties = new List();
33 | }
34 |
35 | public override string ToString()
36 | {
37 | return string.Format("Name: {0}, StartLine: {1}, EndLine: {2}", Name, StartLine, EndLine);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/config-template.yml:
--------------------------------------------------------------------------------
1 | php-settings:
2 | # Path to PHP executable
3 | PHPPath : C:/PHP/php.exe
4 |
5 | # PHP file extensions
6 | PHPExts :
7 | - .php
8 | - .php3
9 | - .php4
10 | - .php5
11 | - .phtml
12 | - .inc
13 |
14 | # Path to PHP parse project (Main.php file)
15 | PHPParsePath : D:\Dokumenter\Skolesager\10.-Semester\GIT\PHPAnalysis\PHPAnalysis-parser\src\Main.php
16 |
17 | graph-settings:
18 | # Path to the graphviz dot convert tool
19 | GraphvizPath : C:\Program Files (x86)\Graphviz-2.38\dot.exe
20 |
21 | # Arguments to the graphviz
22 | GraphvizArguments : -Tpng -O
23 |
24 | component-settings:
25 | # Indicates whether external components should be used
26 | IncludeComponents : True
27 |
28 | # Path to external components.
29 | ComponentFolder : .\Components\
30 |
31 | func-spec-settings:
32 | #Path array to function specifications
33 | PHPSpecs:
34 | - "C:/mmk-php-vuln-scanner/PHPAnalysis/PHPAnalysis/FunctionSpecs/JSONSpecifications"
35 | - "C:/mmk-php-vuln-scanner/PHPAnalysis/PHPAnalysis/FunctionSpecs/StoredSQLProviders"
36 |
37 | #Path to extensions specification, can be excluded if not needed
38 | ExtensionSpecs:
39 | - "C:/mmk-php-vuln-scanner/PHPAnalysis/PHPAnalysis/FunctionSpecs/WPSpecifications"
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Parsing/CFGCreator_SkipElements_Tests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using NUnit.Framework;
3 | using PHPAnalysis.Analysis;
4 | using PHPAnalysis.Data.CFG;
5 | using PHPAnalysis.Parsing;
6 | using PHPAnalysis.Tests.TestUtils;
7 | using PHPAnalysis.Utils;
8 |
9 | namespace PHPAnalysis.Tests.Analysis
10 | {
11 | [TestFixture]
12 | public class CFGCreator_SkipElements_Tests : ConfigDependentTests
13 | {
14 | [TestCase(@"(php, Config.PHPSettings.PHPParserPath);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Components/ComponentContainer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using PHPAnalysis.Analysis;
3 | using PHPAnalysis.Analysis.CFG.Taint;
4 | using PHPAnalysis.Parsing.AstTraversing;
5 |
6 | namespace PHPAnalysis.Components
7 | {
8 | internal sealed class ComponentContainer
9 | {
10 | public ICollection AstVisitors { get; private set; }
11 |
12 | public ICollection BlockAnalyzers { get; private set; }
13 |
14 | public ICollection VulnerabilityReporters { get; private set; }
15 |
16 | public ICollection TaintProviders { get; private set; }
17 |
18 | public ICollection AnalysisStartingListeners { get; private set; }
19 |
20 | public ICollection AnalysisEndedListeners { get; private set; }
21 |
22 | public ComponentContainer()
23 | {
24 | this.AstVisitors = new List();
25 | this.BlockAnalyzers = new List();
26 | this.VulnerabilityReporters = new List();
27 | this.TaintProviders = new List();
28 | this.AnalysisStartingListeners = new List();
29 | this.AnalysisEndedListeners = new List();
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Configuration/GraphConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using PHPAnalysis.Utils;
3 | using System.Text;
4 | using PHPAnalysis.Annotations;
5 |
6 | namespace PHPAnalysis
7 | {
8 | public sealed class GraphConfiguration
9 | {
10 | public string GraphvizPath { get; private set; }
11 | public string GraphvizArguments { get; private set; }
12 |
13 | public GraphConfiguration(string graphvizPath, string graphvizArguments)
14 | {
15 | Preconditions.NotNull(graphvizPath, "graphvizPath");
16 | Preconditions.NotNull(graphvizArguments, "graphvizArguments");
17 |
18 | this.GraphvizPath = graphvizPath;
19 | this.GraphvizArguments = graphvizArguments;
20 | }
21 |
22 | public override string ToString()
23 | {
24 | var stringBuilder = new StringBuilder();
25 | stringBuilder.AppendLine("[Graph configuration:");
26 | stringBuilder.AppendLine(" Graphviz path: " + GraphvizPath);
27 | stringBuilder.AppendLine(" Graphviz arguments: " + GraphvizArguments);
28 | stringBuilder.Append("]");
29 | return stringBuilder.ToString();
30 | }
31 | }
32 |
33 | [UsedImplicitly]
34 | internal sealed class GraphConfigurationMutable
35 | {
36 | public string GraphvizPath { get; set; }
37 | public string GraphvizArguments { get; set; }
38 | }
39 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/ImmutableDictionaryComparer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Immutable;
4 | using System.Linq;
5 |
6 | namespace PHPAnalysis.Utils
7 | {
8 | public sealed class ImmutableDictionaryComparer : IEqualityComparer>
9 | {
10 | private readonly IEqualityComparer valueComparer;
11 | public ImmutableDictionaryComparer(IEqualityComparer valueComparer = null)
12 | {
13 | this.valueComparer = valueComparer ?? EqualityComparer.Default;
14 | }
15 | public bool Equals(IImmutableDictionary first, IImmutableDictionary second)
16 | {
17 | if (first.Count != second.Count) { return false; }
18 | if (first.Keys.Except(second.Keys).Any()) { return false; }
19 | if (second.Keys.Except(first.Keys).Any()) { return false; }
20 |
21 | foreach (var pair in first)
22 | {
23 | if (!valueComparer.Equals(pair.Value, second[pair.Key]))
24 | {
25 | return false;
26 | }
27 | }
28 | return true;
29 | }
30 |
31 | public int GetHashCode(IImmutableDictionary obj)
32 | {
33 | // Required by interface
34 | throw new NotImplementedException();
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Extensions/IImmutableExtentions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.Immutable;
3 | using System.Linq;
4 |
5 | namespace PHPAnalysis.Utils
6 | {
7 | public static class IImmutableExtentions
8 | {
9 | public static IImmutableSet AddRange(this IImmutableSet collection, IEnumerable toAdd)
10 | {
11 | Preconditions.NotNull(toAdd, "toAdd");
12 |
13 | return toAdd.Aggregate(collection, (current, element) => current.Add(element));
14 | }
15 |
16 | public static System.Collections.Immutable.IImmutableDictionary Merge(this System.Collections.Immutable.IImmutableDictionary first, System.Collections.Immutable.IImmutableDictionary second)
17 | where T2 : IMergeable
18 | {
19 | var newDict = first.ToDictionary(x => x.Key, x => x.Value);
20 | foreach (var other in second)
21 | {
22 | T2 set;
23 | if (newDict.TryGetValue(other.Key, out set))
24 | {
25 | set = set.Merge(other.Value);
26 | newDict[other.Key] = set;
27 | }
28 | else
29 | {
30 | newDict.Add(other.Key, other.Value);
31 | }
32 | }
33 | return ImmutableDictionary.Empty.AddRange(newDict);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/For.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using PHPAnalysis.Data;
8 | using QuickGraph.Algorithms.ShortestPath;
9 |
10 | namespace PHPAnalysis.Utils.XmlHelpers
11 | {
12 | internal static class ForLoop
13 | {
14 | public static XmlNode GetInitNode(XmlNode node)
15 | {
16 | const string initNodeName = AstConstants.Subnode + ":" + AstConstants.Subnodes.Init;
17 | return GetSubNode(node, initNodeName);
18 | }
19 |
20 | public static XmlNode GetConditionNode(XmlNode node)
21 | {
22 | const string conditionNodeName = AstConstants.Subnode + ":" + AstConstants.Subnodes.Cond;
23 | return GetSubNode(node, conditionNodeName);
24 | }
25 |
26 | public static XmlNode GetLoopNode(XmlNode node)
27 | {
28 | const string initNodeName = AstConstants.Subnode + ":" + AstConstants.Subnodes.Loop;
29 | return GetSubNode(node, initNodeName);
30 | }
31 |
32 | private static XmlNode GetSubNode(XmlNode node, string nodeName)
33 | {
34 | Preconditions.NotNull(node, "node");
35 | Preconditions.IsTrue(node.LocalName == AstConstants.Nodes.Stmt_For, "Expected for-node but got " + node.Name);
36 |
37 | return node.GetSubNode(nodeName);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/AstTraversing/ASTPrinter.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Xml;
3 | using PHPAnalysis.Utils;
4 |
5 | namespace PHPAnalysis.Parsing.AstTraversing
6 | {
7 | public sealed class ASTPrinter : IXmlVisitor
8 | {
9 | private readonly TextWriter writer;
10 |
11 | private int indentation;
12 |
13 | public ASTPrinter(TextWriter output)
14 | {
15 | Preconditions.NotNull(output, "output");
16 |
17 | this.writer = output;
18 | }
19 |
20 |
21 | public void TraverseStart(object sender, XmlStartTraverseEventArgs e)
22 | {
23 | }
24 |
25 | public void EnteringNode(object sender, XmlTraverseEventArgs e)
26 | {
27 | var node = e.Node;
28 | var toPrint = string.Format("{0}{1}:{2}:{3} - {4}", new string(' ', indentation), node.NodeType, node.Prefix, node.LocalName, node.Value);
29 | writer.WriteLine(toPrint);
30 | indentation++;
31 | }
32 |
33 | public void LeavingNode(object sender, XmlTraverseEventArgs e)
34 | {
35 | var node = e.Node;
36 | indentation--;
37 | var toPrint = string.Format("{0}{1}:{2}:{3} - {4}", new string(' ', indentation), node.NodeType, node.Prefix, node.LocalName, node.Value);
38 | writer.WriteLine(toPrint);
39 | }
40 |
41 | public void TraverseEnd(object sender, XmlEndTraverseEventArgs e)
42 | {
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/Closure.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Text;
3 | using System.Xml;
4 | using PHPAnalysis.Utils;
5 |
6 | namespace PHPAnalysis.Data.PHP
7 | {
8 | public sealed class Closure
9 | {
10 | public XmlNode AstNode { get; private set; }
11 | public int StartLine { get; set; }
12 | public int EndLine { get; set; }
13 | public string File { get; set; }
14 | public Parameter[] Parameters { get; set; }
15 | public ClosureUse[] UseParameters { get; set; }
16 |
17 | public Closure(XmlNode node)
18 | {
19 | Preconditions.NotNull(node, "node");
20 |
21 | this.AstNode = node;
22 | Parameters = new Parameter[0];
23 | UseParameters = new ClosureUse[0];
24 | }
25 |
26 | public override string ToString()
27 | {
28 | var builder = new StringBuilder("function");
29 | builder.Append("(")
30 | .Append(string.Join(", ", Parameters))
31 | .Append(") ");
32 | if (UseParameters.Any())
33 | {
34 | builder.Append("use (")
35 | .Append(string.Join(", ", UseParameters))
36 | .Append(") ");
37 | }
38 |
39 | builder.Append(StartLine)
40 | .Append(" ")
41 | .Append(EndLine);
42 |
43 | return builder.ToString();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Utils/XmlHelpers/ScalarNodeTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Xml;
8 | using System.Xml.XPath;
9 | using NUnit.Framework;
10 | using PHPAnalysis.Data;
11 | using PHPAnalysis.Utils.XmlHelpers;
12 |
13 | namespace PHPAnalysis.Tests.Utils.XmlHelpers
14 | {
15 | [TestFixture]
16 | public class ScalarNodeTests
17 | {
18 | [TestCase(1.1),TestCase(123.1)]
19 | public void DValueResolving(double valueToTest)
20 | {
21 | var node = CreateDValueNodeWithValue(valueToTest);
22 |
23 | double result = ScalarNode.GetDValue(node);
24 |
25 | Assert.AreEqual(valueToTest, result);
26 | }
27 |
28 | private static XmlNode CreateDValueNodeWithValue(double value)
29 | {
30 | var doc = new XmlDocument();
31 | var node = doc.CreateNode(XmlNodeType.Element, AstConstants.Node, AstConstants.Nodes.Scalar_DNumber, "");
32 | var valueNode = doc.CreateNode(XmlNodeType.Element, AstConstants.Subnode, AstConstants.Subnodes.Value, "");
33 | var floatNode = doc.CreateNode(XmlNodeType.Element, AstConstants.Scalar, AstConstants.Scalars.Float, "");
34 | floatNode.InnerText = value.ToString(CultureInfo.InvariantCulture);
35 | valueNode.AppendChild(floatNode);
36 | node.AppendChild(valueNode);
37 | return node;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("PHPAnalysis.Tests")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("PHPAnalysis.Tests")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("56b730c1-f414-4401-9017-64921d754d52")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("PHPAnalysis")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("PHPAnalysis")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("20ea6434-7f3b-4d4a-85a2-a9dd3187803c")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/WordPress.Plugin/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("WordPress.Plugin")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("WordPress.Plugin")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("ac2b0212-99fa-42d4-8902-37042cb99acb")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/FileWriter.Plugin/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("FileWriter.Plugin")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("FileWriter.Plugin")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("74954e6e-666a-4ad9-88dc-be07948d02bf")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/Conditional.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using System.Xml.Linq;
8 | using PHPAnalysis.Data;
9 |
10 | namespace PHPAnalysis.Utils.XmlHelpers
11 | {
12 | public static class Conditional
13 | {
14 | private static readonly string[] NodesWithCondSubNode =
15 | {
16 | AstConstants.Nodes.Stmt_Case,
17 | AstConstants.Nodes.Stmt_Do,
18 | AstConstants.Nodes.Stmt_ElseIf,
19 | AstConstants.Nodes.Stmt_For,
20 | AstConstants.Nodes.Stmt_If,
21 | AstConstants.Nodes.Stmt_Switch,
22 | AstConstants.Nodes.Stmt_While,
23 | };
24 |
25 | public static bool HasConditionNode(XmlNode node)
26 | {
27 | return NodesWithCondSubNode.Contains(node.LocalName);
28 | }
29 |
30 | public static XmlNode GetCondNode(XmlNode node)
31 | {
32 | Preconditions.NotNull(node, "node");
33 | Preconditions.IsTrue(NodesWithCondSubNode.Contains(node.LocalName),
34 | "Expected node representing conditional statement. Received a " + node.Name);
35 |
36 | return node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Cond);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/AstNodeInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using PHPAnalysis.Data;
8 |
9 | namespace PHPAnalysis.Utils.XmlHelpers
10 | {
11 | public static class AstNodeInfo
12 | {
13 | public static XmlNode GetVarNameXmlNode(XmlNode node)
14 | {
15 | Preconditions.NotNull(node, "node");
16 | var varNode = node;
17 |
18 | while (varNode.HasChildNodes)
19 | {
20 | XmlNode tempNode;
21 | if (varNode.TryGetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Var, out tempNode))
22 | {
23 | varNode = tempNode;
24 | if (tempNode.TryGetSubNode(AstConstants.Node + ":" + AstConstants.Nodes.Expr_Variable, out tempNode))
25 | {
26 | if (tempNode.TryGetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Name, out tempNode))
27 | {
28 | return tempNode;
29 | }
30 | }
31 | }
32 | varNode = varNode.FirstChild;
33 | }
34 |
35 | throw new ArgumentException("Unknown XmlNode structure - Unable to find variable name - Implementation needed");
36 | }
37 |
38 | public static XmlNode GetValueFromXmlNode(XmlNode node)
39 | {
40 |
41 |
42 | return null;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.PluginInterface/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("PHPAnalysis.PluginInterface")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Microsoft")]
12 | [assembly: AssemblyProduct("PHPAnalysis.PluginInterface")]
13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5b1ed30b-0f69-4750-a6a0-24409f5afd0a")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Analysis/CFG/CFGTraverserTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Moq;
7 | using NUnit.Framework;
8 | using PHPAnalysis.Analysis.CFG;
9 | using PHPAnalysis.Analysis.CFG.Traversal;
10 | using PHPAnalysis.Parsing;
11 | using PHPAnalysis.Tests.TestUtils;
12 | using PHPAnalysis.Utils;
13 |
14 | namespace PHPAnalysis.Tests.Analysis.CFG
15 | {
16 | [TestFixture]
17 | public class CFGTraverserTests
18 | {
19 | [Test]
20 | public void CFGTraverser_ShouldTraverseAllBlocksAtLeastOnce()
21 | {
22 | var analysisMock = new Mock();
23 | analysisMock.Setup(a => a.Analyze(null)).Returns(false);
24 |
25 | var traverser = new CFGTraverser(new ForwardTraversal(), analysisMock.Object, new QueueWorklist());
26 | }
27 | }
28 |
29 | [TestFixture]
30 | public sealed class ReversePostOrderTests : ConfigDependentTests
31 | {
32 | [Test]
33 | public void ReversePostOrderAlgorithm1()
34 | {
35 | string phpCode = @"(phpCode, Config.PHPSettings.PHPParserPath).Graph;
47 | new CFGPruner().Prune(cfg);
48 |
49 | //cfg.VisualizeGraph("cfg", Config.GraphSettings);
50 |
51 | var postOrder = new ReversePostOrderAlgorithm(cfg).CalculateReversePostOrder();
52 |
53 |
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Configuration/FuncSpecConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.CompilerServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using PHPAnalysis.Annotations;
8 | using PHPAnalysis.Utils;
9 | using YamlDotNet.Serialization;
10 |
11 | namespace PHPAnalysis.Configuration
12 | {
13 | public sealed class FuncSpecConfiguration
14 | {
15 | public IList PHPSpecs { get; private set; }
16 | public IList ExtensionSpecs { get; private set; }
17 |
18 | public FuncSpecConfiguration(IList phpSpecs, IList extensionSpecs)
19 | {
20 | Preconditions.NotNull(phpSpecs, "phpSpecs");
21 | this.PHPSpecs = phpSpecs;
22 |
23 | this.ExtensionSpecs = extensionSpecs ?? new List();
24 | }
25 |
26 | public override string ToString()
27 | {
28 | var sb = new StringBuilder();
29 | sb.AppendLine("PHP specs paths: ");
30 | foreach (var path in PHPSpecs)
31 | {
32 | sb.AppendLine("-" + "".PadLeft(2) + path);
33 | }
34 | sb.AppendLine("Extension paths:");
35 | foreach (var path in ExtensionSpecs)
36 | {
37 | sb.AppendLine("-" + "".PadLeft(2) + path);
38 | }
39 | return sb.ToString();
40 | }
41 | }
42 |
43 | [UsedImplicitly]
44 | internal sealed class FuncSpecConfigurationMutable
45 | {
46 | public List PHPSpecs { get; set; }
47 | public List ExtensionSpecs { get; set; }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/TaintHandlerTaintSet.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.Immutable;
3 | using PHPAnalysis.Data;
4 | using PHPAnalysis.Utils;
5 |
6 | namespace PHPAnalysis.Analysis.CFG
7 | {
8 | public sealed class TaintHandlerTaintSet : IMergeable
9 | {
10 | public IImmutableDictionary Taint { get; private set; }
11 |
12 | public TaintHandlerTaintSet(Dictionary variableTaints)
13 | {
14 | Preconditions.NotNull(variableTaints, "variableTaints");
15 |
16 | Taint = ImmutableDictionary.Empty;
17 | Taint = Taint.AddRange(variableTaints);
18 | }
19 | public TaintHandlerTaintSet(IImmutableDictionary variableTaint)
20 | {
21 | Preconditions.NotNull(variableTaint, "variableTaint");
22 | Taint = variableTaint;
23 | }
24 |
25 | public void AddTaintedVar(Variable var, VariableTaint varTaint)
26 | {
27 | Taint = Taint.SetItem(var, varTaint);
28 | }
29 |
30 | public TaintHandlerTaintSet Merge(TaintHandlerTaintSet other)
31 | {
32 | var taintDict = new Dictionary();
33 | foreach (KeyValuePair variableTaint in Taint)
34 | {
35 | var mergedTaint = variableTaint.Value.Merge(other.Taint[variableTaint.Key]);
36 | taintDict.Add(variableTaint.Key, mergedTaint);
37 | }
38 |
39 | return new TaintHandlerTaintSet(taintDict);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Configuration/PHPConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.ObjectModel;
3 | using System.Linq;
4 | using System.Text;
5 | using PHPAnalysis.Annotations;
6 | using PHPAnalysis.Utils;
7 |
8 | namespace PHPAnalysis.Configuration
9 | {
10 | public sealed class PHPConfiguration
11 | {
12 | public string PHPPath { get; private set; }
13 | public string PHPParserPath { get; private set; }
14 | public IList PHPFileExtensions { get; private set; }
15 |
16 | public PHPConfiguration(string phpPath, string phpParserPath, IList phpExtensions)
17 | {
18 | Preconditions.NotNull(phpPath, "phpPath");
19 | Preconditions.NotNull(phpParserPath, "phpParserPath");
20 | Preconditions.NotNull(phpExtensions, "phpExtensions");
21 |
22 | this.PHPParserPath = phpParserPath;
23 | this.PHPPath = phpPath;
24 | this.PHPFileExtensions = phpExtensions;
25 | }
26 |
27 | public override string ToString()
28 | {
29 | var stringBuilder = new StringBuilder();
30 | stringBuilder.AppendLine("PHP Path: " + PHPPath);
31 | stringBuilder.AppendLine("PHP Parser: " + PHPParserPath);
32 | stringBuilder.AppendLine("File extensions: " + string.Join(", ", PHPFileExtensions.ToArray()));
33 | return stringBuilder.ToString();
34 | }
35 | }
36 |
37 | [UsedImplicitly]
38 | internal sealed class PHPConfigurationMutable
39 | {
40 | public string PHPPath { get; set; }
41 | public List PHPExts { get; set; }
42 | public string PHPParsePath { get; set; }
43 | }
44 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/ExecutiveDeskToyAnimation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.IO.Cmd
4 | {
5 | internal class ExecutiveDeskToyAnimation : AnimationIndicator
6 | {
7 | protected override string[] Steps
8 | {
9 | get
10 | {
11 | return new[] {
12 | @"╔════╤╤╤╤════╗" + Environment.NewLine +
13 | @"║ │││ \ ║" + Environment.NewLine +
14 | @"║ │││ O ║" + Environment.NewLine +
15 | @"║ OOO ║",
16 | @"╔════╤╤╤╤════╗" + Environment.NewLine +
17 | @"║ ││││ ║" + Environment.NewLine +
18 | @"║ ││││ ║" + Environment.NewLine +
19 | @"║ OOOO ║",
20 | @"╔════╤╤╤╤════╗" + Environment.NewLine +
21 | @"║ / │││ ║" + Environment.NewLine +
22 | @"║ O │││ ║" + Environment.NewLine +
23 | @"║ OOO ║",
24 | @"╔════╤╤╤╤════╗" + Environment.NewLine +
25 | @"║ ││││ ║" + Environment.NewLine +
26 | @"║ ││││ ║" + Environment.NewLine +
27 | @"║ OOOO ║"
28 | };
29 | }
30 | }
31 |
32 | protected override string FinalStep
33 | {
34 | get { return Steps[1]; }
35 | }
36 |
37 | public ExecutiveDeskToyAnimation(int max = 100) : base(max)
38 | {
39 |
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/ExpressionInfo.cs:
--------------------------------------------------------------------------------
1 | using PHPAnalysis.Data;
2 | using PHPAnalysis.Utils;
3 |
4 | namespace PHPAnalysis.Analysis.CFG.Taint
5 | {
6 | ///
7 | /// Represents the information being propagated up through the AST when analyzing a CFG block
8 | /// in the taint analysis.
9 | ///
10 | public sealed class ExpressionInfo : IMergeable
11 | {
12 | public TaintSets ExpressionTaint { get; set; }
13 | public StoredVulnInfo ExpressionStoredTaint { get; set; }
14 | public ValueInfo ValueInfo { get; set; }
15 |
16 | public ExpressionInfo()
17 | {
18 | this.ExpressionTaint = new TaintSets().ClearTaint();
19 | this.ExpressionStoredTaint = new StoredVulnInfo();
20 | this.ValueInfo = new ValueInfo();
21 | }
22 |
23 | public ExpressionInfo Merge(ExpressionInfo other)
24 | {
25 | return new ExpressionInfo()
26 | {
27 | ExpressionTaint = this.ExpressionTaint.Merge(other.ExpressionTaint),
28 | ExpressionStoredTaint = this.ExpressionStoredTaint.Merge(other.ExpressionStoredTaint),
29 | ValueInfo = this.ValueInfo.Merge(other.ValueInfo)
30 | };
31 | }
32 |
33 | public ExpressionInfo AssignmentClone()
34 | {
35 | return new ExpressionInfo() {
36 | ExpressionTaint = this.ExpressionTaint.DeepClone(),
37 | ExpressionStoredTaint = this.ExpressionStoredTaint, // TODO: CLONE!
38 | ValueInfo = this.ValueInfo.AssignmentClone()
39 | };
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/PHPAnalysis-parser/src/commands/CountCommand.php:
--------------------------------------------------------------------------------
1 | setName('count')
18 | ->setDescription('Compute code file statistics (Require CLOC)')
19 | ->addArgument('target', InputArgument::REQUIRED, 'Target directory of scan.')
20 | ->addOption('ext', 'e', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Count files with specified extensions.', null)
21 | //->addOption('subdirs', 'sub', InputOption::VALUE_OPTIONAL, "Include subdirectories when counting.", true);
22 | ;
23 | }
24 |
25 | protected function execute(InputInterface $input, OutputInterface $output) {
26 | $target = $input->getArgument('target');
27 |
28 | if ( !is_dir($target) ) {
29 | $output->writeln("Error: Target does not seem to be a valid directory..");
30 | return;
31 | }
32 |
33 | $output->writeln("Starting directory scan of " . $target);
34 | system("cloc " . $target);
35 |
36 | //$output->writeln(iterator_count($this->GetFiles($target)));
37 | //$output->writeln("");
38 |
39 | //foreach ($this->GetFiles($target) as $file) {
40 | // $output->writeln($file);
41 | //}
42 | }
43 |
44 | private function GetFiles($dir) {
45 | $finder = new Finder();
46 | return $finder->files()->in($dir);
47 | }
48 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/PrioritizedCompositeAnalysis.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using PHPAnalysis.Data.CFG;
4 | using PHPAnalysis.Utils;
5 | using QuickGraph;
6 |
7 | namespace PHPAnalysis.Analysis.CFG
8 | {
9 | public sealed class PrioritizedCompositeAnalysis : ICFGAnalysis
10 | {
11 | private readonly SortedList _analyses;
12 |
13 | public PrioritizedCompositeAnalysis()
14 | {
15 | this._analyses = new SortedList();
16 | }
17 |
18 | public void AddAnalysis(ICFGAnalysis analysis, uint priority)
19 | {
20 | Preconditions.NotNull(analysis, "analysis");
21 | string message = "Two analyses cannot have the same priority (" + priority + ").";
22 | Preconditions.IsFalse(_analyses.ContainsKey(priority), message, "priority");
23 |
24 | _analyses.Add(priority, analysis);
25 | }
26 |
27 | public void Initialize(CFGBlock cfgBlock)
28 | {
29 | foreach (var cfgAnalysis in _analyses)
30 | {
31 | cfgAnalysis.Value.Initialize(cfgBlock);
32 | }
33 | }
34 |
35 | public bool Analyze(TaggedEdge edge)
36 | {
37 | var didAnyChange = false;
38 | foreach (var cfgAnalysis in _analyses)
39 | {
40 | if (cfgAnalysis.Value.Analyze(edge))
41 | {
42 | didAnyChange = true;
43 | }
44 | }
45 | return didAnyChange;
46 | }
47 |
48 | public bool Analyze2(CFGBlock block, IBidirectionalGraph> graph)
49 | {
50 | throw new NotImplementedException();
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/StackSet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using PHPAnalysis.Utils;
6 |
7 | namespace PHPAnalysis.Data
8 | {
9 | public sealed class StackSet : ICollection, IReadOnlyCollection
10 | {
11 | private readonly Stack _stack;
12 | private readonly HashSet _set;
13 |
14 | public StackSet()
15 | {
16 | this._stack = new Stack();
17 | this._set = new HashSet();
18 | }
19 |
20 | public void Enqueue(T item)
21 | {
22 | if (!_set.Contains(item))
23 | {
24 | _stack.Push(item);
25 | _set.Add(item);
26 | }
27 | }
28 |
29 | public T Dequeue()
30 | {
31 | if (_stack.IsEmpty())
32 | {
33 | throw new InvalidOperationException("Stack is empty");
34 | }
35 |
36 | _set.Remove(_stack.Peek());
37 | return _stack.Pop();
38 | }
39 |
40 | public IEnumerator GetEnumerator()
41 | {
42 | return _stack.GetEnumerator();
43 | }
44 |
45 | IEnumerator IEnumerable.GetEnumerator()
46 | {
47 | return GetEnumerator();
48 | }
49 |
50 | public void CopyTo(Array array, int index)
51 | {
52 | ((ICollection) _stack).CopyTo(array, index);
53 | }
54 |
55 | public int Count
56 | {
57 | get { return _stack.Count; }
58 | }
59 |
60 | object ICollection.SyncRoot
61 | {
62 | get { return ((ICollection) _stack).SyncRoot; }
63 | }
64 |
65 | bool ICollection.IsSynchronized
66 | {
67 | get { return ((ICollection) _stack).IsSynchronized; }
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/BreakContinue.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Runtime.CompilerServices;
4 | using System.Xml;
5 | using System.Xml.Linq;
6 | using PHPAnalysis.Data;
7 |
8 | namespace PHPAnalysis.Utils.XmlHelpers
9 | {
10 | internal static class BreakContinue
11 | {
12 | public static readonly int DefaultScopeNumber = 1;
13 |
14 | ///
15 | /// Tries to get the number associated with the break/continue statement.
16 | /// e.g. Continue 3; or Break 10;
17 | ///
18 | public static bool TryGetScopeNumber(XmlNode node, out int scopeNumber)
19 | {
20 | Preconditions.NotNull(node, "node");
21 | Preconditions.IsTrue(node.LocalName == AstConstants.Nodes.Stmt_Break ||
22 | node.LocalName == AstConstants.Nodes.Stmt_Continue,
23 | "Expected a break/continue node, but received a " + node.Name);
24 |
25 |
26 | const int minimumValue = 1;
27 | scopeNumber = minimumValue;
28 |
29 | XDocument xNode = XDocument.Parse(node.OuterXml);
30 | XNamespace nsa = AstConstants.Namespaces.SubNode;
31 |
32 | var numDescendants = xNode.Descendants(nsa + AstConstants.Subnodes.Num)
33 | .SingleOrDefault();
34 |
35 | if (numDescendants == null)
36 | {
37 | return false;
38 | }
39 | var number = numDescendants.Descendants(nsa + AstConstants.Subnodes.Value)
40 | .Select(n => Convert.ToInt32(n.Value))
41 | .SingleOrDefault();
42 |
43 | if (number < minimumValue)
44 | {
45 | return false;
46 | }
47 |
48 | scopeNumber = number;
49 | return true;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/StringAnalysis.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 | using System.Threading.Tasks;
7 | using System.Xml;
8 |
9 | namespace PHPAnalysis.Analysis.CFG.Taint
10 | {
11 | public static class StringAnalysis
12 | {
13 | ///
14 | /// Checks whether the given string statement is an SQL insertion statement
15 | /// Examples: INSERT INTO, UPDATE
16 | ///
17 | public static bool IsSQLInsertionStmt(string statement)
18 | {
19 | return statement.ToUpper().StartsWith("INSERT INTO") || statement.ToUpper().StartsWith("UPDATE");
20 | }
21 |
22 | ///
23 | /// Checks whether the given string statement is an SQL retrieve statement
24 | /// Examples: SELECT
25 | ///
26 | public static bool IsSQLRetrieveStmt(string statement)
27 | {
28 | return statement.ToUpper().StartsWith("SELECT");
29 | }
30 |
31 | public static string RetrieveSQLTableName(string statement)
32 | {
33 | var result = "";
34 | if (statement.ToUpper().StartsWith("INSERT INTO"))
35 | {
36 | var rex = new Regex(@"(?i)(?<=\bINSERT INTO\s)[\p{L}_-]+");
37 | result = rex.Match(statement).Value.ToLower();
38 | }
39 | else if (statement.ToUpper().StartsWith("UPDATE"))
40 | {
41 | var rex = new Regex(@"(?i)(?<=\bUPDATE\s)[\p{L}_-]+");
42 | result = rex.Match(statement).Value.ToLower();
43 | }
44 | else if (statement.ToUpper().StartsWith("SELECT"))
45 | {
46 | var rex = new Regex(@"(?i)(?<=\bFROM\s)[\p{L}_-]+");
47 | result = rex.Match(statement).Value.ToLower();
48 | }
49 |
50 | return result;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/IVulnerabilityStorage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Immutable;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using PHPAnalysis.Analysis.CFG;
8 | using PHPAnalysis.Analysis.CFG.Taint;
9 | using PHPAnalysis.Annotations;
10 | using PHPAnalysis.Data;
11 | using PHPAnalysis.Utils;
12 |
13 | namespace PHPAnalysis.Analysis
14 | {
15 | public interface IVulnerabilityStorage
16 | {
17 | IEnumerable Vulnerabilities { get; }
18 |
19 | void AddVulnerability(IVulnerabilityInfo vulnerabilityInfo);
20 | void AddPossibleStoredVulnerability(IStoredVulnerabilityInfo vulnerabilityInfo);
21 | }
22 |
23 | public interface IVulnerabilityInfo
24 | {
25 | string Message { get; }
26 | ImmutableStack IncludeStack { get; }
27 |
28 | ImmutableStack CallStack { get; }
29 | }
30 |
31 | public interface IStoredVulnerabilityInfo : IVulnerabilityInfo
32 | {
33 | StoredVulnInfo PossibleStoredVuln { get; set; }
34 | VulnType VulnerabilityType { get; set; }
35 | }
36 | public class VulnerabilityInfo : IVulnerabilityInfo
37 | {
38 | public string Message { get; set; }
39 | public ImmutableStack IncludeStack { get; set; }
40 |
41 | public ImmutableStack CallStack { get; set; }
42 | }
43 | public class StoredVulnerabilityInfo : IStoredVulnerabilityInfo
44 | {
45 | public string Message { get; set; }
46 | public ImmutableStack IncludeStack { get; set; }
47 | public ImmutableStack CallStack { get; set; }
48 |
49 | public StoredVulnInfo PossibleStoredVuln { get; set; }
50 | public VulnType VulnerabilityType { get; set; }
51 | }
52 |
53 | [Flags]
54 | public enum VulnType
55 | {
56 | Unknown = 0,
57 | XSS = 1,
58 | SQL = 2,
59 | BOTH = 3,
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CompositeVulneribilityReporter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using PHPAnalysis.Analysis.PHPDefinitions;
4 | using PHPAnalysis.Utils;
5 |
6 | namespace PHPAnalysis.Analysis
7 | {
8 | internal sealed class CompositeVulneribilityReporter : IVulnerabilityReporter
9 | {
10 | private readonly ICollection _reporters = new List();
11 | public uint NumberOfReportedVulnerabilities { get; private set; }
12 |
13 | public CompositeVulneribilityReporter(params IVulnerabilityReporter[] reporters)
14 | {
15 | Preconditions.NotNull(reporters, "reporters");
16 | _reporters.AddRange(reporters);
17 | }
18 |
19 | public CompositeVulneribilityReporter(IEnumerable reporters)
20 | {
21 | Preconditions.NotNull(reporters, "reporters");
22 | _reporters.AddRange(reporters);
23 | }
24 |
25 | public void ReportVulnerability(IVulnerabilityInfo vulnerabilityInfo)
26 | {
27 | foreach (var vulnerabilityReporter in _reporters)
28 | {
29 | vulnerabilityReporter.ReportVulnerability(vulnerabilityInfo);
30 | }
31 |
32 | NumberOfReportedVulnerabilities++;
33 | }
34 |
35 | public void ReportStoredVulnerability(IVulnerabilityInfo[] vulnerabilityPathInfos)
36 | {
37 | foreach (var vulnerabilityReporter in _reporters)
38 | {
39 | vulnerabilityReporter.ReportStoredVulnerability(vulnerabilityPathInfos);
40 | }
41 |
42 | NumberOfReportedVulnerabilities++;
43 | }
44 |
45 | public void RegisterFunctionsHandler(FunctionsHandler functionsHandler)
46 | {
47 | foreach (var vulnerabilityReporter in _reporters)
48 | {
49 | vulnerabilityReporter.RegisterFunctionsHandler(functionsHandler);
50 | }
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/FunctionSpecs/WPSpecifications/wpSQLSanitizers.json:
--------------------------------------------------------------------------------
1 | {
2 | "SQLSanitizersFuncs":[
3 | {
4 | "name":"esc_sql",
5 | "formats":[ "esc_sql(string)" ],
6 | "totalParameters": 1,
7 | "parameters": [
8 | { "number":1, "name":"sql", "type":"string", "isReturnValue":true }
9 | ],
10 | "returnType":"string",
11 | "defaultStatus": "None"
12 | },
13 | {
14 | "name":"wpdb->prepare",
15 | "formats":[ "wpdb->prepare(string, array)" ],
16 | "totalParameters": 2,
17 | "parameters": [
18 | { "number":1, "name":"query", "type":"string", "isReturnValue":true },
19 | { "number":2, "name":"value_parameter", "type":"array", "IsVariadic": true, "isReturnValue":false }
20 | ],
21 | "returnType":"string",
22 | "defaultStatus": "SQL_ALL"
23 | },
24 | {
25 | "name":"checked",
26 | "formats": [ "checked(string, bool, bool)" ],
27 | "totalParameters":3,
28 | "parameters": [
29 | { "number":1, "name":"string", "type":"string" },
30 | { "number":2, "name":"string", "type":"bool", "isoptional":true },
31 | { "number":3, "name":"string", "type":"bool", "isoptional":true }
32 | ],
33 | "returnType":"string",
34 | "defaultStatus":"None"
35 | },
36 | {
37 | "name":"selected",
38 | "formats": [ "checked(string, bool, bool)" ],
39 | "totalParameters":3,
40 | "parameters": [
41 | { "number":1, "name":"string", "type":"string" },
42 | { "number":2, "name":"string", "type":"bool", "isoptional":true },
43 | { "number":3, "name":"string", "type":"bool", "isoptional":true }
44 | ],
45 | "returnType":"string",
46 | "defaultStatus":"None"
47 | }
48 | ]
49 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/FunctionCall.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Xml;
4 | using System.Collections.Generic;
5 | using PHPAnalysis.Analysis.CFG.Taint;
6 | using PHPAnalysis.Data;
7 |
8 | namespace PHPAnalysis
9 | {
10 | public class FunctionCall
11 | {
12 | public string Name { get; set; }
13 | public XmlNode ASTNode { get; set; }
14 | public int StartLine { get; set; }
15 | public int EndLine { get; set; }
16 | public IDictionary Arguments { get; set; }
17 |
18 | public FunctionCall(string name, XmlNode astNode, int start, int end)
19 | {
20 | this.Name = name;
21 | this.ASTNode = astNode;
22 | this.StartLine = start;
23 | this.EndLine = end;
24 | }
25 |
26 | public override string ToString()
27 | {
28 | return string.Format("{0} {1} {2}", Name, StartLine, EndLine);
29 | }
30 | }
31 |
32 | public class MethodCall : FunctionCall
33 | {
34 | public IList ClassNames { get; set; }
35 | public Variable Var { get; set; }
36 |
37 | public MethodCall(string methodName, IList className, XmlNode astNode, int start, int end, Variable variable = null)
38 | : base(methodName, astNode, start, end)
39 | {
40 | this.ClassNames = className;
41 | this.Var = variable;
42 | }
43 |
44 | public string CreateFullMethodName(string className)
45 | {
46 | // HACK - this.Name should NOT already have class name in it!
47 | // It sometimes has because of the way we handle methodnames when extracting/putting into functionhandler.
48 | if (this.Name.Contains("->"))
49 | {
50 | return this.Name;
51 | }
52 | return className + "->" + this.Name;
53 | }
54 |
55 | public override string ToString()
56 | {
57 | return string.Format("[{0}] ->{1}", string.Join(",", ClassNames), base.ToString());
58 | }
59 | }
60 | }
61 |
62 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/AnimationIndicator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace PHPAnalysis.IO.Cmd
5 | {
6 | internal abstract class AnimationIndicator : ProgressIndicator
7 | {
8 | protected abstract string[] Steps { get; }
9 | protected abstract string FinalStep { get; }
10 | public int Max { get; private set; }
11 | public int Min { get; private set; }
12 |
13 | private int _progress = 0;
14 | private int counter = 0;
15 | private Timer timer;
16 | private readonly int _cursorTopStart;
17 |
18 | protected AnimationIndicator(int max = 100)
19 | {
20 | this.Min = 0;
21 | this.Max = max;
22 | if (Console.CursorLeft != 0)
23 | Console.WriteLine();
24 | this._cursorTopStart = Console.CursorTop;
25 | }
26 |
27 | public override sealed void Step()
28 | {
29 | if (_progress >= Max) { return; }
30 | if (counter == 0)
31 | {
32 | timer = new Timer(RunAnimation, null, 0, 250);
33 | }
34 |
35 | _progress++;
36 | Stepped(_progress);
37 | if (_progress == Max)
38 | {
39 | timer.Dispose();
40 | Console.SetCursorPosition(0, _cursorTopStart);
41 | Console.Write(FinalStep);
42 | Console.Write(" " + (int)PercentOf(_progress, Max) + "%");
43 | Console.Write(Environment.NewLine);
44 | }
45 | }
46 |
47 | private void RunAnimation(object stateInfo)
48 | {
49 | Console.SetCursorPosition(0, _cursorTopStart);
50 | counter++;
51 | Console.Write(Steps[counter % Steps.Length]);
52 | Console.Write(" " + (int)PercentOf(_progress, Max) + "%");
53 | }
54 |
55 | private static float PercentOf(int value, int target)
56 | {
57 | return ((value / (float)target) * 100);
58 | }
59 |
60 | protected virtual void Stepped(int progress) { }
61 | }
62 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/BarIndicator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.IO.Cmd
4 | {
5 | internal sealed class BarIndicator : ProgressIndicator
6 | {
7 | public int Max { get; private set; }
8 | public int Min { get; private set; }
9 |
10 | private readonly int _barWidth;
11 | private int _progress = 0;
12 |
13 | private int ProgressPosition { get { return _barWidth + 3; } }
14 |
15 | public BarIndicator(int max = 100)
16 | {
17 | this.Min = 0;
18 | this.Max = max;
19 | this._barWidth = 32;
20 | }
21 |
22 | public override void Step()
23 | {
24 | if (_progress >= Max) { return; }
25 |
26 | _progress++;
27 | UpdateProgress(_progress, Max);
28 | if (_progress == Max)
29 | {
30 | System.Console.Write(Environment.NewLine);
31 | }
32 | }
33 |
34 | private void UpdateProgress(int progress, int total)
35 | {
36 | DrawEmptyProgressBar();
37 | System.Console.CursorLeft = 1;
38 |
39 | DrawBar(progress, total);
40 |
41 | DrawProcent(progress, total);
42 | }
43 |
44 | private void DrawBar(int progress, int total)
45 | {
46 | System.Console.CursorLeft = 1;
47 |
48 | float howManyToPrint = (progress / (float)total) * (_barWidth - 2);
49 |
50 | System.Console.Write(new string('#', (int)howManyToPrint));
51 |
52 | }
53 |
54 | private void DrawEmptyProgressBar()
55 | {
56 | System.Console.CursorLeft = 0;
57 | System.Console.Write("[" + new string('-', _barWidth - 2) + "]");
58 | }
59 |
60 | private void DrawProcent(int progress, int total)
61 | {
62 | System.Console.CursorLeft = ProgressPosition;
63 | System.Console.Write((int)PercentOf(progress, total) + "%");
64 | }
65 |
66 | private float PercentOf(int value, int target)
67 | {
68 | return ((value / (float)target) * 100);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/PHPAnalysis/WordPress.Plugin/WpTaintProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using System.Linq;
4 | using PHPAnalysis;
5 | using PHPAnalysis.Analysis;
6 | using PHPAnalysis.Analysis.CFG;
7 | using PHPAnalysis.Analysis.CFG.Taint;
8 | using PHPAnalysis.Data;
9 | using PHPAnalysis.Utils;
10 |
11 | namespace WordPress.Plugin
12 | {
13 | [Export(typeof (ITaintProvider))]
14 | public sealed class WpTaintProvider : ITaintProvider
15 | {
16 | public ImmutableVariableStorage GetTaint()
17 | {
18 | var defaultTaint = new DefaultTaintProvider().GetTaint();
19 |
20 | var variableStorage = defaultTaint.ToMutable();
21 |
22 | foreach (var superGlobal in variableStorage.SuperGlobals)
23 | {
24 | foreach (var var in superGlobal.Value.Info.Variables)
25 | {
26 | var newTaint = var.Value.Info.Taints.DeepClone();
27 | if (newTaint.SqliTaint.Single().TaintTag > SQLITaint.SQL_NoQ)
28 | {
29 | newTaint.SqliTaint.Clear();
30 | newTaint.SqliTaint.Add(new SQLITaintSet( SQLITaint.SQL_NoQ));
31 | }
32 |
33 | var.Value.Info.Taints = newTaint;
34 | var.Value.Info.DefaultDimensionTaintFactory = () =>
35 | new TaintSets(new SQLITaintSet(SQLITaint.SQL_NoQ), new XSSTaintSet(XSSTaint.XSS_ALL));
36 | var.Value.Info.NestedVariableDefaultTaintFactory = var.Value.Info.DefaultDimensionTaintFactory;
37 | }
38 | }
39 |
40 | var wpdbGlobal = new Variable("wpdb", VariableScope.File);
41 | var prefixVar = new Variable("prefix", VariableScope.Instance) { Info = { Value = "Eir_" } };
42 | wpdbGlobal.Info.Variables.Add(new VariableTreeDimension() { Key = "prefix" }, prefixVar);
43 | wpdbGlobal.Info.ClassNames.Add("wpdb");
44 |
45 | variableStorage.GlobalVariables.Add("wpdb", wpdbGlobal);
46 |
47 | return ImmutableVariableStorage.CreateFromMutable(variableStorage);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Parsing/CFGCreator_Case_Tests.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using NUnit.Framework;
3 | using PHPAnalysis.Analysis;
4 | using PHPAnalysis.Parsing;
5 | using PHPAnalysis.Tests.TestUtils;
6 |
7 | namespace PHPAnalysis.Tests.Analysis
8 | {
9 | class CFGCreator_Case_Tests : ConfigDependentTests
10 | {
11 | [TestCase(@"(php, Config.PHPSettings.PHPParserPath);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/XmlHelpers/ScalarNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Linq;
4 | using System.Runtime.InteropServices.ComTypes;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Xml;
8 | using PHPAnalysis.Data;
9 |
10 | namespace PHPAnalysis.Utils.XmlHelpers
11 | {
12 | public static class ScalarNode
13 | {
14 | public static string GetStringValue(XmlNode node)
15 | {
16 | Preconditions.NotNull(node, "node");
17 | Preconditions.IsTrue(node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Scalar_String, "String value retrieval only supported for " + AstConstants.Nodes.Scalar_String + " nodes. Was " + node.Name, "node");
18 |
19 | return node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value)
20 | .GetSubNode(AstConstants.Scalar + ":" + AstConstants.Scalars.String).InnerText;
21 | }
22 |
23 | public static int GetLValue(XmlNode node)
24 | {
25 | Preconditions.NotNull(node, "node");
26 | Preconditions.IsTrue(node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Scalar_LNumber, "LValue retrieval only supported for " + AstConstants.Nodes.Scalar_LNumber + " nodes. Was " + node.Name, "node");
27 |
28 | var innerText = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value)
29 | .GetSubNode(AstConstants.Scalar + ":" + AstConstants.Scalars.Int).InnerText;
30 |
31 | return int.Parse(innerText);
32 | }
33 |
34 | public static double GetDValue(XmlNode node)
35 | {
36 | Preconditions.NotNull(node, "Node");
37 | Preconditions.IsTrue(node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Scalar_DNumber, "DValue retrieval only supported for " + AstConstants.Nodes.Scalar_DNumber + " nodes. Was " + node.Name, "node");
38 |
39 | var innerText = node.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value)
40 | .GetSubNode(AstConstants.Scalar + ":" + AstConstants.Scalars.Float).InnerText;
41 |
42 | return double.Parse(innerText, CultureInfo.InvariantCulture);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/CFGASTNodeVisitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Xml;
4 | using PHPAnalysis.Data;
5 | using PHPAnalysis.Parsing.AstTraversing;
6 |
7 | namespace PHPAnalysis.Analysis.CFG
8 | {
9 | class CFGASTNodeVisitor : IXmlVisitor
10 | {
11 | public List NodesOfInterest;
12 | public void TraverseStart(object sender, XmlStartTraverseEventArgs e)
13 | {
14 | NodesOfInterest = new List();
15 | }
16 |
17 | public void EnteringNode(object sender, XmlTraverseEventArgs e)
18 | {
19 | var node = e.Node;
20 | switch (node.LocalName)
21 | {
22 | case AstConstants.Nodes.Expr_Assign:
23 | NodesOfInterest.Add(node);
24 | break;
25 | case AstConstants.Nodes.Expr_AssignOp_BitwiseAnd:
26 | case AstConstants.Nodes.Expr_AssignOp_BitwiseOr:
27 | case AstConstants.Nodes.Expr_AssignOp_BitwiseXor:
28 | case AstConstants.Nodes.Expr_AssignOp_Concat:
29 | case AstConstants.Nodes.Expr_AssignOp_Div:
30 | case AstConstants.Nodes.Expr_AssignOp_Minus:
31 | case AstConstants.Nodes.Expr_AssignOp_Mod:
32 | case AstConstants.Nodes.Expr_AssignOp_Mul:
33 | case AstConstants.Nodes.Expr_AssignOp_Plus:
34 | case AstConstants.Nodes.Expr_AssignOp_Pow:
35 | case AstConstants.Nodes.Expr_AssignOp_ShiftLeft:
36 | case AstConstants.Nodes.Expr_AssignOp_ShiftRight:
37 | case AstConstants.Nodes.Expr_AssignRef:
38 | break;
39 | case AstConstants.Nodes.Stmt_Echo:
40 | break;
41 | case AstConstants.Nodes.Expr_ShellExec:
42 | break;
43 | case AstConstants.Nodes.Expr_Eval:
44 | break;
45 | }
46 | }
47 |
48 | public void LeavingNode(object sender, XmlTraverseEventArgs e)
49 | {
50 |
51 | }
52 |
53 | public void TraverseEnd(object sender, XmlEndTraverseEventArgs e)
54 | {
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/ProjectParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Xml;
7 | using PHPAnalysis.Configuration;
8 | using PHPAnalysis.IO.Cmd;
9 | using PHPAnalysis.Utils;
10 |
11 | namespace PHPAnalysis.Parsing
12 | {
13 | public sealed class ProjectParser
14 | {
15 | private string ProjectPath { get; set; }
16 | private PHPConfiguration PHPSettings { get; set; }
17 |
18 | public ProjectParser(string projectPath, PHPConfiguration settings)
19 | {
20 | Preconditions.NotNull(projectPath, "projectPath");
21 | Preconditions.NotNull(settings, "settings");
22 |
23 | PHPSettings = settings;
24 |
25 | if (!Directory.Exists(projectPath))
26 | {
27 | string errorMsg = "Directory does not exist. (" + projectPath + ")";
28 | throw new DirectoryNotFoundException(errorMsg);
29 | }
30 |
31 | this.ProjectPath = projectPath;
32 | }
33 |
34 | public ParseResult ParseProjectFiles()
35 | {
36 | IEnumerable files = Directory.GetFiles(ProjectPath, "*", SearchOption.AllDirectories)
37 | .Where(file => PHPSettings.PHPFileExtensions.Contains(Path.GetExtension(file)))
38 | .Select(file => file.Replace(@"\\", @"\"));
39 |
40 | var result = new ParseResult();
41 |
42 | var phpFileParser = new FileParser(PHPSettings.PHPParserPath);
43 |
44 | var progrssIndicator = ProgressIndicatorFactory.CreateProgressIndicator(files.Count());
45 |
46 | foreach (var file in files)
47 | {
48 | progrssIndicator.Step();
49 | try
50 | {
51 | XmlDocument parseResult = phpFileParser.ParsePHPFile(file);
52 | result.ParsedFiles.Add(file, parseResult);
53 | }
54 | catch (XmlException)
55 | {
56 | result.FilesThatFailedToParse.Add(file);
57 | }
58 | }
59 | return result;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/IO/Cmd/BikeGuyRidingAnimation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis.IO.Cmd
4 | {
5 | internal class BikeGuyRidingAnimation : AnimationIndicator
6 | {
7 | private string[] UseThisStep { get; set; }
8 | private int Progrezz { get; set; }
9 | protected override string[] Steps
10 | {
11 | get { return DoBikeGuy(); }
12 | }
13 |
14 | protected override string FinalStep
15 | {
16 | get
17 | {
18 | var indentation = new string(' ', GetBikePosition());
19 | return indentation + @" PHEW- o " + Environment.NewLine +
20 | indentation + @" _ \<,_" + Environment.NewLine +
21 | indentation + @" (*)| (*)";
22 | }
23 | }
24 |
25 | public BikeGuyRidingAnimation(int max = 100)
26 | : base(max)
27 | {
28 | UseThisStep = new[] {@"
29 | ---------- __o
30 | -------- _ \<,_
31 | ------- (*)/ (*)",@"
32 | ---------- __o
33 | -------- _ \<,_
34 | ------- (*) \(*)",
35 | };
36 | }
37 |
38 | private string[] DoBikeGuy()
39 | {
40 | var indentation = new string(' ', GetBikePosition());
41 | UseThisStep = new[] { indentation + @" ---------- __o" + Environment.NewLine +
42 | indentation + @" -------- _ \<,_" + Environment.NewLine +
43 | indentation + @"------- (*)/ (*)",
44 | indentation + @" ---------- __o" + Environment.NewLine +
45 | indentation + @" -------- _ \<,_" + Environment.NewLine +
46 | indentation + @"------- (*) \(*)",
47 | };
48 |
49 | return UseThisStep;
50 | }
51 |
52 | protected override void Stepped(int progress)
53 | {
54 | Progrezz = progress;
55 | }
56 |
57 | private int GetBikePosition()
58 | {
59 | int windowWidth = System.Console.WindowWidth - 25;
60 | int i = (int)((Progrezz / (float)Max) * windowWidth);
61 | return i;
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Parsing/CFGCreator_If_Tests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using NUnit.Framework;
7 | using PHPAnalysis.Analysis;
8 | using PHPAnalysis.Configuration;
9 | using PHPAnalysis.Parsing;
10 | using PHPAnalysis.Tests.TestUtils;
11 |
12 | namespace PHPAnalysis.Tests.Analysis
13 | {
14 | [TestFixture]
15 | public class CFGCreator_If_Tests : ConfigDependentTests
16 | {
17 | [Test]
18 | public void CFGCreation_StandardIf()
19 | {
20 | #region PHP Code
21 | string phpCode = @"(php, Config.PHPSettings.PHPParserPath);
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/File.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.IO;
5 | using System.Xml;
6 | using PHPAnalysis.Data.CFG;
7 | using PHPAnalysis.Data.PHP;
8 | using PHPAnalysis.Utils;
9 | using QuickGraph;
10 |
11 | namespace PHPAnalysis.Data
12 | {
13 | public sealed class File
14 | {
15 | public XmlNode AstNode { get; private set; }
16 | public string FullPath { get; set; }
17 | public string Name { get { return Path.GetFileName(FullPath); } }
18 |
19 | public string Extension { get { return Path.GetExtension(FullPath); } }
20 |
21 |
22 | public IDictionary> Functions { get; set; }
23 | //public IReadOnlyDictionary Functions
24 | //{
25 | // get { return new ReadOnlyDictionary(_functions); }
26 | //}
27 |
28 | public IDictionary> Classes { get; set; }
29 | //public IReadOnlyDictionary Classes
30 | //{
31 | // get { return new ReadOnlyDictionary(_classes); }
32 | //}
33 |
34 | public IDictionary> Interfaces { get; set; }
35 | public Closure[] Closures { get; set; }
36 | public IBidirectionalGraph> CFG { get; set; }
37 |
38 | public File()
39 | {
40 | this.Functions = new Dictionary>();
41 | this.Classes = new Dictionary>();
42 | this.Interfaces = new Dictionary>();
43 | }
44 |
45 | public File(XmlNode node) : this()
46 | {
47 | Preconditions.NotNull(node, "node");
48 |
49 | this.AstNode = node;
50 | }
51 |
52 | public File(IDictionary> functions, IDictionary> classes)
53 | {
54 | Preconditions.NotNull(functions, "functions");
55 | Preconditions.NotNull(classes, "classes");
56 |
57 | this.Functions = functions;
58 | this.Classes = classes;
59 | }
60 |
61 | public override string ToString()
62 | {
63 | return this.Name;
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Analysis/AST/IncludeResolvertTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Xml;
7 | using Moq;
8 | using NUnit.Framework;
9 | using PHPAnalysis.Analysis;
10 | using PHPAnalysis.Analysis.AST;
11 | using PHPAnalysis.Analysis.CFG;
12 | using PHPAnalysis.Analysis.CFG.Taint;
13 | using PHPAnalysis.Analysis.CFG.Traversal;
14 | using PHPAnalysis.Data;
15 | using PHPAnalysis.Parsing;
16 | using PHPAnalysis.Tests.TestUtils;
17 | using PHPAnalysis.Utils.XmlHelpers;
18 |
19 | namespace PHPAnalysis.Tests.Analysis.AST
20 | {
21 | [TestFixture]
22 | public class IncludeResolvertTests : ConfigDependentTests
23 | {
24 | [TestCase(@" new File() {FullPath = f}).ToList());
35 |
36 | var ast = PHPParseUtils.ParsePHPCode(phpCode, Config.PHPSettings.PHPParserPath);
37 |
38 | ast.IterateAllNodes(node =>
39 | {
40 | if (node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Expr_Include)
41 | {
42 | File file;
43 | if (includeResolver.TryResolveInclude(node, out file))
44 | {
45 | Assert.IsTrue(shouldResolve);
46 | }
47 | else
48 | {
49 | Assert.IsFalse(shouldResolve);
50 | }
51 | }
52 | return true;
53 | });
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/QueueSet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using PHPAnalysis.Utils;
5 |
6 | namespace PHPAnalysis.Data
7 | {
8 | public sealed class QueueSet : ICollection, IReadOnlyCollection
9 | {
10 | private readonly Queue _queue;
11 | private readonly HashSet _set;
12 |
13 | public QueueSet()
14 | {
15 | this._queue = new Queue();
16 | this._set = new HashSet();
17 | }
18 |
19 | ///
20 | /// If item already exist it will not be inserted.
21 | ///
22 | ///
23 | public void Enqueue(T item)
24 | {
25 | if (!_set.Contains(item))
26 | {
27 | _queue.Enqueue(item);
28 | _set.Add(item);
29 | }
30 | }
31 |
32 | public T Dequeue()
33 | {
34 | if (_queue.IsEmpty())
35 | {
36 | throw new InvalidOperationException("Queue is empty");
37 | }
38 | _set.Remove(_queue.Peek());
39 | return _queue.Dequeue();
40 | }
41 |
42 | public bool Contains(T item)
43 | {
44 | return _set.Contains(item);
45 | }
46 |
47 | public void Clear()
48 | {
49 | _set.Clear();
50 | _queue.Clear();
51 | }
52 |
53 | public IEnumerator GetEnumerator()
54 | {
55 | return _queue.GetEnumerator();
56 | }
57 |
58 | IEnumerator IEnumerable.GetEnumerator()
59 | {
60 | return GetEnumerator();
61 | }
62 |
63 | void ICollection.CopyTo(Array array, int index)
64 | {
65 | ((ICollection) _queue).CopyTo(array, index);
66 | }
67 |
68 | public void CopyTo(T[] array, int index)
69 | {
70 | _queue.CopyTo(array, index);
71 | }
72 |
73 | public int Count
74 | {
75 | get { return _queue.Count; }
76 | }
77 |
78 | object ICollection.SyncRoot
79 | {
80 | get { return ((ICollection)_queue).SyncRoot; }
81 | }
82 |
83 | bool ICollection.IsSynchronized
84 | {
85 | get { return ((ICollection)_queue).IsSynchronized; }
86 | }
87 | }
88 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/PHPDefinitions/Source.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Newtonsoft.Json;
4 | using Newtonsoft.Json.Linq;
5 | using PHPAnalysis.Analysis.CFG;
6 |
7 | namespace PHPAnalysis
8 | {
9 | public class Source
10 | {
11 | public string Name { get; set; }
12 | public string Type { get; set; }
13 | public List Formats { get; set; }
14 | public XSSTaintSet XssTaint { get; set; }
15 | public SQLITaintSet SqliTaint { get; set; }
16 |
17 | public Source(string json) : this(JToken.Parse(json))
18 | {
19 | //Nothing! Just enabling both string and JToken version of ctor
20 | }
21 |
22 | public Source(JToken JSON)
23 | {
24 | Name = (string)JSON.SelectToken(Keys.PHPDefinitionJSONKeys.GeneralKeys.Name);
25 | Type = (string)JSON.SelectToken(Keys.PHPDefinitionJSONKeys.GeneralKeys.Type);
26 | var xssTaintStr = (string)JSON.SelectToken(Keys.PHPDefinitionJSONKeys.GeneralKeys.XssTaint);
27 | var sqlTaintStr = (string)JSON.SelectToken(Keys.PHPDefinitionJSONKeys.GeneralKeys.SqlTaint);
28 |
29 | //Set up XSS taint from JSON, if it cannot be parsed, then use the default XSS_ALL tag
30 | XSSTaint tmpXss = XSSTaint.XSS_ALL;
31 | var success = Enum.TryParse(xssTaintStr, out tmpXss);
32 | if (success)
33 | {
34 | XssTaint = new XSSTaintSet(tmpXss);
35 | }
36 | else
37 | {
38 | XssTaint = new XSSTaintSet(XSSTaint.XSS_ALL);
39 | }
40 |
41 | //Set up SQL taint from JSON. If it cannot be parsed then use the default SQL_ALL tag.
42 | SQLITaint tmpSqli = SQLITaint.SQL_ALL;
43 | success = Enum.TryParse(sqlTaintStr, out tmpSqli);
44 | if (success)
45 | {
46 | SqliTaint = new SQLITaintSet(tmpSqli);
47 | }
48 | else
49 | {
50 | SqliTaint = new SQLITaintSet(SQLITaint.SQL_ALL);
51 | }
52 |
53 | Formats = new List();
54 | var formats = (JArray)JSON.SelectToken(Keys.PHPDefinitionJSONKeys.GeneralKeys.Formats);
55 | foreach (string format in formats)
56 | {
57 | Formats.Add(format);
58 | }
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/FunctionSpecs/JSONSpecifications/CondSanitizers.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConditionSanitizerFuncs":
3 | [
4 | {
5 | "name":"is_bool",
6 | "formats": [ "is_bool(bool)" ],
7 | "totalParameters":1,
8 | "parameters": [
9 | { "number":1, "name":"bool", "type":"object" }
10 | ],
11 | "returnType":"bool",
12 | "defaultStatus":"XSSSQL_SAFE"
13 | },
14 | {
15 | "name":"is_int",
16 | "formats": [ "is_int(int)" ],
17 | "aliases": [ "is_integer", "is_long" ],
18 | "totalParameters":1,
19 | "parameters": [
20 | { "number":1, "name":"int", "type":"object" }
21 | ],
22 | "returnType":"bool",
23 | "defaultStatus":"XSSSQL_SAFE"
24 | },
25 | {
26 | "name":"is_float",
27 | "formats": [ "is_float(float)" ],
28 | "aliases": [ "is_double", "is_real" ],
29 | "totalParameters":1,
30 | "parameters": [
31 | { "number":1, "name":"float", "type":"object" }
32 | ],
33 | "returnType":"bool",
34 | "defaultStatus":"XSSSQL_SAFE"
35 | },
36 | {
37 | "name":"is_numeric",
38 | "formats": [ "is_numeric(number)" ],
39 | "totalParameters":1,
40 | "parameters": [
41 | { "number":1, "name":"number", "type":"object" }
42 | ],
43 | "returnType":"bool",
44 | "defaultStatus":"XSSSQL_SAFE"
45 | },
46 | {
47 | "name":"is_float",
48 | "formats": [ "is_null(object)" ],
49 | "totalParameters":1,
50 | "parameters": [
51 | { "number":1, "name":"object", "type":"object" }
52 | ],
53 | "returnType":"bool",
54 | "defaultStatus":"XSSSQL_SAFE"
55 | },
56 | {
57 | "name":"ctype_alnum",
58 | "formats": [ "ctype_alnum(string)" ],
59 | "totalParameters":1,
60 | "parameters": [
61 | { "number":1, "name":"text", "type":"string" }
62 | ],
63 | "returnType":"bool",
64 | "defaultStatus":"XSSSQL_SAFE"
65 | },
66 | {
67 | "name":"ctype_digit",
68 | "formats":[ "ctype_digit(string)" ],
69 | "aliases": [ "ctype_xdigit" ],
70 | "totalParameters":1,
71 | "parameters": [
72 | { "number":1, "name":"object", "type":"string" }
73 | ],
74 | "returnType":"bool",
75 | "defaultStatus":"XSSSQL_SAFE"
76 | },
77 | {
78 | "name":"ctype_space",
79 | "formats": [ "ctype_space(string)" ],
80 | "totalParameters":1,
81 | "parameters": [
82 | { "number":1, "name":"text", "type":"string" }
83 | ],
84 | "returnType":"bool",
85 | "defaultStatus":"XSSSQL_SAFE"
86 | }
87 | ]
88 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Arguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using CommandLine;
4 | using CommandLine.Text;
5 | using PHPAnalysis.Annotations;
6 |
7 | namespace PHPAnalysis
8 | {
9 | public sealed class Arguments
10 | {
11 | private const string TargetHelpText = "Directory or file to be analyzed.";
12 | private const string ScanAllSubroutinesHelpText =
13 | "If set, analysis will scan all subroutines (methods + functions), " +
14 | "no matter if they are called or not.";
15 |
16 | private const string SummaryHelpText = "If set, analysis will generate summaries of " +
17 | "subroutines and use those when seing a call to a subroutine. (Warning: This will " +
18 | "decrease analysis precision)";
19 |
20 | private const string ConfigLocHelpText = "If set, the analysis will read the given config file " +
21 | ", instead of defaulting to the one in the running folder. Use this if you encounter " +
22 | "problems with finding the Config.yml file. Usage: Full path and filename to Config.yml file";
23 |
24 | [Option('t', "target", Required = true, HelpText = TargetHelpText)]
25 | public string Target { get; set; }
26 |
27 | [Option('a', "all", DefaultValue = false, HelpText = ScanAllSubroutinesHelpText)]
28 | public bool ScanAllSubroutines { get; set; }
29 |
30 | [Option('s', "summaries", DefaultValue = false, HelpText = SummaryHelpText)]
31 | public bool UseFunctionSummaries { get; set; }
32 |
33 | [Option('c', "configlocation", HelpText = ConfigLocHelpText)]
34 | public string ConfigLocation { get; set; }
35 |
36 | [ParserState]
37 | public IParserState LastParserState { get; set; }
38 |
39 | [HelpOption, UsedImplicitly]
40 | public string GetUsage()
41 | {
42 | var helpText = HelpText.AutoBuild(this, current => HelpText.DefaultParsingErrorsHandler(this, current));
43 | helpText.Heading = new HeadingInfo("Eir", "0.0.1");
44 | helpText.Copyright = new CopyrightInfo(" ", 2015);
45 | helpText.AdditionalNewLineAfterOption = true;
46 | helpText.AddPreOptionsLine("---------------------");
47 | helpText.AddPreOptionsLine("Usage: PhpAnalyzer -t [Directory/File] [Options]");
48 | helpText.AddPreOptionsLine(" : PhpAnalyzer [Options] -t [Directory/File]");
49 | return helpText;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/FunctionSpecs/JSONSpecifications/XSSSinks.json:
--------------------------------------------------------------------------------
1 | {
2 | "XssSinkFuncs":[
3 | {
4 | "name":"print",
5 | "formats":[ "print(string)", "printf string" ],
6 | "totalParameters":1,
7 | "parameters": [
8 | { "number":1, "type":"string", "name":"arg" },
9 | ],
10 | "defaultOutput":true,
11 | "returnType":"int",
12 | "defaultStatus":"XSS_ALL"
13 | },
14 | {
15 | "name":"printf",
16 | "formats":[ "printf(string, mix)" ],
17 | "totalParameters":2,
18 | "parameters": [
19 | { "number":1, "type":"string", "name":"format" },
20 | { "number":2, "type":"mix", "name":"...", "IsVariadic":true}
21 | ],
22 | "defaultOutput":true,
23 | "returnType":"int",
24 | "defaultStatus":"XSS_ALL"
25 | },
26 | {
27 | "name":"vprintf",
28 | "formats":[ "vsprintf(string, mix)" ],
29 | "totalParameters":2,
30 | "parameters": [
31 | { "number":1, "type":"string", "name":"format" },
32 | { "number":2, "type":"mix", "name":"arg", "IsVariadic":false}
33 | ],
34 | "defaultOutput":true,
35 | "returnType":"string",
36 | "defaultStatus":"XSS_ALL"
37 | },
38 | {
39 | "name":"print_r",
40 | "formats":[ "print_r(mix, bool)", "print_r(mix)" ],
41 | "totalParameters":2,
42 | "parameters": [
43 | { "number":1, "type":"mix", "name":"expression" },
44 | { "number":2, "type":"bool", "name":"return", "optional":true, "values": [
45 | {"value":true, "outputs":false },
46 | {"value":false, "outputs":true }
47 | ]
48 | }
49 | ],
50 | "defaultOutput":true,
51 | "returnType":"string",
52 | "defaultStatus":"XSS_ALL"
53 | },
54 | {
55 | "name":"die",
56 | "formats":[ "die(string)", "die(int)" ],
57 | "aliases": [ "exit" ],
58 | "totalParameters":1,
59 | "parameters": [
60 | { "number":1, "type":"mix", "name":"status" }
61 | ],
62 | "defaultOutput":true,
63 | "returnType":"void",
64 | "defaultStatus":"XSS_ALL"
65 | },
66 | {
67 | "name":"var_export",
68 | "formats":[ "var_export(mix)" ],
69 | "totalParameters":2,
70 | "parameters": [
71 | { "number":1, "type":"mix", "name":"expression" },
72 | { "number":2, "type":"bool", "name":"return", "values": [
73 | {"value":true, "outputs":false },
74 | {"value":false, "outputs":true }
75 | ]
76 | }
77 | ],
78 | "defaultOutput":true,
79 | "returnType":"mix",
80 | "defaultStatus":"XSS_ALL"
81 | },
82 | ]
83 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/Taint/ISinkAnalyzer.cs:
--------------------------------------------------------------------------------
1 | using System.IO.IsolatedStorage;
2 | using System.Linq;
3 | using PHPAnalysis.Data;
4 | using PHPAnalysis.Data.CFG;
5 | using PHPAnalysis.Utils;
6 |
7 | namespace PHPAnalysis.Analysis.CFG
8 | {
9 | public interface ISinkAnalyzer
10 | {
11 | bool IsSink(CFGBlock target);
12 | void AnalyzeSink(CFGBlock target, CFGTaintInfo taintInfo);
13 | }
14 |
15 | public sealed class XSSSinkAnalyzer : ISinkAnalyzer
16 | {
17 | private readonly string[] sinks = {
18 | AstConstants.Nodes.Stmt_Echo,
19 | AstConstants.Nodes.Expr_Print,
20 | };
21 |
22 | private readonly IVulnerabilityReporter vulnerabilityReporter;
23 |
24 | public XSSSinkAnalyzer(IVulnerabilityReporter vulnerabilityReporter)
25 | {
26 | Preconditions.NotNull(vulnerabilityReporter, "vulnerabilityReporter");
27 | this.vulnerabilityReporter = vulnerabilityReporter;
28 | }
29 |
30 | public bool IsSink(CFGBlock target)
31 | {
32 | Preconditions.NotNull(target, "target");
33 |
34 | if (target.AstEntryNode == null) { return false; }
35 |
36 | return this.sinks.Contains(target.AstEntryNode.LocalName);
37 | }
38 |
39 | public void AnalyzeSink(CFGBlock target, CFGTaintInfo taintInfo)
40 | {
41 | switch (target.AstEntryNode.LocalName)
42 | {
43 | case AstConstants.Nodes.Stmt_Echo:
44 | AnalyzeEcho(target, taintInfo);
45 | break;
46 | case AstConstants.Nodes.Expr_Print:
47 | break;
48 | default:
49 | break;
50 | }
51 | }
52 |
53 | private void AnalyzeEcho(CFGBlock block, CFGTaintInfo taintInfo)
54 | {
55 | //var xssTaintedVars = taintInfo.In.Where(info => info.Value.XssTaint.TaintTags.Contains(XSSTaint.XSS_ALL))
56 | // .Select(info => info.Key);
57 | //foreach (var taintedVar in xssTaintedVars)
58 | //{
59 | // if (block.AstEntryNode.InnerText.Contains(taintedVar))
60 | // {
61 | // vulnerabilityReporter.ReportVulnerability(block, "XSS");
62 | // }
63 | //}
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/VariableTreeDimension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using PHPAnalysis.Utils;
4 |
5 | namespace PHPAnalysis.Data
6 | {
7 | public sealed class VariableTreeDimension : IEquatable, IDeepCloneable
8 | {
9 | public int Index { get; set; }
10 | public string Key { get; set; }
11 |
12 | //public Variable VariableKey { get; set; }
13 |
14 | public VariableTreeDimension()
15 | {
16 | this.Index = -1;
17 | }
18 |
19 | #region Equality members
20 | public bool Equals(VariableTreeDimension other)
21 | {
22 | if (ReferenceEquals(null, other))
23 | {
24 | return false;
25 | }
26 | if (ReferenceEquals(this, other))
27 | {
28 | return true;
29 | }
30 | return Index == other.Index && string.Equals(Key, other.Key);
31 | }
32 |
33 | public override bool Equals(object obj)
34 | {
35 | if (ReferenceEquals(null, obj))
36 | {
37 | return false;
38 | }
39 | if (ReferenceEquals(this, obj))
40 | {
41 | return true;
42 | }
43 | return obj is VariableTreeDimension && Equals((VariableTreeDimension) obj);
44 | }
45 |
46 | public override int GetHashCode()
47 | {
48 | unchecked
49 | {
50 | return (Index * 397) ^ (Key != null ? Key.GetHashCode() : 0);
51 | }
52 | }
53 |
54 | public static bool operator ==(VariableTreeDimension left, VariableTreeDimension right)
55 | {
56 | return Equals(left, right);
57 | }
58 |
59 | public static bool operator !=(VariableTreeDimension left, VariableTreeDimension right)
60 | {
61 | return !Equals(left, right);
62 | }
63 | #endregion
64 |
65 | public VariableTreeDimension DeepClone()
66 | {
67 | return new VariableTreeDimension() {
68 | Index = this.Index,
69 | Key = this.Key
70 | };
71 | }
72 |
73 | public override string ToString()
74 | {
75 | return Key ?? Index.ToString(CultureInfo.InvariantCulture);
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/XmlHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Xml;
7 |
8 | namespace PHPAnalysis.Parsing
9 | {
10 | public static class XmlHelper
11 | {
12 | public static bool ContainsIllegalCharacters(string toCheck)
13 | {
14 | try
15 | {
16 | XmlConvert.VerifyXmlChars(toCheck);
17 | return true;
18 | }
19 | catch (XmlException)
20 | {
21 | return false;
22 | }
23 | }
24 |
25 | //The outline for this method has been found on stack overflow: http://stackoverflow.com/questions/8331119/escape-invalid-xml-characters-in-c-sharp
26 | ///
27 | /// Method to replace Illegal XML characters, such that we can actually parse the files and analyse them!
28 | ///
29 | /// The string that has been stripped for illegal characters
30 | /// XML string with illegal characters
31 | public static string ReplaceIllegalXmlCharacters(string inputString)
32 | {
33 | if (string.IsNullOrWhiteSpace(inputString))
34 | {
35 | return inputString;
36 | }
37 |
38 | var inputLength = inputString.Length;
39 | var output = new StringBuilder();
40 | for (int i = 0; i < inputLength; i++)
41 | {
42 | if (XmlConvert.IsXmlChar(inputString[i]))
43 | {
44 | output.Append(inputString[i]);
45 | }
46 | else if (i + 1 < inputLength && XmlConvert.IsXmlSurrogatePair(inputString[i + 1], inputString[i]))
47 | {
48 | output.Append(inputString[i]);
49 | i++;
50 | output.Append(inputString[i]);
51 | }
52 | else
53 | {
54 | Debug.WriteLine("Found invalid XML character! Converting to HEX value with 0x prepended! The char was: {0}", inputString[i]);
55 | var utf8EndoEncoding = new UTF8Encoding();
56 | byte[] encoded = utf8EndoEncoding.GetBytes(inputString[i].ToString());
57 | output.Append("0x" + BitConverter.ToString(encoded));
58 | }
59 | }
60 | return output.ToString();
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/AST/MetricVisitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml;
3 | using PHPAnalysis.Data;
4 | using PHPAnalysis.Parsing.AstTraversing;
5 |
6 | namespace PHPAnalysis.Analysis.AST
7 | {
8 | public class MetricVisitor : IXmlVisitor
9 | {
10 | public int TotalNodes { get; private set; }
11 | public int EchoStatements { get; private set; }
12 | public int PotentialSQLQueries { get; private set; }
13 | public int IncludeStatements { get; private set; }
14 | public int Classes { get; private set; }
15 | public int Methods { get; private set; }
16 | public int Functions { get; private set; }
17 | public int Gotos { get; private set; }
18 |
19 | public void TraverseStart(object sender, XmlStartTraverseEventArgs e) { }
20 |
21 | public void EnteringNode(object sender, XmlTraverseEventArgs e)
22 | {
23 | XmlNode node = e.Node;
24 | TotalNodes++;
25 | switch (node.LocalName)
26 | {
27 | case "Stmt_Echo":
28 | EchoStatements++;
29 | break;
30 | case "#text":
31 | StringLiteral(node);
32 | break;
33 | case AstConstants.Nodes.Stmt_Function:
34 | Functions++;
35 | break;
36 | case AstConstants.Nodes.Stmt_ClassMethod:
37 | Methods++;
38 | break;
39 | case AstConstants.Nodes.Stmt_Class:
40 | Classes++;
41 | break;
42 | case "Expr_Include":
43 | IncludeStatements++;
44 | break;
45 | case AstConstants.Nodes.Stmt_Goto:
46 | Gotos++;
47 | break;
48 | }
49 | }
50 |
51 | public void LeavingNode(object sender, XmlTraverseEventArgs e) { }
52 |
53 | public void TraverseEnd(object sender, XmlEndTraverseEventArgs e) { }
54 |
55 | private void StringLiteral(XmlNode node)
56 | {
57 | // Poor query recognizer.. But whatevs
58 | if (node.InnerText.StartsWith("select ", StringComparison.OrdinalIgnoreCase) ||
59 | node.InnerText.StartsWith("update ", StringComparison.OrdinalIgnoreCase) ||
60 | node.InnerText.StartsWith("delete ", StringComparison.OrdinalIgnoreCase))
61 | {
62 | PotentialSQLQueries++;
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.PluginInterface/PHPAnalysis.PluginInterface.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {789EEAEE-8017-4C6B-8A78-F56B7E599652}
8 | Library
9 | Properties
10 | PHPAnalysis.PluginInterface
11 | PHPAnalysis.PluginInterface
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
53 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/CFG/ScopeHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using PHPAnalysis.Utils;
7 |
8 | namespace PHPAnalysis.Data.CFG
9 | {
10 | ///
11 | /// Manages the different scopes (loop, if, switch, ..) were currently in, when traversing the CFG.
12 | ///
13 | internal sealed class ScopeHandler
14 | {
15 | private readonly Stack allScopes = new Stack();
16 | private readonly Stack ifScopes = new Stack();
17 | ///
18 | /// Contains loopscopes. The stack can contain both actual loop (while, for, ..) and switch cases.
19 | /// Switch cases are regarded as a special loop, since both break and continue works with them.
20 | ///
21 | private readonly Stack loopScopes = new Stack();
22 | public AbstractScope CurrentScope { get { return allScopes.Peek(); } }
23 | public bool IsInLoop
24 | {
25 | get
26 | {
27 | return loopScopes.Any();
28 | }
29 | }
30 |
31 | public bool IsInnermostScopeALoop
32 | {
33 | get
34 | {
35 | if (loopScopes.IsEmpty())
36 | {
37 | return false;
38 | }
39 | return allScopes.Peek() == loopScopes.Peek();
40 | }
41 | }
42 |
43 | public void PushIfStmt(IfScope ifblock)
44 | {
45 | this.ifScopes.Push(ifblock);
46 | this.allScopes.Push(ifblock);
47 | }
48 | public IfScope PopIfStmt()
49 | {
50 | this.allScopes.Pop();
51 | return this.ifScopes.Pop();
52 | }
53 | public IfScope GetIfStmt()
54 | {
55 | return this.ifScopes.Peek();
56 | }
57 |
58 | public void EnterLoop(AbstractScope loopBlock)
59 | {
60 | this.loopScopes.Push(loopBlock);
61 | this.allScopes.Push(loopBlock);
62 | }
63 | public AbstractScope LeaveLoop()
64 | {
65 | this.allScopes.Pop();
66 | return this.loopScopes.Pop();
67 | }
68 | public AbstractScope GetInnermostLoop()
69 | {
70 | return this.loopScopes.Peek();
71 | }
72 |
73 | public AbstractScope GetLoopScope(int scopesToSkip)
74 | {
75 | return loopScopes.ElementAt(scopesToSkip);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Parsing/CFGCreator_ClassTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NUnit.Framework;
3 | using PHPAnalysis.Tests.Analysis;
4 | using PHPAnalysis.Analysis.AST;
5 | using PHPAnalysis.Parsing;
6 | using PHPAnalysis.Data.CFG;
7 | using QuickGraph.Algorithms;
8 | using System.Linq;
9 | using PHPAnalysis.Data;
10 | using PHPAnalysis.Parsing.AstTraversing;
11 | using PHPAnalysis.Tests.TestUtils;
12 |
13 | namespace PHPAnalysis.Tests
14 | {
15 | [TestFixture]
16 | public class CFGCreator_ClassTests : ConfigDependentTests
17 | {
18 | [TestCase(@"")]
30 | [TestCase(@"")]
40 | public void CFGCreator_RootAndExitIsStmtClassMethod(string phpcode)
41 | {
42 | var extract = ParseAndExtract(phpcode);
43 | foreach (var @class in extract.Classes)
44 | {
45 | foreach (var method in @class.Methods)
46 | {
47 | var ast = method.AstNode;
48 | var traverser = new XmlTraverser();
49 | var cfgcreator = new CFGCreator();
50 | traverser.AddVisitor(cfgcreator);
51 | traverser.Traverse(ast);
52 |
53 | var graph = cfgcreator.Graph;
54 |
55 | //Root assertions
56 | Assert.AreEqual(AstConstants.Nodes.Stmt_ClassMethod, graph.Vertices.First().ToString());
57 | graph.AssertInEdges(graph.Vertices.First(), 0, "Entry node - in edges");
58 | graph.AssertOutEdges(graph.Vertices.First(), 1, "Entry node - out edges");
59 | Assert.AreEqual(true, graph.Vertices.First().IsRoot);
60 |
61 | //Leaf assertions
62 | graph.AssertOutEdges(graph.Vertices.ElementAt(1), 0, "Exit node - out edges");
63 | Assert.AreEqual(true, graph.Vertices.ElementAt(1).IsLeaf);
64 | }
65 | }
66 | }
67 |
68 | private ClassAndFunctionExtractor ParseAndExtract(string php)
69 | {
70 | return PHPParseUtils.ParseAndIterate(php, Config.PHPSettings.PHPParserPath);
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Parsing/FileParser.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Xml;
3 | using PHPAnalysis.Annotations;
4 | using PHPAnalysis.Utils;
5 | using System.Text;
6 | using System;
7 |
8 | namespace PHPAnalysis.Parsing
9 | {
10 | public sealed class FileParser
11 | {
12 | private string _parserPath;
13 | public string ParserPath
14 | {
15 | get
16 | {
17 | return _parserPath.StartsWith("\"") ? _parserPath
18 | : "\"" + _parserPath + "\"";
19 | }
20 | set { this._parserPath = value; }
21 | }
22 |
23 | public FileParser(string parserPath)
24 | {
25 | Preconditions.NotNull(parserPath, "parserPath");
26 |
27 | this.ParserPath = parserPath;
28 | }
29 |
30 | public XmlDocument ParsePHPFile(string pathToFile)
31 | {
32 | Preconditions.NotNull(pathToFile, "pathToFile");
33 |
34 | var xmlDocument = new XmlDocument();
35 |
36 | var process = CreateParseProcess(pathToFile);
37 | process.Start();
38 |
39 | string tmp;
40 | var finalOutput = new StringBuilder ();
41 | while ((tmp = process.StandardOutput.ReadLine ()) != null)
42 | {
43 | tmp = XmlHelper.ReplaceIllegalXmlCharacters(tmp);
44 | finalOutput.AppendLine (tmp);
45 | }
46 | xmlDocument.LoadXml(finalOutput.ToString());
47 | return xmlDocument;
48 | }
49 |
50 | private Process CreateParseProcess([NotNull] string fileToParse)
51 | {
52 | string arguments = this.ParserPath + " parse ";
53 |
54 | fileToParse = fileToParse.StartsWith("\"") ? fileToParse
55 | : "\"" + fileToParse + "\"";
56 | arguments += fileToParse;
57 |
58 | var processStartInfo = new ProcessStartInfo() {
59 | FileName = "php",
60 | Arguments = arguments,
61 | UseShellExecute = false,
62 | RedirectStandardOutput = true,
63 | CreateNoWindow = true
64 | };
65 | var process = new Process() {
66 | StartInfo = processStartInfo
67 | };
68 | return process;
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.Tests/Analysis/ReachDefTests.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using NUnit.Framework;
4 | using PHPAnalysis.Analysis.CFG;
5 | using PHPAnalysis.Analysis.CFG.Traversal;
6 | using PHPAnalysis.Parsing;
7 | using PHPAnalysis.Tests.TestUtils;
8 | using PHPAnalysis.Utils;
9 | using PHPAnalysis.Utils.XmlHelpers;
10 |
11 | namespace PHPAnalysis.Tests.Analysis
12 | {
13 | [TestFixture]
14 | class ReachDefTests : ConfigDependentTests
15 | {
16 | [Test, Ignore("Not implemented")]
17 | public void IfElseVarDefTest()
18 | {
19 | const string php = @"() { 4, 8 };
36 | var outLineNumbers = new List() { 4, 8, 10 };
37 |
38 | foreach (var block in reachDef.ReachingSetDictionary)
39 | {
40 | if (block.Key.AstEntryNode != null && block.Key.AstEntryNode.Name == "node:Expr_Assign")
41 | {
42 | if (block.Value.DefinedInVars.Any())
43 | {
44 | int ins = AstNode.GetStartLine(block.Value.DefinedInVars.Values.First().Info.Block.AstEntryNode);
45 | inLineNumbers.RemoveAll(x => ins == x);
46 | }
47 | if (block.Value.DefinedOutVars.Any())
48 | {
49 | int outs = AstNode.GetStartLine(block.Value.DefinedOutVars.Values.First().Info.Block.AstEntryNode);
50 | outLineNumbers.RemoveAll(x => x == outs);
51 | }
52 | }
53 | }
54 |
55 | Assert.IsTrue(inLineNumbers.IsEmpty(), "The InLineNumbers are incorrect!");
56 | Assert.IsTrue(outLineNumbers.IsEmpty(), "The OutLineNumbers are incorrect!");
57 | }
58 |
59 | private CFGCreator ParseAndBuildCFG(string php)
60 | {
61 | return PHPParseUtils.ParseAndIterate(php, Config.PHPSettings.PHPParserPath);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Utils/Extensions/CollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Immutable;
4 | using System.Linq;
5 | using System.Runtime.CompilerServices;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Threading.Tasks;
9 | using PHPAnalysis.Data;
10 | using YamlDotNet.Core.Tokens;
11 |
12 | namespace PHPAnalysis.Utils
13 | {
14 | public static class CollectionExtensions
15 | {
16 | public static void AddRange(this ICollection collection, IEnumerable toAdd)
17 | {
18 | Preconditions.NotNull(toAdd, "toAdd");
19 | if (collection.IsReadOnly) { throw new NotSupportedException(); }
20 |
21 | foreach (var element in toAdd)
22 | {
23 | collection.Add(element);
24 | }
25 | }
26 |
27 | public static void AddRange(this IDictionary collection, IEnumerable> toAdd)
28 | {
29 | Preconditions.NotNull(collection, "collection");
30 | if (collection.IsReadOnly)
31 | {
32 | throw new NotSupportedException();
33 | }
34 |
35 | foreach (var keyValuePair in toAdd)
36 | {
37 | collection.Add(keyValuePair);
38 | }
39 | }
40 |
41 | public static bool DictionaryEquals(
42 | this IDictionary first, IDictionary second,
43 | IEqualityComparer comparer = null)
44 | {
45 | if (ReferenceEquals(first, second)) { return true; }
46 | if (first == null || second == null) { return false; }
47 | if (first.Count != second.Count) { return false; }
48 |
49 | comparer = comparer ?? EqualityComparer.Default;
50 |
51 | foreach (var keyValuePair in first)
52 | {
53 | TValue matchingValue;
54 | if (!second.TryGetValue(keyValuePair.Key, out matchingValue) ||
55 | !comparer.Equals(keyValuePair.Value, matchingValue))
56 | {
57 | return false;
58 | }
59 | }
60 | return true;
61 | }
62 |
63 | public static ImmutableStack ToImmutableStack(this Stack mutableStack)
64 | {
65 | Preconditions.NotNull(mutableStack, "mutableStack");
66 |
67 | var result = ImmutableStack.Empty;
68 |
69 | for (int i = mutableStack.Count - 1; i >= 0; i--)
70 | {
71 | result = result.Push(mutableStack.ElementAt(i));
72 | }
73 | return result;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Components/ComponentImporter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.Immutable;
3 | using System.ComponentModel.Composition;
4 | using System.ComponentModel.Composition.Hosting;
5 | using System.Reflection;
6 | using System.Reflection.Emit;
7 | using System.Runtime.InteropServices;
8 | using PHPAnalysis.Analysis;
9 | using PHPAnalysis.Analysis.CFG.Taint;
10 | using PHPAnalysis.Annotations;
11 | using PHPAnalysis.Parsing.AstTraversing;
12 | using PHPAnalysis.Utils;
13 |
14 | namespace PHPAnalysis.Components
15 | {
16 | internal sealed class ComponentImporter
17 | {
18 | [ImportMany(typeof(IXmlVisitor)), UsedImplicitly]
19 | private IEnumerable AstTraversers { get; set; }
20 |
21 | [ImportMany(typeof(IVulnerabilityReporter)), UsedImplicitly]
22 | private IEnumerable VulnerabilityReporters { get; set; }
23 |
24 | [ImportMany(typeof(ITaintProvider)), UsedImplicitly]
25 | private IEnumerable TaintProviders { get; set; }
26 |
27 | [ImportMany(typeof(IBlockAnalyzerComponent)), UsedImplicitly]
28 | private IEnumerable BlockAnalyzers { get; set; }
29 |
30 | [ImportMany(typeof(IAnalysisStartingListener)), UsedImplicitly]
31 | private IEnumerable AnalysisStartingListener { get; set; }
32 |
33 | [ImportMany(typeof(IAnalysisEndedListener)), UsedImplicitly]
34 | private IEnumerable AnalysisEndedListeners { get; set; }
35 |
36 | public ComponentContainer ImportComponents(string componentPath)
37 | {
38 | var catalog = new AggregateCatalog();
39 |
40 | catalog.Catalogs.Add(new DirectoryCatalog(componentPath));
41 | catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
42 |
43 | var container = new CompositionContainer(catalog);
44 |
45 | container.ComposeParts(this);
46 |
47 | return CreateComponentContainer();
48 | }
49 |
50 | private ComponentContainer CreateComponentContainer()
51 | {
52 | var componentContainer = new ComponentContainer();
53 |
54 | componentContainer.AstVisitors.AddRange(this.AstTraversers);
55 | componentContainer.VulnerabilityReporters.AddRange(this.VulnerabilityReporters);
56 | componentContainer.BlockAnalyzers.AddRange(this.BlockAnalyzers);
57 | componentContainer.TaintProviders.AddRange(this.TaintProviders);
58 | componentContainer.AnalysisStartingListeners.AddRange(this.AnalysisStartingListener);
59 | componentContainer.AnalysisEndedListeners.AddRange(this.AnalysisEndedListeners);
60 |
61 | return componentContainer;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25123.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PHPAnalysis", "PHPAnalysis\PHPAnalysis.csproj", "{04511BB1-4881-44F2-B07D-FD88CEDE53CB}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PHPAnalysis.Tests", "PHPAnalysis.Tests\PHPAnalysis.Tests.csproj", "{19467754-4DA7-4531-BB51-8CC024A0CCB3}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WordPress.Plugin", "WordPress.Plugin\WordPress.Plugin.csproj", "{B27C2212-E33B-4BEF-9FB7-62113A3682C6}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5B98AE9F-4B39-426F-B5D5-DF549FDE4327}"
13 | ProjectSection(SolutionItems) = preProject
14 | Performance1.psess = Performance1.psess
15 | EndProjectSection
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileWriter.Plugin", "FileWriter.Plugin\FileWriter.Plugin.csproj", "{6EBE6355-A353-4614-A507-EB251282541B}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {04511BB1-4881-44F2-B07D-FD88CEDE53CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {04511BB1-4881-44F2-B07D-FD88CEDE53CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {04511BB1-4881-44F2-B07D-FD88CEDE53CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {04511BB1-4881-44F2-B07D-FD88CEDE53CB}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {19467754-4DA7-4531-BB51-8CC024A0CCB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {19467754-4DA7-4531-BB51-8CC024A0CCB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {19467754-4DA7-4531-BB51-8CC024A0CCB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {19467754-4DA7-4531-BB51-8CC024A0CCB3}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {B27C2212-E33B-4BEF-9FB7-62113A3682C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {B27C2212-E33B-4BEF-9FB7-62113A3682C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {B27C2212-E33B-4BEF-9FB7-62113A3682C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {B27C2212-E33B-4BEF-9FB7-62113A3682C6}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {6EBE6355-A353-4614-A507-EB251282541B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {6EBE6355-A353-4614-A507-EB251282541B}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {6EBE6355-A353-4614-A507-EB251282541B}.Release|Any CPU.ActiveCfg = Release|Any CPU
40 | {6EBE6355-A353-4614-A507-EB251282541B}.Release|Any CPU.Build.0 = Release|Any CPU
41 | EndGlobalSection
42 | GlobalSection(SolutionProperties) = preSolution
43 | HideSolutionNode = FALSE
44 | EndGlobalSection
45 | EndGlobal
46 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/AST/IncludeResolver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.Remoting.Contexts;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Threading.Tasks;
9 | using System.Xml;
10 | using PHPAnalysis.Data;
11 | using PHPAnalysis.Utils;
12 | using PHPAnalysis.Utils.XmlHelpers;
13 | using File = PHPAnalysis.Data.File;
14 |
15 | namespace PHPAnalysis.Analysis.AST
16 | {
17 | public interface IIncludeResolver
18 | {
19 | bool TryResolveInclude(XmlNode node, out File path);
20 | }
21 |
22 | public sealed class IncludeResolver : IIncludeResolver
23 | {
24 | // TODO - Currently we're just looking at the filename and see if we can resolve it.
25 | // We should at least try to use the path if it is present.
26 | private readonly List _projectFiles;
27 | public IncludeResolver(ICollection projectFiles)
28 | {
29 | Preconditions.NotNull(projectFiles, "projectFiles");
30 | _projectFiles = new List(projectFiles);
31 | }
32 |
33 | ///
34 | /// Matching last string in include expression against all files and select the first match.
35 | /// This is incredibly basic and not necessarily correct. The path is ignored and there could be multiple files
36 | /// with the same name.
37 | ///
38 | public bool TryResolveInclude(XmlNode node, out File path)
39 | {
40 | Preconditions.NotNull(node, "node");
41 | Preconditions.IsTrue(node.Name == AstConstants.Node + ":" + AstConstants.Nodes.Expr_Include, "Given node was not an include node. It was " + node.Name, "node");
42 |
43 | string includeString = "";
44 |
45 | node.IterateAllNodes(xmlNode =>
46 | {
47 | if (xmlNode.LocalName != AstConstants.Nodes.Scalar_String)
48 | return false;
49 | includeString = xmlNode.GetSubNode(AstConstants.Subnode + ":" + AstConstants.Subnodes.Value).InnerText;
50 | return true;
51 | });
52 |
53 | string fileName = Path.GetFileName(includeString);
54 |
55 | return TryGetFile(fileName, out path);
56 | }
57 |
58 | private bool TryGetFile(string fileName, out File file)
59 | {
60 | var matchingFiles = _projectFiles.Where(projectFile => projectFile.Name == fileName).ToList();
61 |
62 | if (!matchingFiles.Any() || matchingFiles.Count > 1)
63 | {
64 | file = null;
65 | return false;
66 | }
67 | file = matchingFiles.Single();
68 | return true;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Provider/Keys.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PHPAnalysis
4 | {
5 | public static class Keys
6 | {
7 | public static class PHPDefinitionJSONKeys
8 | {
9 | public static class FunctionSpecificationArrays
10 | {
11 | public const string Sources = "SourceFuncs";
12 | public const string XssSanitizer = "XSSSanitizersFuncs";
13 | public const string SqlSanitizer = "SQLSanitizersFuncs";
14 | public const string XssSinks = "XssSinkFuncs";
15 | public const string SqlSinks = "SqlSinksFuncs";
16 | public const string CondSinks = "ConditionSanitizerFuncs";
17 | public const string StoredVulnProviders = "StoredVulnerabilityProviders";
18 | }
19 |
20 | public static class GeneralKeys
21 | {
22 | public const string Name = "name";
23 | public const string Type = "type";
24 | public const string Formats = "formats";
25 | public const string Aliases = "aliases";
26 | public const string ParameterCount = "totalParameters";
27 | public const string Parameters = "parameters";
28 | public const string DefaultStatusCode = "defaultStatus";
29 | public const string OutputsPerDefault = "defaultOutput";
30 | public const string ReturnType = "returnType";
31 | public const string XssTaint = "XSSTaint";
32 | public const string SqlTaint = "SQLTaint";
33 | public const string Classnames = "classnames";
34 | }
35 |
36 | public static class ParameterJSONKeys
37 | {
38 | public const string ParameterNumber = "number";
39 | public const string ParameterType = "type";
40 | public const string ParameterName = "name";
41 | public const string ParameterIsOptional = "optional";
42 | public const string ParameterValues = "values";
43 | public const string ParameterCanCreateHole = "can_be_vulnerable";
44 | public const string ParameterIsVariadic = "IsVariadic";
45 | public const string ParameterIsReturnValue = "isReturnValue";
46 | }
47 |
48 | public static class ValuesJSONKeys
49 | {
50 | public const string Value = "value";
51 | public const string IsOutputing = "outputs";
52 | public const string StatusCode = "outputStatus";
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Eir
2 | PHP vulnerability scanner written in C#. Why C#? Because! That's why!
3 |
4 | ### Requirements
5 | * .NET 4.5 or Mono 3.12.0-1
6 | * PHP >= 5.3
7 | * Good intentions
8 |
9 | ### Getting it running
10 | 1. Download project
11 | 2. Install [Composer](https://getcomposer.org/) (for the PHP parser)
12 | 2.1. From the PHPAnalysis-parser folder run composer update in terminal
13 | 2.2. Make sure all dependencies are correctly installed.
14 | 3. Fix the config.yml
15 | 4. Run the application
16 |
17 | #### Getting it running on Ubuntu 16.04
18 |
19 | 1. Install PHP
20 | `sudo apt install php7.0-cli`
21 | 2. Make sure you have the XML library
22 | `sudo apt install php-xml`
23 | 3. Install Composer
24 | `sudo apt install composer`
25 | 4. [Install Mono](http://www.mono-project.com/download/#download-lin)
26 | `sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF`
27 | `echo "deb http://download.mono-project.com/repo/ubuntu xenial main" | sudo tee /etc/apt/sources.list.d/mono-official.list`
28 | `sudo apt-get update`
29 | `sudo apt-get install mono-devel`
30 | 5. Install NuGet
31 | `sudo apt install nuget`
32 | 6. Install PHPAnalysis-parser dependencies with Composer
33 | `composer install`
34 | `composer update`
35 | 6. Restore NuGet packages for PHPAnalysis solution
36 | `nuget restore`
37 | 7. Build solution
38 | `msbuild ./PHPAnalysis.sln`
39 | 8. Update the _config.yml_ file with correct settings
40 | - Remember to reference the _FileWriter_ and/or the _WordPress_ dll files if needed
41 | 9. Run the analysis
42 | `mono PHPAnalysis.exe --all --target ./myPhpFile.php`
43 |
44 |
45 | ### Errors
46 |
47 | A list of possible errors you might experience while setting up/using this application and possible ways to mitigate them.
48 |
49 | -----------------------
50 | #### "Parser error: Syntax error, unexpected EOF on line xx"
51 | (PHP project/parser throws this error)
52 |
53 | Make sure that there is no syntactical errors in your PHP code. This scanner does not handle syntax errors very well.
54 | If the syntax is correct, try updating to the newest version of PHP.
55 |
56 | -----------------------
57 | #### CONFIGURATION ERROR
58 | Make sure the configuration file (`config.yml`) is present and has the correct format. It should look like the `config-template.yml` file.
59 | Standard rules for Yaml files apply.
60 |
61 | Common error:
62 | Using tabs instead of spaces. Indentation should be done using spaces.
63 |
64 | -----------------------
65 | ### External dependencies
66 |
67 | - [CommandLineParser](https://commandline.codeplex.com/) 1.9.71
68 | - [Newtonsoft.Json](https://www.newtonsoft.com/json) 10.0.0
69 | - [PHP-Parser](https://github.com/nikic/PHP-Parser) 1.1.0
70 | - [QuickGraph](https://quickgraph.codeplex.com/) 3.6.61119.7
71 | - [Microsoft.Bcl.Immutable](https://www.nuget.org/packages/Microsoft.Bcl.Immutable) 1.0.34
72 | - [YamlDotNet](https://github.com/aaubry/YamlDotNet) 4.2.2
73 |
74 |
75 | - [Moq](https://github.com/Moq/moq4) 4.7.127
76 | - [NUnit](http://www.nunit.org/) 3.8.1
77 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Data/PHP/Parameter.cs:
--------------------------------------------------------------------------------
1 | using System.Xml;
2 | using PHPAnalysis.Utils;
3 |
4 | namespace PHPAnalysis.Data.PHP
5 | {
6 | public class Parameter
7 | {
8 | public XmlNode AstNode { get; private set; }
9 | public string Name { get; set; }
10 | public bool ByReference { get; set; }
11 | public bool IsVariadic { get; set; }
12 | public bool IsOptional { get; set; }
13 | public bool IsReturn { get; set; }
14 | public string DefaultValue { get; set;}
15 | ///
16 | /// This property indicates whether this parameter can create a security issue through the input.
17 | /// An example is the mysqli_query($dblink, $query). The dblink cannot create an issue, however the $query can.
18 | ///
19 | /// true if this instance can create a security issue; otherwise false.
20 | public bool IsSensitive { get; set; }
21 |
22 | //public string DefaultValue
23 | //{
24 | // get
25 | // {
26 | // var defaultNodeName = AstConstants.SubNode + ":" + AstConstants.Subnodes.Default;
27 | // var val = AstNode.GetSubNode(defaultNodeName);
28 | // return val.Value;
29 | // }
30 | //}
31 |
32 | public Parameter(bool optional = false, bool vulnerable = true,
33 | bool isVariadic = false, bool byRef = false, string defaultValue = "", bool isReturn = false)
34 | {
35 | this.ByReference = byRef;
36 | this.IsVariadic = isVariadic;
37 | this.IsOptional = optional;
38 | this.IsSensitive = vulnerable;
39 | this.AstNode = null;
40 | this.DefaultValue = defaultValue;
41 | this.IsReturn = isReturn;
42 | }
43 |
44 | public Parameter(string name, bool optional = false, bool vulnerable = true, bool variadic = false,
45 | bool byRef = false, string defaultValue = "", bool isReturn = false) : this(optional, vulnerable, variadic, byRef, defaultValue, isReturn)
46 | {
47 | this.Name = name;
48 | }
49 |
50 | public Parameter(string name, XmlNode node, bool optional = false, bool vulnerable = true, bool variadic = false,
51 | bool byRef = false, string defaultValue = "", bool isReturn = false) : this(name, optional, vulnerable, variadic, byRef, defaultValue, isReturn)
52 | {
53 | Preconditions.NotNull(node, "node");
54 | this.AstNode = node;
55 | }
56 |
57 | public Parameter(XmlNode node)
58 | {
59 | //TODO: Could extract stuff from the param, and set the properties from the ast node
60 | //-||-: or the getters could be implemented to check if the property is null or empty and if it is, then it should extract and return
61 | Preconditions.NotNull(node, "node");
62 | this.AstNode = node;
63 | }
64 |
65 | public override string ToString()
66 | {
67 | return string.Format("{0}{1}{2}{3}",
68 | ByReference ? "&" : "",
69 | IsVariadic ? "..." : "",
70 | Name,
71 | IsOptional ? " = ": "");
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Configuration/Config.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using System.Text;
4 | using PHPAnalysis.Annotations;
5 | using PHPAnalysis.Utils;
6 | using PHPAnalysis.Utils.Exceptions;
7 | using YamlDotNet.Core;
8 | using YamlDotNet.Serialization;
9 |
10 | namespace PHPAnalysis.Configuration
11 | {
12 | public sealed class Config
13 | {
14 | public PHPConfiguration PHPSettings { get; private set; }
15 | public GraphConfiguration GraphSettings { get; private set; }
16 | public ComponentConfiguration ComponentSettings { get; private set; }
17 | public FuncSpecConfiguration FuncSpecSettings { get; private set; }
18 |
19 | private Config(ConfigurationMutable config)
20 | {
21 | Preconditions.NotNull(config, "config");
22 |
23 | PHPSettings = new PHPConfiguration(config.PHPConfiguration.PHPPath, config.PHPConfiguration.PHPParsePath, config.PHPConfiguration.PHPExts);
24 | GraphSettings = new GraphConfiguration(config.GraphConfiguration.GraphvizPath, config.GraphConfiguration.GraphvizArguments);
25 | ComponentSettings = new ComponentConfiguration(config.ComponentSettings.ComponentFolder, config.ComponentSettings.IncludeComponents);
26 | FuncSpecSettings = new FuncSpecConfiguration(config.FuncSpecSettings.PHPSpecs, config.FuncSpecSettings.ExtensionSpecs);
27 | }
28 |
29 | public static Config ReadConfiguration(string configPath)
30 | {
31 | Preconditions.NotNull(configPath, "configPath");
32 | var configInput = new StringReader(File.ReadAllText(configPath));
33 | var deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().Build();
34 |
35 | try
36 | {
37 | var config = deserializer.Deserialize(configInput);
38 | return new Config(config);
39 | }
40 | catch (SyntaxErrorException e)
41 | {
42 | throw new ConfigurationParseException("Could not parse config file: " + configPath, e);
43 | }
44 | }
45 |
46 | public override string ToString()
47 | {
48 | var sb = new StringBuilder();
49 | sb.AppendLine("PHP Settings: ");
50 | sb.AppendLine(PHPSettings.ToString());
51 | sb.AppendLine("Graph Settings: ");
52 | sb.AppendLine(GraphSettings.ToString());
53 | sb.AppendLine("Component Settings:");
54 | sb.AppendLine(ComponentSettings.ToString());
55 | return sb.ToString();
56 | }
57 |
58 | [UsedImplicitly]
59 | internal sealed class ConfigurationMutable
60 | {
61 | [YamlMember(Alias = "php-settings")]
62 | public PHPConfigurationMutable PHPConfiguration { get; set; }
63 |
64 | [YamlMember(Alias = "graph-settings")]
65 | public GraphConfigurationMutable GraphConfiguration { get; set; }
66 |
67 | [YamlMember(Alias = "component-settings")]
68 | public ComponentConfigurationMutable ComponentSettings { get; set; }
69 |
70 | [YamlMember(Alias = "func-spec-settings")]
71 | public FuncSpecConfigurationMutable FuncSpecSettings { get; set; }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/FunctionSpecs/StoredSQLProviders/databaseProviders.json:
--------------------------------------------------------------------------------
1 | {
2 | "StoredVulnerabilityProviders":
3 | [
4 | {
5 | "name":"mysqli_result->fetch_array",
6 | "formats":[ "mysqli_result->fetch_array(int)", "mysqli_result->fetch_array()" ],
7 | "totalParameters":1,
8 | "parameters": [
9 | { "number":1, "name":"resulttype", "type":"int", "optional":true }
10 | ],
11 | "returnType":"mix"
12 | },
13 | {
14 | "name":"mysqli_result->fetch_assoc",
15 | "formats": [ "mysqli_result->fetch_assoc()" ],
16 | "totalParameters":0,
17 | "parameters": [],
18 | "returnType":"array"
19 | },
20 | {
21 | "name":"SQLiteResult->fetch",
22 | "formats": [ "SQLiteResult->fetch(int, bool)", "SQLiteResult->fetch(int)" ],
23 | "aliases": [ "SQLiteUnbuffered->fetch" ],
24 | "totalParameters":2,
25 | "parameters": [
26 | { "number":1, "name":"result_type", "type":"int", "optional":true },
27 | { "number":2, "name":"decode_binary", "type":"bool", "optional":true }
28 | ],
29 | "returnType":"array"
30 | },
31 | {
32 | "name":"SQLiteResult->fetchObject",
33 | "formats": [ "SQLiteResult->fetchObject(string, array, bool)", "SQLiteResult->fetchObject(string, array)", "SQLiteResult->fetchObject(string)" ],
34 | "aliases": [ "SQLiteUnbuffered->fetchObject" ],
35 | "totalParameters":3,
36 | "parameters":[
37 | { "number":1, "name":"class_name", "type":"string" },
38 | { "number":2, "name":"ctor_params", "type":"array", "optional":true },
39 | { "number":3, "name":"decode_binary", "type":"bool", "optional":true }
40 | ],
41 | "returnType":"object"
42 | },
43 | {
44 | "name":"SQLiteResult->fetchSingle",
45 | "formats": [ "SQLiteResult->fetchSingle(bool)", "SQLiteResult->fetchSingle()" ],
46 | "aliases": [ "SQLiteUnbuffered->fetchSingle", "SQLiteResult::fetchString" ],
47 | "totalParameters":1,
48 | "parameters": [
49 | { "number":1, "name":"decode_binary", "type":"bool", "optional":true }
50 | ],
51 | "returnType":"string"
52 | },
53 | {
54 | "name":"mysqli_result->fetch_all",
55 | "formats": [ "mysqli_result->fetch_all(int)", "mysqli_result->fetch_all()" ],
56 | "totalParameters":1,
57 | "parameters":[
58 | { "number":1, "name":"result_type", "type":"int", "optional":true }
59 | ],
60 | "returnType":"mix"
61 | },
62 | {
63 | "name":"mysqli_result->fetch_field",
64 | "formats": [ "mysqli_result->fetch_field()" ],
65 | "totalParameters":0,
66 | "parameters": [],
67 | "returnType":"object"
68 | },
69 | {
70 | "name":"mysqli_result->fetch_fields",
71 | "formats": [ "mysqli_result->fetch_fields()" ],
72 | "totalParameters":0,
73 | "parameters":[],
74 | "returnType":"array"
75 | },
76 | {
77 | "name":"mysqli_result->fetch_object",
78 | "formats": [ "mysqli_result->fetch_object(string, array)", "mysqli_result->fetch_object(string)" ],
79 | "totalParameters":2,
80 | "parameters": [
81 | { "number":1, "name":"class_name", "type":"string", "optional":true },
82 | { "number":2, "name":"stdClass", "type":"array", "optional":true }
83 | ],
84 | "returnType":"object"
85 | },
86 | {
87 | "name":"mysqli_result->fetch_row",
88 | "formats": [ "mysqli_result->fetch_row()" ],
89 | "totalParameters":0,
90 | "parameters":[],
91 | "returnType":"mix"
92 | }
93 | ]
94 | }
--------------------------------------------------------------------------------
/PHPAnalysis/PHPAnalysis/Analysis/CFG/CFGPruner.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 | using System.Linq;
4 | using System.Xml;
5 | using PHPAnalysis.Data.CFG;
6 | using PHPAnalysis.Utils;
7 | using QuickGraph;
8 | using QuickGraph.Algorithms;
9 |
10 | namespace PHPAnalysis.Analysis.CFG
11 | {
12 | public interface ICFGPruner
13 | {
14 | void Prune(BidirectionalGraph> graph);
15 | }
16 |
17 | public sealed class CFGPruner : ICFGPruner
18 | {
19 | private BidirectionalGraph> graph;
20 |
21 | public void Prune(BidirectionalGraph> graph)
22 | {
23 | Preconditions.NotNull(graph, "graph");
24 | this.graph = graph;
25 |
26 | RemoveUnreachableBlocks();
27 | RemoveEmptyBlocks();
28 |
29 | this.graph = null;
30 | }
31 |
32 | private void RemoveUnreachableBlocks()
33 | {
34 | var root = graph.Roots().Single(v => v.IsSpecialBlock);
35 |
36 | var reachableBlocks = graph.ReachableBlocks(root);
37 | var unreachableBlocks = graph.Vertices.Except(reachableBlocks).ToList();
38 |
39 | foreach (var unreachableBlock in unreachableBlocks)
40 | {
41 | graph.RemoveVertex(unreachableBlock);
42 | }
43 | }
44 |
45 | private void RemoveEmptyBlocks()
46 | {
47 | //HACK: Not the most efficient way of solving this.
48 | //-||-: However it works.
49 | var lastTimeCount = int.MaxValue;
50 | var numberOfVertices = graph.Vertices.Count();
51 | while (numberOfVertices != lastTimeCount)
52 | {
53 | var toRemove = new List();
54 |
55 | foreach (var vertex in graph.Vertices)
56 | {
57 | int inEdgesCount = graph.InEdges(vertex).Count();
58 | int outEdgesCount = graph.OutEdges(vertex).Count();
59 |
60 | if (!(vertex.IsLeaf || vertex.IsRoot || vertex.IsSpecialBlock || vertex.AstEntryNode != null))
61 | {
62 | if (inEdgesCount == 1 && outEdgesCount == 0)
63 | {
64 | toRemove.Add(vertex);
65 | }
66 | else if (inEdgesCount > 0 && outEdgesCount == 1)
67 | {
68 | foreach (var edge in graph.InEdges(vertex))
69 | {
70 | var parent = edge.Source;
71 | var child = graph.OutEdge(vertex, 0).Target;
72 |
73 | graph.AddEdge(new TaggedEdge(parent, child, edge.Tag));
74 | toRemove.Add(vertex);
75 | }
76 | }
77 | }
78 | }
79 |
80 | foreach (var vertex in toRemove)
81 | {
82 | graph.RemoveVertex(vertex);
83 | }
84 |
85 | lastTimeCount = numberOfVertices;
86 | numberOfVertices = graph.Vertices.Count();
87 | }
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/PHPAnalysis/FileWriter.Plugin/FileWriter.Plugin.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {6EBE6355-A353-4614-A507-EB251282541B}
8 | Library
9 | Properties
10 | FileWriter.Plugin
11 | FileWriter.Plugin
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 | False
36 | ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | {04511bb1-4881-44f2-b07d-fd88cede53cb}
54 | PHPAnalysis
55 |
56 |
57 |
58 |
59 |
60 |
61 |
68 |
--------------------------------------------------------------------------------
/PHPAnalysis/WordPress.Plugin/WordPress.Plugin.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B27C2212-E33B-4BEF-9FB7-62113A3682C6}
8 | Library
9 | Properties
10 | WordPress.Plugin
11 | WordPress.Plugin
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 | False
36 | ..\packages\Microsoft.Bcl.Immutable.1.0.34\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | {04511bb1-4881-44f2-b07d-fd88cede53cb}
58 | PHPAnalysis
59 |
60 |
61 |
62 |
69 |
--------------------------------------------------------------------------------