├── .build
├── MSBuild.Community.Tasks.dll
└── MSBuild.Community.Tasks.targets
├── .github
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── help-and-other-questions.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── App_LocalResources
└── View.ascx.resx
├── Build.proj
├── BuildScripts
├── MSBuild.Community.Tasks.Targets
└── ModulePackage.targets
├── Components
├── AuditChecks.cs
├── CheckResult.cs
├── Checks
│ ├── CheckAllowableFileExtensions.cs
│ ├── CheckBiography.cs
│ ├── CheckDebug.cs
│ ├── CheckDefaultPage.cs
│ ├── CheckDiskAcccessPermissions.cs
│ ├── CheckDnnVersion.cs
│ ├── CheckHiddenSystemFiles.cs
│ ├── CheckHttpModules.cs
│ ├── CheckModuleHeaderAndFooter.cs
│ ├── CheckPasswordFormat.cs
│ ├── CheckRarelyUsedSuperuser.cs
│ ├── CheckSiteRegistration.cs
│ ├── CheckSqlRisk.cs
│ ├── CheckSuperuserOldPassword.cs
│ ├── CheckTelerikVulnerability.cs
│ ├── CheckTracing.cs
│ ├── CheckUnexpectedExtensions.cs
│ └── CheckViewstatemac.cs
├── EscapedString.cs
├── FeatureController.cs
├── FileExtensionWhitelist.cs
├── IAuditCheck.cs
├── SeverityEnum.cs
└── Utility.cs
├── DNN.Modules.SecurityAnalyzer.csproj
├── DNN.Modules.SecurityAnalyzer.sln
├── HttpModules
└── SecurityAnalyzerModule.cs
├── Images
├── Extensions_16x16_Standard.png
└── Extensions_32x32_Standard.png
├── LICENSE
├── License.txt
├── Properties
└── AssemblyInfo.cs
├── Providers
└── DataProviders
│ └── SqlDataProvider
│ ├── 01.00.00.SqlDataProvider
│ ├── 08.00.02.SqlDataProvider
│ └── Uninstall.SqlDataProvider
├── README.md
├── References
└── DotNetNuke.dll
├── ReleaseNotes.txt
├── Resources
├── CheckFileExists.resources
├── ExecuteCommand.resources
├── GetFolderTree.resources
├── RegRead.resources
├── SysAdmin.resources
└── sums.resources
├── Scripts
├── dnnscripts.js
└── jquery-ui.min.js
├── SecurityAnalyzer.dnn
├── SecurityAnalyzerModuleBase.cs
├── Styles
└── dnnstyles.css
├── View.ascx
├── View.ascx.cs
├── View.ascx.designer.cs
├── module.css
├── packages.config
├── web.Debug.config
├── web.Release.config
└── web.config
/.build/MSBuild.Community.Tasks.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DNNCommunity/DNN.SecurityAnalyzer/c4fd5bc4cccface170f959ad9d19fa885c5baba6/.build/MSBuild.Community.Tasks.dll
--------------------------------------------------------------------------------
/.build/MSBuild.Community.Tasks.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(MSBuildExtensionsPath)\MSBuildCommunityTasks
7 | $(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | Community contributions are essential part of any open source project. The
4 | community has access to a large number of unique configurations which would
5 | be extremely difficult for the core maintainers to reproduce. We want to keep
6 | it as easy as possible to contribute changes that get things working in your
7 | environment. There are a few guidelines that we need contributors to follow
8 | so that we can have a chance of keeping on top of things.
9 |
10 | ## Getting Started
11 |
12 |
13 | * Make sure you have a [GitHub account](https://github.com/signup/free)
14 | * **Submit an issue** for your issue, assuming one does not already exist. If you have the rights, you should assign yourself to the issue. If you do not have that ability please add a comment noting that a pull request will be submitted for the issue. After review, if the pull request is accepted, we will mark the issue as resolved and assign it to a release so it can be QA'ed.
15 | * Clearly describe the issue including steps to reproduce when it is a bug.
16 | * Make sure you fill in the earliest version that you know has the issue.
17 | * Fork the repository on GitHub
18 |
19 | ## Making Changes
20 |
21 | * Create a topic branch from where you want to base your work.
22 | * This is usually the 'development' branch.
23 | * Release branches should only be targeted by official committers.
24 | * To quickly create a topic branch based on development; `git checkout -b my_contribution development`
25 | * Make commits of logical units.
26 | * Check for unnecessary whitespace with `git diff --check` before committing.
27 | * Make sure your commit messages are in the proper format
28 | * For bonus points run and add unit tests
29 | * Make sure you have added the necessary tests for your changes.
30 | * Run _all_ the tests to assure nothing else was accidentally broken.
31 |
32 |
33 | ## Making Trivial Changes
34 |
35 | ### Documentation
36 |
37 | For changes of a trivial nature to comments and documentation, it is not
38 | always necessary to create a new ticket in the issue tracker. In this case, it is appropriate to start the first line of a commit with '(doc)' instead of
39 | a ticket number.
40 |
41 | ````
42 | (doc) Add documentation commit example to CONTRIBUTING
43 |
44 | There is no example for contributing a documentation commit
45 | to the DNN repository. This is a problem because the contributor
46 | is left to assume how a commit of this nature may appear.
47 |
48 | The first line is a real life imperative statement with '(doc)' in
49 | place of what would have been the ticket number in a
50 | non-documentation related commit. The body describes the nature of
51 | the new documentation or comments added.
52 | ````
53 |
54 | ## Submitting Changes
55 |
56 | * Sign the [Contributor License Agreement](http://www.dnnsoftware.com).
57 | * Push your changes to a topic branch in your fork of the repository.
58 | * Submit a pull request to the DNN.Platform repository in the DNNSoftware organization.
59 | * The committers will handle updating the associated issue in the DNN Tracker to ensure it gets the necessary code review and QA.
60 |
61 | ## Acceptance of your Changes
62 | * We have a group of fellow developers that review pull requests submitted by developers like yourself.
63 | * If your changes look good, then changes are merged to an appropriate release.
64 | * We may ask you to make further changes or reject the change (with proper reasonsing - we hope that's not the case though).
65 | * You should get an email notification as we complete processing of your pull request.
66 |
67 | ## Downloading latest package with your changes
68 | * As soon as changes are accepted, our team city build server gets into action.
69 | * New builds are usually available within 10 minutes of acceptance.
70 |
71 | # Additional Resources
72 |
73 | * [Contributor License Agreement](http://www.dnnsoftware.com)
74 | * [General GitHub documentation](http://help.github.com/)
75 | * [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
76 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | ## Describe the bug
8 | A clear and concise description of what the bug is.
9 |
10 |
11 | ## Software Versions
12 | - DNN: 00.00.00
13 | - Module: 00.00.00
14 |
15 |
16 | ## To Reproduce
17 | Steps to reproduce the behavior:
18 | 1. Go to '...'
19 | 2. Click on '....'
20 | 3. Scroll down to '....'
21 | 4. See error
22 |
23 |
24 | ## Expected behavior
25 | A clear and concise description of what you expected to happen.
26 |
27 |
28 | ## Screenshots
29 | If applicable, add screenshots to help explain your problem.
30 |
31 |
32 | ## Error log
33 | **Note: Debug DLL's**
34 | Please replace the current extension DLL's with the debug DLL's (if these are available with the release) and reproduce the error with the debug DLL's before pasting the error log.
35 |
36 | Paste the error log that is related to this issue.
37 |
38 |
39 | ## Additional context
40 | Add any other context about the problem here.
41 |
42 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | ## Is your feature request related to a problem?
8 | **Please describe.**
9 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
10 |
11 | ## Describe the solution you'd like
12 | A clear and concise description of what you want to happen.
13 |
14 | ## Describe alternatives you've considered
15 | A clear and concise description of any alternative solutions or features you've considered.
16 |
17 | ## Additional context
18 | Add any other context or screenshots about the feature request here.
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/help-and-other-questions.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Help and other questions
3 | about: Ask for help or others questions re. using the module
4 |
5 | ---
6 |
7 | ## Please summarize your question in one sentence
8 |
9 |
10 | ## Give a more extended description
11 |
12 |
13 | ## Steps to reproduce (if needed)
14 |
15 |
16 | ## Other comments or remarks
17 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | ### Description of PR...
7 |
8 | ## Changes made
9 | - Item 1
10 | - Item 2
11 |
12 |
13 | ## PR Template Checklist
14 |
15 | - [ ] Fixes Bug
16 | - [ ] Feature solution
17 | - [ ] Other
18 |
19 |
20 | ## Please mark which issue is solved
21 |
22 |
23 | Close #
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Visual Studio
3 | #################
4 |
5 | ## Ignore Visual Studio temporary files, build results, and
6 | ## files generated by popular Visual Studio add-ons.
7 |
8 | # User-specific files
9 | *.suo
10 | *.user
11 | *.sln.docstates
12 | *.local.sln
13 | *.local.sln.GhostDoc.xml
14 |
15 | ## Ignore VS2015/Roslyn artifacts
16 | *.sln.ide/
17 | .vs/
18 |
19 | # Build results
20 | [Rr]elease
21 | *_i.c
22 | *_p.c
23 | *.ilk
24 | *.meta
25 | *.obj
26 | *.pch
27 | *.pgc
28 | *.pgd
29 | *.rsp
30 | *.sbr
31 | *.tlb
32 | *.tli
33 | *.tlh
34 | *.tmp
35 | *.eml
36 | *.vspscc
37 | .builds
38 | *.dotCover
39 | *.ldf
40 |
41 | # git merge artifacts
42 | *.orig
43 | *.gitmodules
44 |
45 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
46 | [Pp]ackages/
47 |
48 | # Visual Studio profiler
49 | *.psess
50 | *.vsp
51 |
52 | # ReSharper is a .NET coding add-in
53 | _ReSharper*
54 |
55 | # Others
56 |
57 | [Oo]bj
58 | TestResults
59 | *.Cache
60 | ClientBin
61 | stylecop.*
62 | ~$*
63 | *.dbmdl
64 | Generated_Code #added for RIA/Silverlight projects
65 |
66 | # Backup & report files from converting an old project file to a newer
67 | # Visual Studio version. Backup files are not needed, because we have git ;-)
68 | _UpgradeReport_Files/
69 | Backup*/
70 | UpgradeLog*.XML
71 |
72 | ############
73 | ## DNN
74 | ############
75 |
76 | # Ignore artifacts from deployed/installed site
77 |
78 | DNN_*.zip
79 |
80 | !DNN [Pp]latform/[Cc]omponents
81 | !DNN [Pp]latform/[Cc]ontrols
82 | DNN [Pp]latform/[Cc]omponents/[Cc]lient[Dd]ependency/[Ss]ource/[Bb]in
83 | DNN [Pp]latform/[Cc]ontrols/[Cc]ountry[Ll]ist[Bb]ox/[Bb]in/*
84 |
85 | DNN [Pp]latform/*/[Bb]in
86 | DNN [Pp]latform/Tests/*/[Bb]in/*
87 | DNN [Pp]latform/Modules/*/[Bb]in/*
88 | DNN [Pp]latform/Admin Modules/*/[Bb]in/*
89 | DNN [Pp]latform/MVC Modules/*/[Bb]in/*
90 | DNN [Pp]latform/[Pp]roviders/*/*/[Bb]in/*
91 | DNN [Pp]latform/[Pp]roviders/*/*/*/[Bb]in/*
92 | DNN [Pp]latform/Syndication/[Bb]in/*
93 |
94 |
95 | [Ww]ebsite/*/[Dd]efault.aspx
96 |
97 | [Ww]ebsite/[Aa]dmin/[Pp]ersonabar
98 |
99 | [Ww]ebsite/[Aa]pp_[Cc]ode
100 |
101 | [Ww]ebsite/[Aa]pp_[Dd]ata
102 |
103 | [Ww]ebsite/[Bb]in
104 |
105 | [Ww]ebsite/[Cc]onfig
106 |
107 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Ff]ifty[Oo]ne[Cc]lient[Cc]apability[Pp]rovider
108 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Rr]ad[Ee]ditor[Pp]rovider
109 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Tt]axonomy
110 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Uu]rl[Mm]anagement
111 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Hh]tml[Ee]ditor[Mm]anager
112 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Rr]ecycle[Bb]in
113 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]dmin/[Nn]ewsletters
114 |
115 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]uthentication[Ss]ervices/[Ff]acebook
116 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]uthentication[Ss]ervices/[Gg]oogle
117 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]uthentication[Ss]ervices/[Ll]ive
118 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]uthentication[Ss]ervices/[Tt]witter
119 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]uthentication[Ss]ervices/DNN[Pp]ro_[Aa]ctive[Dd]irectory
120 |
121 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Cc]ore[Mm]essaging
122 | [Ww]ebsite/[Dd]esktop[Mm]odules/DDRMenu
123 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Dd]evice[Pp]review[Mm]anagement
124 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Dd]igital[Aa]ssets
125 | [Ww]ebsite/[Dd]esktop[Mm]odules/DNNCorp
126 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Dd][Nn][Nn]
127 | [Ww]ebsite/[Dd]esktop[Mm]odules/HTML
128 | [Ww]ebsite/[Dd]esktop[Mm]odules/MVC
129 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Jj]ournal
130 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Mm]ember[Dd]irectory
131 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Mm]obile[Mm]anagement
132 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Rr]azor[Mm]odules
133 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ss]ocial[Gg]roups
134 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ss]ubscriptions[Mm]gmt
135 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ii]dentity[Ss]witcher
136 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Bb]log
137 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ii][Ff]rame
138 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Aa]nnouncements
139 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ee]vents
140 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ff]eedback
141 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Ff][Aa][Qq]s
142 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Mm]edia
143 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Uu]ser[Dd]efined[Tt]able
144 | [Ww]ebsite/[Dd]esktop[Mm]odules/dnnGlimpse
145 | [Ww]ebsite/[Dd]esktop[Mm]odules/[Tt]est*
146 |
147 | [Ww]ebsite/[Ii]nstall/*/*.zip
148 | [Ww]ebsite/[Ii]nstall/*/*.resources
149 | [Ww]ebsite/[Ii]nstall/[Cc]leanup
150 | [Ww]ebsite/[Ii]nstall/[Cc]onfig
151 | [Ww]ebsite/[Ii]nstall/[Dd]ot[Nn]et[Nn]uke.install.config
152 | [Ww]ebsite/[Ii]nstall/installstat.log.resources.txt
153 | [Ww]ebsite/[Ii]nstall/upgradestat.log.resources.txt
154 |
155 | [Ww]ebsite/[Ll]icenses/*.txt
156 |
157 | [Ww]ebsite/[Mm]odules
158 |
159 | [Ww]ebsite/[Pp]ortals/_default/[Ll]ogs
160 | [Ww]ebsite/[Pp]ortals/_default/[Mm]erged[Tt]emplate
161 | [Ww]ebsite/[Pp]ortals/_default/[Bb]lank [Ww]ebsite*.*
162 | [Ww]ebsite/[Pp]ortals/_default/[Dd]efault [Ww]ebsite*.*
163 | [Ww]ebsite/[Pp]ortals/_default/[Mm]obile [Ww]ebsite*.*
164 | [Ww]ebsite/[Pp]ortals/_default/[Cc]ontainers/*/thumbnail*.jpg
165 | [Ww]ebsite/[Pp]ortals/_default/[Cc]ontainers/[Cc]avalier/*.*
166 | [Ww]ebsite/[Pp]ortals/_default/[Ss]kins/*/thumbnail*.jpg
167 | [Ww]ebsite/[Pp]ortals/_default/[Ss]kins/[Cc]avalier
168 | [Ww]ebsite/[Pp]ortals/_default/[Ss]kins/[Cc]avalier/*/*.*
169 |
170 | [Ww]ebsite/[Pp]ortals/_default/[Uu]ser*
171 | [Ww]ebsite/[Pp]ortals/[0-9]*/
172 |
173 | [Ww]ebsite/[Pp]roviders/[Dd]ata[Pp]roviders/*/*.resources
174 | [Ww]ebsite/[Pp]roviders/*/*/license.txt
175 | [Ww]ebsite/[Pp]roviders/*/*/release[Nn]otes.txt
176 | [Ww]ebsite/[Pp]roviders/[Ff]older[Pp]roviders
177 |
178 | [Ww]ebsite/[Rr]esources/[Ll]ibraries
179 |
180 | [Ww]ebsite/[Ss]ignatures
181 |
182 | [Ww]ebsite/51[Dd]egrees.mobi.config
183 | [Ww]ebsite/[Dd]ot[Nn]et[Nn]uke.log4net.config
184 | [Ww]ebsite/[Dd]ot[Nn]et[Nn]uke.config
185 | [Ww]ebsite/[Ss]ite[Aa]nalytics.config
186 | [Ww]ebsite/[Ss]ite[Uu]rls.config
187 | [Ww]ebsite/web.config
188 | [Ww]ebsite/app_offline.htm
189 |
190 | # ignore all other language resx files
191 | *.de-DE.resx
192 | *.es-ES.resx
193 | *.fr-FR.resx
194 | *.it-IT.resx
195 | *.nl-NL.resx
196 |
197 | # but do track translations in the Install folder
198 | ![Ww]ebsite/[Ii]nstall/[Aa]pp_[Ll]ocal[Rr]esources/*.de-DE.resx
199 | ![Ww]ebsite/[Ii]nstall/[Aa]pp_[Ll]ocal[Rr]esources/*.es-ES.resx
200 | ![Ww]ebsite/[Ii]nstall/[Aa]pp_[Ll]ocal[Rr]esources/*.fr-FR.resx
201 | ![Ww]ebsite/[Ii]nstall/[Aa]pp_[Ll]ocal[Rr]esources/*.it-IT.resx
202 | ![Ww]ebsite/[Ii]nstall/[Aa]pp_[Ll]ocal[Rr]esources/*.nl-NL.resx
203 |
204 | *.zip.manifest
205 |
206 | ############
207 | ## Windows
208 | ############
209 |
210 | # Windows image file caches
211 | Thumbs.db
212 |
213 | # Folder config file
214 | Desktop.ini
215 |
216 | Website/Install/Temp/
217 | install/
218 |
--------------------------------------------------------------------------------
/Build.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\.build
5 |
6 |
7 |
8 |
9 |
10 |
11 | 1.0.0.0
12 | 1.0.0.0
13 | 1.0.0.0
14 |
15 |
16 |
17 |
18 | 1.0.0.0
19 | $(BUILD_NUMBER)
20 | $(BUILD_NUMBER)
21 |
22 |
23 |
24 | Release
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
35 |
36 |
37 |
38 |
39 |
40 |
48 |
49 |
50 |
51 |
52 |
53 | Configuration=$(BuildConfiguration)
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/BuildScripts/MSBuild.Community.Tasks.Targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\BuildScripts
5 | $(MSBuildProjectDirectory)\..\..\..\bin
6 | $(SolutionDir)\packages\MSBuildTasks.1.4.0.61\tools\MSBuild.Community.Tasks.dll
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/BuildScripts/ModulePackage.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
16 | $(Version).00
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/Components/AuditChecks.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web;
5 | using DNN.Modules.SecurityAnalyzer.Components.Checks;
6 | using DotNetNuke.Common;
7 |
8 | namespace DNN.Modules.SecurityAnalyzer.Components
9 | {
10 | public class AuditChecks
11 | {
12 | private readonly IEnumerable _auditChecks;
13 |
14 | public AuditChecks()
15 | {
16 | var checks = new List
17 | {
18 | new CheckDnnVersion(),
19 | new CheckDebug(),
20 | new CheckTracing(),
21 | new CheckBiography(),
22 | new CheckSiteRegistration(),
23 | new CheckRarelyUsedSuperuser(),
24 | new CheckSuperuserOldPassword(),
25 | new CheckUnexpectedExtensions(),
26 | new CheckDefaultPage(),
27 | new CheckModuleHeaderAndFooter(),
28 | new CheckPasswordFormat(),
29 | new CheckDiskAcccessPermissions(),
30 | new CheckSqlRisk(),
31 | new CheckAllowableFileExtensions(),
32 | new CheckHiddenSystemFiles(),
33 | new CheckTelerikVulnerability(),
34 | new CheckHttpModules()
35 | };
36 |
37 | if (Globals.NETFrameworkVersion <= new Version(4, 5, 1))
38 | {
39 | checks.Insert(2, new CheckViewstatemac());
40 | }
41 |
42 | _auditChecks= checks.AsReadOnly();
43 | }
44 |
45 | public IList DoChecks(bool checkAll = false)
46 | {
47 | var results = new List();
48 | foreach (var check in _auditChecks)
49 | {
50 | try
51 | {
52 | var result = checkAll || !check.LazyLoad ? check.Execute() : new CheckResult(SeverityEnum.Unverified, check.Id);
53 | results.Add(result);
54 | }
55 | catch (Exception ex)
56 | {
57 | var result = new CheckResult(SeverityEnum.Unverified, check.Id);
58 | result.Notes.Add("An error occured, Message: " + HttpUtility.HtmlEncode(ex.Message));
59 | results.Add(result);
60 | }
61 |
62 | }
63 | return results;
64 | }
65 |
66 | public CheckResult DoCheck(string id)
67 | {
68 | try
69 | {
70 | var check = _auditChecks.FirstOrDefault(c => c.Id.Equals(id, StringComparison.InvariantCultureIgnoreCase));
71 | return check?.Execute();
72 | }
73 | catch (Exception)
74 | {
75 | return new CheckResult(SeverityEnum.Unverified, id);
76 | }
77 | }
78 | }
79 | }
--------------------------------------------------------------------------------
/Components/CheckResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using DotNetNuke.Services.Localization;
4 |
5 | namespace DNN.Modules.SecurityAnalyzer.Components
6 | {
7 | [Serializable]
8 | public class CheckResult
9 | {
10 | public CheckResult(SeverityEnum severity, string checkname)
11 | {
12 | Severity = severity;
13 | CheckName = checkname;
14 | Notes = new List();
15 | }
16 |
17 | public SeverityEnum Severity { get; set; }
18 | public string CheckName { get; set; }
19 |
20 | public string Reason
21 | {
22 | get
23 | {
24 | return Localization.GetString(CheckName + "Reason", LocalResourceFile);
25 | }
26 | }
27 |
28 | public string FailureText
29 | {
30 | get { return Localization.GetString(CheckName + "Failure", LocalResourceFile); }
31 | }
32 |
33 | public string SuccessText
34 | {
35 | get { return Localization.GetString(CheckName + "Success", LocalResourceFile); }
36 | }
37 |
38 | public string CheckNameText
39 | {
40 | get
41 | {
42 |
43 | return CheckName + " : " + Localization.GetString(CheckName + "Name", LocalResourceFile);
44 | }
45 | }
46 |
47 | public IList Notes { get; set; }
48 |
49 | private string LocalResourceFile
50 | {
51 | get { return "~/DesktopModules/DNNCorp/SecurityAnalyzer/App_LocalResources/view.ascx"; }
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckAllowableFileExtensions.cs:
--------------------------------------------------------------------------------
1 | using DotNetNuke.Entities.Controllers;
2 |
3 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
4 | {
5 | public class CheckAllowableFileExtensions : IAuditCheck
6 | {
7 | public string Id => "CheckAllowableFileExtensions";
8 |
9 | public bool LazyLoad => false;
10 |
11 | public CheckResult Execute()
12 | {
13 | var result = new CheckResult(SeverityEnum.Unverified, Id);
14 | var allowedExtensions = new FileExtensionWhitelist(HostController.Instance.GetString("FileExtensions"));
15 | if (allowedExtensions.IsAllowedExtension("asp")
16 | || allowedExtensions.IsAllowedExtension("aspx")
17 | || allowedExtensions.IsAllowedExtension("php"))
18 | {
19 | result.Severity = SeverityEnum.Failure;
20 | result.Notes.Add("Extensions: " + allowedExtensions.ToDisplayString());
21 | }
22 | else
23 | {
24 | result.Severity = SeverityEnum.Pass;
25 | }
26 | return result;
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckBiography.cs:
--------------------------------------------------------------------------------
1 | using DotNetNuke.Common.Lists;
2 | using DotNetNuke.Entities.Portals;
3 | using DotNetNuke.Entities.Profile;
4 |
5 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
6 | {
7 | public class CheckBiography : IAuditCheck
8 | {
9 | public string Id => "CheckBiography";
10 |
11 | public bool LazyLoad => false;
12 |
13 | public CheckResult Execute()
14 | {
15 | var result = new CheckResult(SeverityEnum.Unverified, Id);
16 | var portalController = new PortalController();
17 | var controller = new ListController();
18 |
19 | var richTextDataType = controller.GetListEntryInfo("DataType", "RichText");
20 | result.Severity = SeverityEnum.Pass;
21 | foreach (PortalInfo portal in portalController.GetPortals())
22 | {
23 | var pd = ProfileController.GetPropertyDefinitionByName(portal.PortalID, "Biography");
24 | if (pd != null && pd.DataType == richTextDataType.EntryID)
25 | {
26 | result.Severity = SeverityEnum.Failure;
27 | result.Notes.Add("Portal:" + portal.PortalName);
28 | }
29 | }
30 | return result;
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckDebug.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 |
3 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
4 | {
5 | public class CheckDebug : IAuditCheck
6 | {
7 | public string Id => "CheckDebug";
8 |
9 | public bool LazyLoad => false;
10 |
11 | public CheckResult Execute()
12 | {
13 | var result = new CheckResult(SeverityEnum.Unverified, Id)
14 | {
15 | Severity = HttpContext.Current.IsDebuggingEnabled
16 | ? SeverityEnum.Warning
17 | : SeverityEnum.Pass
18 | };
19 | return result;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckDefaultPage.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using System.Xml;
4 | using DotNetNuke.Application;
5 | using DotNetNuke.Common;
6 |
7 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
8 | {
9 | public class CheckDefaultPage : IAuditCheck
10 | {
11 | public string Id => "CheckDefaultPage";
12 |
13 | public bool LazyLoad => false;
14 |
15 | public CheckResult Execute()
16 | {
17 | var result = new CheckResult(SeverityEnum.Unverified, Id);
18 | IList modifiedFiles;
19 | var fileModified = CheckDefaultPageModified(out modifiedFiles);
20 | if (fileModified)
21 | {
22 | if (modifiedFiles.Count == 0)
23 | {
24 | if (DotNetNukeContext.Current.Application.Version.Major > 6)
25 | {
26 | result.Notes.Add("There is no data available about your current installation, please upgrade this module to it's latest version.");
27 | }
28 | else
29 | {
30 | fileModified = false;
31 | }
32 | }
33 |
34 | result.Severity = SeverityEnum.Failure;
35 | foreach (var filename in modifiedFiles)
36 | {
37 | result.Notes.Add("file:" + filename);
38 | }
39 | }
40 | else
41 | {
42 | result.Severity = SeverityEnum.Pass;
43 | }
44 | return result;
45 | }
46 |
47 | private bool CheckDefaultPageModified(out IList modifiedFiles)
48 | {
49 | modifiedFiles = new List();
50 |
51 | var sumData = Utility.LoadFileSumData();
52 |
53 | var appVersion = Utility.GetApplicationVersion();
54 | var appType = Utility.GetApplicationType();
55 |
56 | var dataNodes = sumData.SelectNodes("/checksums/sum[@version=\"" + appVersion + "\"][@type=\"" + appType + "\"]");
57 | if (dataNodes == null || dataNodes.Count == 0)
58 | {
59 | return true; //when no record matched, need notify user to update the module.
60 | }
61 |
62 | var fileModified = false;
63 | foreach (XmlNode node in dataNodes)
64 | {
65 | var fileName = node.Attributes["name"].Value;
66 | var sum = node.Attributes["sum"].Value;
67 | var file = Path.Combine(Globals.ApplicationMapPath, fileName);
68 | if (!File.Exists(file) || Utility.GetFileCheckSum(file) != sum)
69 | {
70 | fileModified = true;
71 | modifiedFiles.Add(fileName);
72 | }
73 | }
74 |
75 | return fileModified;
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckDiskAcccessPermissions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Security.AccessControl;
6 | using System.Security.Principal;
7 | using DotNetNuke.Common;
8 |
9 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
10 | {
11 | public class CheckDiskAcccessPermissions : IAuditCheck
12 | {
13 | public string Id => "CheckDiskAccess";
14 |
15 | public bool LazyLoad => false;
16 |
17 | public CheckResult Execute()
18 | {
19 | var result = new CheckResult(SeverityEnum.Unverified, Id);
20 | IList accessErrors = new List();
21 | try
22 | {
23 | accessErrors = CheckAccessToDrives();
24 | }
25 | catch (IOException)
26 | {
27 | // e.g., a disk error or a drive was not ready
28 | }
29 | catch (UnauthorizedAccessException)
30 | {
31 | // The caller does not have the required permission.
32 |
33 | }
34 | catch (System.Security.SecurityException)
35 | {
36 | //Some security exception
37 | }
38 |
39 |
40 | if (accessErrors.Count == 0)
41 | {
42 | result.Severity = SeverityEnum.Pass;
43 | }
44 | else
45 | {
46 | result.Severity = SeverityEnum.Warning;
47 | result.Notes = accessErrors;
48 | }
49 | return result;
50 | }
51 |
52 | #region private methods
53 |
54 | private static IList CheckAccessToDrives()
55 | {
56 | var errors = new List();
57 | var dir = new DirectoryInfo(Globals.ApplicationMapPath);
58 |
59 |
60 | while (dir.Parent != null)
61 | {
62 |
63 | try
64 | {
65 | dir = dir.Parent;
66 | var permissions = CheckPermissionOnDir(dir);
67 | var isRoot = dir.Name == dir.Root.Name;
68 | if (permissions.Create == Yes || permissions.Write == Yes || permissions.Delete == Yes || (!isRoot && permissions.Read == Yes))
69 | {
70 | errors.Add(GetPermissionText(dir, permissions, isRoot));
71 | }
72 | }
73 | catch (IOException)
74 | {
75 | // e.g., a disk error or a drive was not ready
76 | }
77 | catch (UnauthorizedAccessException)
78 | {
79 | // The caller does not have the required permission.
80 |
81 | }
82 |
83 | }
84 |
85 | var drives = DriveInfo.GetDrives();
86 | var checkedDrives = new List();
87 | foreach (var drive in drives.Where(d => d.IsReady && d.RootDirectory.Name != dir.Root.Name))
88 | {
89 | try
90 | {
91 | var driveType = drive.DriveType;
92 | if (driveType == DriveType.Fixed || driveType == DriveType.Network)
93 | {
94 | var dir2 = drive.RootDirectory;
95 | var key = dir2.FullName.ToLowerInvariant();
96 | if (checkedDrives.Contains(key))
97 | {
98 | continue;
99 | }
100 |
101 | checkedDrives.Add(key);
102 |
103 | var permissions = CheckPermissionOnDir(dir2);
104 | if (permissions.AnyYes)
105 | {
106 | errors.Add(GetPermissionText(dir2, permissions));
107 | }
108 | }
109 | }
110 | catch (IOException)
111 | {
112 | // e.g., a disk error or a drive was not ready
113 | }
114 | catch (UnauthorizedAccessException)
115 | {
116 | // The caller does not have the required permission.
117 | }
118 | }
119 |
120 | return errors;
121 | }
122 |
123 | private static string GetPermissionText(DirectoryInfo dir, Permissions permissions, bool ignoreRead = false)
124 | {
125 | var message = ignoreRead
126 | ? @"{0} - Write:{2}, Create:{3}, Delete:{4}"
127 | : @"{0} - Read:{1}, Write:{2}, Create:{3}, Delete:{4}";
128 | return string.Format(@"{0} - Read:{1}, Write:{2}, Create:{3}, Delete:{4}",
129 | dir.FullName, permissions.Read, permissions.Write, permissions.Create, permissions.Delete);
130 | }
131 |
132 | private static Permissions CheckPermissionOnDir(DirectoryInfo dir)
133 | {
134 | var permissions = new Permissions(No);
135 | var disSecurity = dir.GetAccessControl(AccessControlSections.Access);
136 | var accessRules = disSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier));
137 | var poolIdentity = WindowsIdentity.GetCurrent();
138 | if (poolIdentity.User != null && poolIdentity.Groups != null)
139 | {
140 | foreach (FileSystemAccessRule rule in accessRules)
141 | {
142 | if (poolIdentity.User.Value == rule.IdentityReference.Value || poolIdentity.Groups.Contains(rule.IdentityReference))
143 | {
144 | if ((rule.FileSystemRights & (FileSystemRights.CreateDirectories | FileSystemRights.CreateFiles)) != 0)
145 | if (rule.AccessControlType == AccessControlType.Allow)
146 | permissions.Create = Yes;
147 | else
148 | permissions.SetThenLockCreate(No);
149 |
150 | if ((rule.FileSystemRights & FileSystemRights.Write) != 0)
151 | if (rule.AccessControlType == AccessControlType.Allow)
152 | permissions.Write = Yes;
153 | else
154 | permissions.SetThenLockWrite(No);
155 |
156 | if ((rule.FileSystemRights & (FileSystemRights.Read | FileSystemRights.ReadData)) != 0)
157 | if (rule.AccessControlType == AccessControlType.Allow)
158 | permissions.Read = Yes;
159 | else
160 | permissions.SetThenLockRead(No);
161 |
162 | if ((rule.FileSystemRights & (FileSystemRights.Delete | FileSystemRights.DeleteSubdirectoriesAndFiles)) != 0)
163 | if (rule.AccessControlType == AccessControlType.Allow)
164 | permissions.Delete = Yes;
165 | else
166 | permissions.SetThenLockDelete(No);
167 | }
168 | }
169 | }
170 |
171 | return permissions;
172 | }
173 |
174 | #endregion
175 |
176 | #region helpers
177 |
178 | private const char Yes = 'Y';
179 | private const char No = 'N';
180 |
181 | private class Permissions
182 | {
183 | public Permissions(char initial)
184 | {
185 | _create = _write = _read = _delete = initial;
186 | }
187 |
188 | public bool AnyYes
189 | {
190 | get { return Create == Yes || Write == Yes || Read == Yes || Delete == Yes; }
191 | }
192 |
193 | private char _create;
194 | private char _write;
195 | private char _read;
196 | private char _delete;
197 |
198 | private bool _createLocked;
199 | private bool _writeLocked;
200 | private bool _readLocked;
201 | private bool _deleteLocked;
202 |
203 | public char Create
204 | {
205 | get { return _create; }
206 | set { if (!_createLocked) _create = value; }
207 | }
208 |
209 | public char Write
210 | {
211 | get { return _write; }
212 | set { if (!_writeLocked) _write = value; }
213 | }
214 |
215 | public char Read
216 | {
217 | get { return _read; }
218 | set { if (!_readLocked) _read = value; }
219 | }
220 |
221 | public char Delete
222 | {
223 | get { return _delete; }
224 | set { if (!_deleteLocked) _delete = value; }
225 | }
226 |
227 | public void SetThenLockCreate(char value)
228 | {
229 | if (!_createLocked)
230 | {
231 | _createLocked = true;
232 | _create = value;
233 | }
234 | }
235 |
236 | public void SetThenLockWrite(char value)
237 | {
238 | if (!_writeLocked)
239 | {
240 | _writeLocked = true;
241 | _write = value;
242 | }
243 | }
244 |
245 | public void SetThenLockRead(char value)
246 | {
247 | if (!_readLocked)
248 | {
249 | _readLocked = true;
250 | _read = value;
251 | }
252 | }
253 |
254 | public void SetThenLockDelete(char value)
255 | {
256 | if (!_deleteLocked)
257 | {
258 | _deleteLocked = true;
259 | _delete = value;
260 | }
261 | }
262 | }
263 |
264 | #endregion
265 | }
266 | }
267 |
--------------------------------------------------------------------------------
/Components/Checks/CheckDnnVersion.cs:
--------------------------------------------------------------------------------
1 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
2 | {
3 | using DotNetNuke.Application;
4 | using DotNetNuke.Services.Localization;
5 |
6 | public class CheckDnnVersion : IAuditCheck
7 | {
8 | private const string ResourceFileRoot = "~/DesktopModules/DNNCorp/SecurityAnalyzer/App_LocalResources/View.ascx";
9 |
10 | public string Id => "CheckDnnVersion";
11 |
12 | public bool LazyLoad => false;
13 |
14 | public CheckResult Execute()
15 | {
16 | const int KnownCompromisedVersion = 8;
17 | var severity = DotNetNukeContext.Current.Application.Version.Major <= KnownCompromisedVersion
18 | ? SeverityEnum.Failure
19 | : SeverityEnum.Warning;
20 |
21 | return new CheckResult(severity, Id)
22 | {
23 | Notes =
24 | {
25 | Localization.GetString("CheckDnnVersion" + severity + "Note", ResourceFileRoot),
26 | }
27 | };
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Components/Checks/CheckHiddenSystemFiles.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
4 | {
5 | public class CheckHiddenSystemFiles : IAuditCheck
6 | {
7 | public string Id => "CheckHiddenSystemFiles";
8 |
9 | public bool LazyLoad => true;
10 |
11 | public CheckResult Execute()
12 | {
13 | var result = new CheckResult(SeverityEnum.Unverified, Id);
14 | var investigatefiles = Utility.FineHiddenSystemFiles();
15 | if (investigatefiles.Any())
16 | {
17 | result.Severity = SeverityEnum.Failure;
18 | foreach (var filename in investigatefiles)
19 | {
20 | result.Notes.Add("file:" + filename);
21 | }
22 | }
23 | else
24 | {
25 | result.Severity = SeverityEnum.Pass;
26 | }
27 | return result;
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckHttpModules.cs:
--------------------------------------------------------------------------------
1 | using DNN.Modules.SecurityAnalyzer.HttpModules;
2 |
3 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
4 | {
5 | public class CheckHttpModules : IAuditCheck
6 | {
7 | public string Id => "CheckHttpModules";
8 |
9 | public bool LazyLoad => false;
10 |
11 | public CheckResult Execute()
12 | {
13 | var result = new CheckResult(SeverityEnum.Unverified, Id)
14 | {
15 | Severity = !SecurityAnalyzerModule.SAHttpModuleExists
16 | ? SeverityEnum.Failure
17 | : SeverityEnum.Pass
18 | };
19 | return result;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckModuleHeaderAndFooter.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using DotNetNuke.Data;
3 |
4 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
5 | {
6 | public class CheckModuleHeaderAndFooter : IAuditCheck
7 | {
8 | public string Id => "CheckModuleHeaderAndFooter";
9 |
10 | public bool LazyLoad => false;
11 |
12 | public CheckResult Execute()
13 | {
14 | var result = new CheckResult(SeverityEnum.Unverified, Id);
15 | var dr = DataProvider.Instance().ExecuteReader("SecurityAnalyzer_GetModulesHasHeaderFooter");
16 | result.Severity = SeverityEnum.Pass;
17 | while (dr.Read())
18 | {
19 | result.Severity = SeverityEnum.Warning;
20 | var note = string.Format("TabId: {0}, Module Id: {1}", dr["TabId"], dr["ModuleId"]);
21 | var headerValue = dr["Header"].ToString();
22 | var footerValue = dr["Footer"].ToString();
23 | if (!string.IsNullOrEmpty(headerValue))
24 | {
25 | note += string.Format(" Header: {0}", HttpUtility.HtmlEncode(headerValue));
26 | }
27 | if (!string.IsNullOrEmpty(footerValue))
28 | {
29 | note += string.Format(" Footer: {0}", HttpUtility.HtmlEncode(footerValue));
30 | }
31 | note += "< br />";
32 |
33 | result.Notes.Add(note);
34 | }
35 | return result;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckPasswordFormat.cs:
--------------------------------------------------------------------------------
1 | using DotNetNuke.Security.Membership;
2 |
3 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
4 | {
5 | public class CheckPasswordFormat : IAuditCheck
6 | {
7 | public string Id => "CheckPasswordFormat";
8 |
9 | public bool LazyLoad => false;
10 |
11 | public CheckResult Execute()
12 | {
13 | var result = new CheckResult(SeverityEnum.Unverified, Id);
14 | var format = MembershipProvider.Instance().PasswordFormat;
15 | if (format == PasswordFormat.Hashed)
16 | {
17 | result.Severity = SeverityEnum.Pass;
18 | }
19 | else
20 | {
21 | result.Notes.Add("Setting:" + format.ToString());
22 | result.Severity = SeverityEnum.Failure;
23 | }
24 | return result;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckRarelyUsedSuperuser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DotNetNuke.Entities.Users;
3 |
4 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
5 | {
6 | public class CheckRarelyUsedSuperuser : IAuditCheck
7 | {
8 | public string Id => "CheckRarelyUsedSuperuser";
9 |
10 | public bool LazyLoad => false;
11 |
12 | public CheckResult Execute()
13 | {
14 | var result = new CheckResult(SeverityEnum.Unverified, Id);
15 | var totalRecords = 0;
16 |
17 | var superUsers = UserController.GetUsers(-1, 1, int.MaxValue, ref totalRecords, false, true);
18 | result.Severity = SeverityEnum.Pass;
19 | foreach (UserInfo user in superUsers)
20 | {
21 | if (DateTime.Now.AddMonths(-6) > user.Membership.LastLoginDate ||
22 | DateTime.Now.AddMonths(-6) > user.Membership.LastActivityDate)
23 | {
24 | result.Severity = SeverityEnum.Warning;
25 | result.Notes.Add("Superuser:" + user.Username);
26 | }
27 | }
28 | return result;
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckSiteRegistration.cs:
--------------------------------------------------------------------------------
1 | using DotNetNuke.Entities.Portals;
2 |
3 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
4 | {
5 | public class CheckSiteRegistration : IAuditCheck
6 | {
7 | public string Id => "CheckSiteRegistration";
8 |
9 | public bool LazyLoad => false;
10 |
11 | public CheckResult Execute()
12 | {
13 | var result = new CheckResult(SeverityEnum.Unverified, Id);
14 | var portalController = new PortalController();
15 | result.Severity = SeverityEnum.Pass;
16 | foreach (PortalInfo portal in portalController.GetPortals())
17 | {
18 | //check for public registration
19 | if (portal.UserRegistration == 2)
20 | {
21 | result.Severity = SeverityEnum.Warning;
22 | result.Notes.Add("Portal:" + portal.PortalName);
23 | }
24 | }
25 | return result;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckSqlRisk.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Data.SqlClient;
3 | using System.IO;
4 | using DotNetNuke.Common;
5 | using DotNetNuke.Data;
6 | using DotNetNuke.Services.Localization;
7 | using Assembly = System.Reflection.Assembly;
8 |
9 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
10 | {
11 | public class CheckSqlRisk : IAuditCheck
12 | {
13 | public string Id => "CheckSqlRisk";
14 |
15 | public bool LazyLoad => false;
16 |
17 | private string LocalResourceFile
18 | {
19 | get { return "~/DesktopModules/DNNCorp/SecurityAnalyzer/App_LocalResources/view.ascx"; }
20 | }
21 |
22 | public CheckResult Execute()
23 | {
24 | var result = new CheckResult(SeverityEnum.Unverified, Id);
25 | IList checkList = new List()
26 | {
27 | "SysAdmin",
28 | "ExecuteCommand",
29 | "GetFolderTree",
30 | "CheckFileExists",
31 | "RegRead"
32 | };
33 |
34 | result.Severity = SeverityEnum.Pass;
35 | foreach (var name in checkList)
36 | {
37 | if (!VerifyScript(name))
38 | {
39 | result.Severity = SeverityEnum.Warning;
40 | result.Notes.Add(Localization.GetString(name + ".Error", LocalResourceFile));
41 | }
42 | }
43 | return result;
44 | }
45 |
46 | private static bool VerifyScript(string name)
47 | {
48 | try
49 | {
50 | var script = LoadScript(name);
51 | if (!string.IsNullOrEmpty(script))
52 | {
53 | using (var reader = DataProvider.Instance().ExecuteSQL(script))
54 | {
55 | if (reader != null && reader.Read())
56 | {
57 | int affectCount;
58 | int.TryParse(reader[0].ToString(), out affectCount);
59 | return affectCount == 0;
60 | }
61 | }
62 | }
63 | }
64 | catch (SqlException)
65 | {
66 | //ignore; return no failure
67 | }
68 | return true;
69 | }
70 |
71 | public static string LoadScript(string name)
72 | {
73 | var resourceName = string.Format("DNN.Modules.SecurityAnalyzer.Resources.{0}.resources", name);
74 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
75 | {
76 | if (stream != null)
77 | {
78 | var script = new StreamReader(stream).ReadToEnd();
79 | return script.Replace("%SiteRoot%", Globals.ApplicationMapPath);
80 | }
81 |
82 | return null;
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckSuperuserOldPassword.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DotNetNuke.Entities.Users;
3 |
4 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
5 | {
6 | public class CheckSuperuserOldPassword : IAuditCheck
7 | {
8 | public string Id => "CheckSuperuserOldPassword";
9 |
10 | public bool LazyLoad => false;
11 |
12 | public CheckResult Execute()
13 | {
14 | var result = new CheckResult(SeverityEnum.Unverified, Id);
15 | var totalRecords = 0;
16 | var superUsers = UserController.GetUsers(-1, 1, int.MaxValue, ref totalRecords, false, true);
17 | result.Severity = SeverityEnum.Pass;
18 | foreach (UserInfo user in superUsers)
19 | {
20 | if (DateTime.Now.AddMonths(-6) > user.Membership.LastPasswordChangeDate)
21 | {
22 | result.Severity = SeverityEnum.Warning;
23 | result.Notes.Add("Superuser:" + user.Username);
24 | }
25 | }
26 | return result;
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckTelerikVulnerability.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Web;
7 | using DotNetNuke.Common;
8 | using DotNetNuke.Common.Utilities;
9 | using DotNetNuke.Security;
10 | using Assembly = System.Reflection.Assembly;
11 |
12 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
13 | {
14 | public class CheckTelerikVulnerability : IAuditCheck
15 | {
16 | public string Id => "CheckTelerikVulnerability";
17 |
18 | public bool LazyLoad => false;
19 |
20 | private string[] _configKeys = {
21 | "Telerik.AsyncUpload.ConfigurationEncryptionKey",
22 | "Telerik.Upload.ConfigurationHashKey",
23 | "Telerik.Web.UI.DialogParametersEncryptionKey",
24 | };
25 |
26 | private const string DefaultValue = "MDEyMzQ1Njc4OUFCQ0RFRjAxMjM0NTY3ODlBQkNERUYwMTIzNDU2Nzg5QUJDREVG";
27 | private Func _funx = s => string.IsNullOrEmpty(s) || DefaultValue.Equals(s) || s.Length < 40;
28 |
29 | public CheckResult Execute()
30 | {
31 | var result = new CheckResult(SeverityEnum.Unverified, Id);
32 |
33 | var fileSums = new List
34 | {
35 | // SHA-256 hashes
36 | "63de0ee563f34c21b0688fb5f81be02bb2aee94c8e5c855fbece72e4de455945", //Telerik 2013.2.717.40
37 | "f6dc6dd32f4f5698217c72a512ce9872c002be98cfced9a0344b46c50c1a6f02" //Telerik 2013.2.717.35
38 | };
39 |
40 | var compareVersion = new Version(2017, 2, 711);
41 | var filePath = Path.Combine(Globals.ApplicationMapPath, "bin\\Telerik.Web.UI.dll");
42 | result.Severity = SeverityEnum.Pass;
43 |
44 | if (File.Exists(filePath))
45 | {
46 | var assemblyVersion = Assembly.LoadFile(filePath).GetName().Version;
47 | if (assemblyVersion < compareVersion && !fileSums.Contains(Utility.GetFileCheckSum(filePath)))
48 | {
49 | result.Severity = SeverityEnum.Failure;
50 | result.Notes.Add("Telerik.Web.UI.dll assembly has't been patched.");
51 | }
52 |
53 | if (_configKeys.Select(Config.GetSetting).Any(val => _funx(val)))
54 | {
55 | var err = UpdateWebConfigFile();
56 | if (string.IsNullOrEmpty(err))
57 | {
58 | if (HttpContext.Current != null)
59 | {
60 | HttpContext.Current.Response.Redirect(HttpContext.Current.Request.RawUrl, true);
61 | }
62 | }
63 | else
64 | {
65 | result.Notes.Add("Couldn't update web.config file!");
66 | }
67 | }
68 |
69 | // check after trying to add the missing key(s)
70 | foreach (var configKey in _configKeys)
71 | {
72 | if (string.IsNullOrEmpty(Config.GetSetting(configKey)))
73 | {
74 | result.Severity = SeverityEnum.Failure;
75 | result.Notes.Add("App Setting \"" + configKey + "\" doesn't exist in web.config.");
76 | }
77 | }
78 | }
79 | else
80 | {
81 | result.Notes.Add("Telerik component is not installed in this site.");
82 | }
83 |
84 | return result;
85 | }
86 |
87 | private string UpdateWebConfigFile()
88 | {
89 | var strError = "";
90 | try
91 | {
92 | var appSettings = new Dictionary();
93 | foreach (var configKey in _configKeys)
94 | {
95 | var currentKey = Config.GetSetting(configKey);
96 | if (_funx(currentKey))
97 | {
98 | //create a random Telerik encryption key and add it under
99 | var newKey = new PortalSecurity().CreateKey(32);
100 | newKey = Convert.ToBase64String(Encoding.ASCII.GetBytes(newKey));
101 |
102 | appSettings.Add(configKey, newKey);
103 | }
104 | }
105 |
106 | if (appSettings.Count > 0)
107 | {
108 | //save the current config file
109 | Config.BackupConfig();
110 |
111 | //decrypt the web.config if needed.
112 | string providerName;
113 | var decrypted = Utility.DecryptConfigFile(out providerName);
114 |
115 | //open the web.config
116 | var xmlConfig = Config.Load();
117 |
118 | //Update the app settings.
119 | foreach (var settingKey in appSettings.Keys)
120 | {
121 | Config.AddAppSetting(xmlConfig, settingKey, appSettings[settingKey]);
122 | }
123 |
124 | //save the web.config
125 | strError += Config.Save(xmlConfig);
126 |
127 | if (decrypted)
128 | {
129 | Utility.EncryptConfigFile(providerName);
130 | }
131 | }
132 | }
133 | catch (Exception ex)
134 | {
135 | strError += ex.Message;
136 | }
137 | return strError;
138 | }
139 | }
140 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckTracing.cs:
--------------------------------------------------------------------------------
1 | using System.Web;
2 | using System.Web.UI;
3 |
4 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
5 | {
6 | public class CheckTracing : IAuditCheck
7 | {
8 | public string Id => "CheckTracing";
9 |
10 | public bool LazyLoad => false;
11 |
12 | public CheckResult Execute()
13 | {
14 | var result = new CheckResult(SeverityEnum.Unverified, Id);
15 | var page = HttpContext.Current.Handler as Page;
16 |
17 | if (page != null)
18 | {
19 | result.Severity = page.TraceEnabled ? SeverityEnum.Failure : SeverityEnum.Pass;
20 | }
21 | return result;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckUnexpectedExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
5 | {
6 | public class CheckUnexpectedExtensions : IAuditCheck
7 | {
8 | public string Id => "CheckUnexpectedExtensions";
9 |
10 | public bool LazyLoad => true;
11 |
12 | public CheckResult Execute()
13 | {
14 | var result = new CheckResult(SeverityEnum.Unverified, Id);
15 | var invalidFolders = new List();
16 | var investigatefiles = Utility.FindUnexpectedExtensions(invalidFolders).ToList();
17 | if (investigatefiles.Count > 0)
18 | {
19 | result.Severity = SeverityEnum.Failure;
20 | foreach (var filename in investigatefiles)
21 | {
22 | result.Notes.Add("file:" + filename);
23 | }
24 | }
25 | else
26 | {
27 | result.Severity = SeverityEnum.Pass;
28 | }
29 |
30 | if (invalidFolders.Count > 0)
31 | {
32 | var folders = string.Join("", invalidFolders.Select(f => $"
{f}
").ToArray());
33 | result.Notes.Add($"
The following folders are inaccessible due to permission restrictions:
{folders}");
34 | }
35 | return result;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/Components/Checks/CheckViewstatemac.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web;
3 | using System.Web.UI;
4 |
5 | namespace DNN.Modules.SecurityAnalyzer.Components.Checks
6 | {
7 | public class CheckViewstatemac : IAuditCheck
8 | {
9 | public string Id => "CheckViewstatemac";
10 |
11 | public bool LazyLoad => false;
12 |
13 | public CheckResult Execute()
14 | {
15 | var result = new CheckResult(SeverityEnum.Unverified, Id);
16 | try
17 | {
18 | var page = HttpContext.Current.Handler as Page;
19 |
20 | if (page != null)
21 | {
22 | if (page.EnableViewStateMac == false)
23 | {
24 | result.Severity = SeverityEnum.Failure;
25 | }
26 | else
27 | {
28 | result.Severity = SeverityEnum.Pass;
29 | }
30 | }
31 | }
32 | catch (Exception ex)
33 | {
34 | throw (ex);
35 | }
36 | return result;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/Components/EscapedString.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DNNCommunity/DNN.SecurityAnalyzer/c4fd5bc4cccface170f959ad9d19fa885c5baba6/Components/EscapedString.cs
--------------------------------------------------------------------------------
/Components/FeatureController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using DotNetNuke.Common;
5 | using DotNetNuke.Common.Utilities;
6 | using DotNetNuke.Entities.Modules;
7 | using DotNetNuke.Entities.Modules.Definitions;
8 | using DotNetNuke.Entities.Tabs;
9 | using DotNetNuke.Security;
10 | using DotNetNuke.Security.Permissions;
11 |
12 | namespace DNN.Modules.SecurityAnalyzer.Components
13 | {
14 | public class FeatureController : IUpgradeable
15 | {
16 | public string UpgradeModule(string version)
17 | {
18 | switch (version)
19 | {
20 | case "01.00.00":
21 | //Add Extensions Host Page
22 | var moduleDefId = GetModuleDefinition("SecurityAnalyzer", "SecurityAnalyzer");
23 | var auditPage = AddHostPage("Security Analyzer", "Audit site security for best practices.",
24 | "~/DesktopModules/DNNCorp/SecurityAnalyzer/Images/Extensions_16x16_Standard.png", "~/DesktopModules/DNNCorp/SecurityAnalyzer/Images/Extensions_32x32_Standard.png", true);
25 |
26 | var moduleid = AddModuleToPage(auditPage, moduleDefId, "Security Analyzer",
27 | "~/DesktopModules/DNNCorp/SecurityAnalyzer/Images/Extensions_32x32_Standard.png");
28 |
29 | break;
30 | case "08.00.02":
31 | Utility.CleanUpInstallerFiles();
32 | break;
33 | case "08.01.01":
34 | if (TelerikAssemblyExists())
35 | {
36 | UpdateTelerikEncryptionKey("Telerik.Web.UI.DialogParametersEncryptionKey");
37 | }
38 | break;
39 | case "08.01.04":
40 | Utility.UpdateTelerikSkinsSettings();
41 | break;
42 | }
43 |
44 | return String.Empty;
45 | }
46 |
47 | private static int AddModuleToPage(TabInfo page, int moduleDefId, string moduleTitle, string moduleIconFile)
48 | {
49 | //Call overload with InheritPermisions=True
50 | return AddModuleToPage(page, moduleDefId, moduleTitle, moduleIconFile, true);
51 | }
52 |
53 | public static int AddModuleToPage(TabInfo page, int moduleDefId, string moduleTitle, string moduleIconFile,
54 | bool inheritPermissions)
55 | {
56 | var moduleController = new ModuleController();
57 | ModuleInfo moduleInfo;
58 | var moduleId = Null.NullInteger;
59 |
60 | if ((page != null))
61 | {
62 | var isDuplicate = false;
63 | foreach (var kvp in moduleController.GetTabModules(page.TabID))
64 | {
65 | moduleInfo = kvp.Value;
66 | if (moduleInfo.ModuleDefID == moduleDefId)
67 | {
68 | isDuplicate = true;
69 | moduleId = moduleInfo.ModuleID;
70 | }
71 | }
72 |
73 | if (!isDuplicate)
74 | {
75 | moduleInfo = new ModuleInfo
76 | {
77 | ModuleID = Null.NullInteger,
78 | PortalID = page.PortalID,
79 | TabID = page.TabID,
80 | ModuleOrder = -1,
81 | ModuleTitle = moduleTitle,
82 | PaneName = Globals.glbDefaultPane,
83 | ModuleDefID = moduleDefId,
84 | CacheTime = 0,
85 | IconFile = moduleIconFile,
86 | AllTabs = false,
87 | Visibility = VisibilityState.None,
88 | InheritViewPermissions = inheritPermissions
89 | };
90 |
91 | try
92 | {
93 | moduleId = moduleController.AddModule(moduleInfo);
94 | }
95 | catch (Exception)
96 | {
97 | //DnnLog.Error(exc);
98 | }
99 | }
100 | }
101 |
102 | return moduleId;
103 | }
104 |
105 | public static int AddModuleToPage(string tabPath, int portalId, int moduleDefId, string moduleTitle,
106 | string moduleIconFile, bool inheritPermissions)
107 | {
108 | var tabController = new TabController();
109 | var moduleId = Null.NullInteger;
110 |
111 | var tabID = TabController.GetTabByTabPath(portalId, tabPath, Null.NullString);
112 | if ((tabID != Null.NullInteger))
113 | {
114 | var tab = tabController.GetTab(tabID, portalId, true);
115 | if ((tab != null))
116 | {
117 | moduleId = AddModuleToPage(tab, moduleDefId, moduleTitle, moduleIconFile, inheritPermissions);
118 | }
119 | }
120 | return moduleId;
121 | }
122 |
123 | private static int GetModuleDefinition(string desktopModuleName, string moduleDefinitionName)
124 | {
125 | // get desktop module
126 | var desktopModule = DesktopModuleController.GetDesktopModuleByModuleName(desktopModuleName, Null.NullInteger);
127 | if (desktopModule == null)
128 | {
129 | return -1;
130 | }
131 |
132 | // get module definition
133 | var objModuleDefinition = ModuleDefinitionController.GetModuleDefinitionByFriendlyName(
134 | moduleDefinitionName, desktopModule.DesktopModuleID);
135 | if (objModuleDefinition == null)
136 | {
137 | return -1;
138 | }
139 |
140 |
141 | return objModuleDefinition.ModuleDefID;
142 | }
143 |
144 | public static TabInfo AddHostPage(string tabName, string description, string tabIconFile,
145 | string tabIconFileLarge, bool isVisible)
146 | {
147 | var tabController = new TabController();
148 | var hostPage = tabController.GetTabByName("Host", Null.NullInteger);
149 |
150 | if ((hostPage != null))
151 | {
152 | return AddPage(hostPage, tabName, description, tabIconFile, tabIconFileLarge, isVisible,
153 | new TabPermissionCollection(), true);
154 | }
155 | return null;
156 | }
157 |
158 | private static TabInfo AddPage(TabInfo parentTab, string tabName, string description, string tabIconFile,
159 | string tabIconFileLarge, bool isVisible, TabPermissionCollection permissions, bool isAdmin)
160 | {
161 | var parentId = Null.NullInteger;
162 | var portalId = Null.NullInteger;
163 |
164 | if ((parentTab != null))
165 | {
166 | parentId = parentTab.TabID;
167 | portalId = parentTab.PortalID;
168 | }
169 |
170 |
171 | return AddPage(portalId, parentId, tabName, description, tabIconFile, tabIconFileLarge, isVisible,
172 | permissions, isAdmin);
173 | }
174 |
175 | /// -----------------------------------------------------------------------------
176 | ///
177 | /// AddPage adds a Tab Page
178 | ///
179 | /// The Id of the Portal
180 | /// The Id of the Parent Tab
181 | /// The Name to give this new Tab
182 | /// Description.
183 | /// The Icon for this new Tab
184 | /// The large Icon for this new Tab
185 | /// A flag indicating whether the tab is visible
186 | /// Page Permissions Collection for this page
187 | /// Is and admin page
188 | private static TabInfo AddPage(int portalId, int parentId, string tabName, string description,
189 | string tabIconFile, string tabIconFileLarge, bool isVisible, TabPermissionCollection permissions,
190 | bool isAdmin)
191 | {
192 | var tabController = new TabController();
193 |
194 | var tab = tabController.GetTabByName(tabName, portalId, parentId);
195 |
196 | if (tab == null || tab.ParentId != parentId)
197 | {
198 | tab = new TabInfo
199 | {
200 | TabID = Null.NullInteger,
201 | PortalID = portalId,
202 | TabName = tabName,
203 | Title = "",
204 | Description = description,
205 | KeyWords = "",
206 | IsVisible = isVisible,
207 | DisableLink = false,
208 | ParentId = parentId,
209 | IconFile = tabIconFile,
210 | IconFileLarge = tabIconFileLarge,
211 | IsDeleted = false
212 | };
213 | tab.TabID = tabController.AddTab(tab, !isAdmin);
214 |
215 | if (((permissions != null)))
216 | {
217 | foreach (TabPermissionInfo tabPermission in permissions)
218 | {
219 | tab.TabPermissions.Add(tabPermission, true);
220 | }
221 | TabPermissionController.SaveTabPermissions(tab);
222 | }
223 | }
224 |
225 | return tab;
226 | }
227 |
228 | private bool TelerikAssemblyExists()
229 | {
230 | return File.Exists(Path.Combine(Globals.ApplicationMapPath, "bin\\Telerik.Web.UI.dll"));
231 | }
232 |
233 | private static string UpdateTelerikEncryptionKey(string keyName)
234 | {
235 | var strError = "";
236 | var currentKey = Config.GetSetting(keyName);
237 | if (string.IsNullOrEmpty(currentKey) || currentKey.Length < 40)
238 | {
239 | try
240 | {
241 | //save the current config file
242 | Config.BackupConfig();
243 |
244 | //decrypt the web.config if needed.
245 | string providerName;
246 | var decrypted = Utility.DecryptConfigFile(out providerName);
247 |
248 | //open the web.config
249 | var xmlConfig = Config.Load();
250 |
251 | //create a random Telerik encryption key and add it under
252 | var newKey = new PortalSecurity().CreateKey(32);
253 | newKey = Convert.ToBase64String(Encoding.ASCII.GetBytes(newKey));
254 | Config.AddAppSetting(xmlConfig, keyName, newKey);
255 |
256 | //save the web.config
257 | strError += Config.Save(xmlConfig) + Environment.NewLine;
258 |
259 | if (decrypted)
260 | {
261 | Utility.EncryptConfigFile(providerName);
262 | }
263 | }
264 | catch (Exception ex)
265 | {
266 | strError += ex.Message;
267 | }
268 | }
269 | return strError;
270 | }
271 | }
272 | }
--------------------------------------------------------------------------------
/Components/FileExtensionWhitelist.cs:
--------------------------------------------------------------------------------
1 | #region Copyright
2 | //
3 | // DotNetNuke® - http://www.dotnetnuke.com
4 | // Copyright (c) 2002-2017
5 | // by DotNetNuke Corporation
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
8 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
9 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
10 | // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions
13 | // of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
16 | // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
18 | // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19 | // DEALINGS IN THE SOFTWARE.
20 | #endregion
21 |
22 | using System;
23 | using System.Collections.Generic;
24 | using System.Linq;
25 |
26 | namespace DNN.Modules.SecurityAnalyzer.Components
27 | {
28 | public class FileExtensionWhitelist
29 | {
30 | private readonly List _extensions;
31 |
32 | ///
33 | /// Initializes a new instance of the FileExtensionWhiteList class.
34 | ///
35 | /// a comma seperated list of file extensions with no '.'
36 | /// should match the format used in the FileExtensions Host setting specifically it
37 | /// should not have an '.' in the extensions (e.g. txt,jpg,png,doc)
38 | public FileExtensionWhitelist(string extensionList)
39 | {
40 | _extensions = EscapedString.Seperate(extensionList.ToLowerInvariant()).Select(item => "." + item).ToList();
41 | }
42 |
43 | ///
44 | /// Returns a string suitale for display to an end user
45 | ///
46 | /// A String of the whitelist extensions formatted for display to an end user
47 | public string ToDisplayString()
48 | {
49 | return ToDisplayString(null);
50 | }
51 |
52 | ///
53 | /// Formats the extension whitelist appropriate for display to an end user
54 | ///
55 | /// A list of additionalExtensions to add to the current extensions
56 | /// case and '.' prefix will be corrected, and duplicates will be excluded from the string
57 | /// A String of the whitelist extensions formatted for storage display to an end user
58 | public string ToDisplayString(IEnumerable additionalExtensions)
59 | {
60 | IEnumerable allExtensions = CombineLists(additionalExtensions);
61 | return "*" + string.Join(", *", allExtensions.ToArray());
62 | }
63 |
64 | ///
65 | /// The list of extensions in the whitelist.
66 | ///
67 | /// All extensions are lowercase and prefixed with a '.'
68 | public IEnumerable AllowedExtensions
69 | {
70 | get
71 | {
72 | return _extensions;
73 | }
74 | }
75 |
76 | ///
77 | /// Indicates if the file extension is permitted by the Host Whitelist
78 | ///
79 | /// The file extension with or without preceding '.'
80 | /// True if extension is in whitelist or whitelist is empty. False otherwise.
81 | public bool IsAllowedExtension(String extension)
82 | {
83 | return IsAllowedExtension(extension, null);
84 | }
85 |
86 | ///
87 | /// Indicates if the file extension is permitted by the Host Whitelist
88 | ///
89 | /// The file extension with or without preceding '.'
90 | ///
91 | /// True if extension is in whitelist or whitelist is empty. False otherwise.
92 | public bool IsAllowedExtension(string extension, IEnumerable additionalExtensions)
93 | {
94 | List allExtensions = CombineLists(additionalExtensions).ToList();
95 | if (!allExtensions.Any())
96 | {
97 | return true;
98 | }
99 |
100 | if (!extension.StartsWith("."))
101 | {
102 | extension = "." + extension.ToLowerInvariant();
103 | }
104 | else
105 | {
106 | extension = extension.ToLowerInvariant();
107 | }
108 |
109 | return allExtensions.Contains(extension);
110 | }
111 |
112 | public override string ToString()
113 | {
114 | return ToDisplayString();
115 | }
116 |
117 | ///
118 | /// Formats the extension whitelist appropriate for storage in the Host setting
119 | ///
120 | /// A String of the whitelist extensions formatted for storage as a Host setting
121 | public string ToStorageString()
122 | {
123 | return ToStorageString(null);
124 | }
125 |
126 | ///
127 | /// Formats the extension whitelist appropriate for storage in the Host setting
128 | ///
129 | /// A list of additionalExtensions to add to the current extensions
130 | /// case and '.' prefix will be corrected, and duplicates will be excluded from the string
131 | /// A String of the whitelist extensions formatted for storage as a Host setting
132 | public string ToStorageString(IEnumerable additionalExtensions)
133 | {
134 | IEnumerable allExtensions = CombineLists(additionalExtensions);
135 | var leadingDotRemoved = allExtensions.Select(ext => ext.Substring(1));
136 | return EscapedString.Combine(leadingDotRemoved);
137 | }
138 |
139 | private IEnumerable CombineLists(IEnumerable additionalExtensions)
140 | {
141 | if(additionalExtensions == null)
142 | {
143 | return _extensions;
144 | }
145 |
146 | //toList required to ensure that multiple enumerations of the list are possible
147 | var additionalExtensionsList = additionalExtensions.ToList();
148 | if( !additionalExtensionsList.Any())
149 | {
150 | return _extensions;
151 | }
152 |
153 | var normalizedExtensions = NormalizeExtensions(additionalExtensionsList);
154 | return _extensions.Union(normalizedExtensions);
155 | }
156 |
157 | private IEnumerable NormalizeExtensions(IEnumerable additionalExtensions)
158 | {
159 | return additionalExtensions.Select(ext => (ext.StartsWith(".") ? ext : "." + ext).ToLowerInvariant());
160 | }
161 | }
162 | }
--------------------------------------------------------------------------------
/Components/IAuditCheck.cs:
--------------------------------------------------------------------------------
1 | namespace DNN.Modules.SecurityAnalyzer.Components
2 | {
3 | public interface IAuditCheck
4 | {
5 | string Id { get; }
6 |
7 | bool LazyLoad { get; }
8 |
9 | CheckResult Execute();
10 | }
11 | }
--------------------------------------------------------------------------------
/Components/SeverityEnum.cs:
--------------------------------------------------------------------------------
1 | namespace DNN.Modules.SecurityAnalyzer.Components
2 | {
3 | public enum SeverityEnum
4 | {
5 | Pass,
6 | Warning,
7 | Failure,
8 | Unverified
9 | }
10 | }
--------------------------------------------------------------------------------
/Components/Utility.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Security.Cryptography;
8 | using System.Text.RegularExpressions;
9 | using System.Web.Configuration;
10 | using System.Xml;
11 | using DotNetNuke.Application;
12 | using DotNetNuke.Common;
13 | using DotNetNuke.Common.Utilities;
14 | using DotNetNuke.Data;
15 | using Assembly = System.Reflection.Assembly;
16 |
17 | namespace DNN.Modules.SecurityAnalyzer.Components
18 | {
19 | public class Utility
20 | {
21 | private static readonly IList ExcludedFilePathRegexList = new List()
22 | {
23 | new Regex(Regex.Escape("\\App_Data\\ClientDependency"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
24 | new Regex(Regex.Escape("\\App_Data\\Search"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
25 | new Regex(Regex.Escape("\\d+-System\\Cache\\Pages"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
26 | new Regex(Regex.Escape("\\d+-System\\Thumbnailsy"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
27 | new Regex(Regex.Escape("\\Portals\\_default\\Logs"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
28 | new Regex(Regex.Escape("\\App_Data\\_imagecache"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
29 | new Regex(Regex.Escape(AppDomain.CurrentDomain.BaseDirectory + "Default.aspx"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
30 | new Regex(Regex.Escape(AppDomain.CurrentDomain.BaseDirectory + "Default.aspx.cs"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
31 | new Regex(Regex.Escape(AppDomain.CurrentDomain.BaseDirectory + "web.config"), RegexOptions.Compiled | RegexOptions.IgnoreCase),
32 | };
33 |
34 | private const long MaxFileSize = 1024*1024*10; //10M
35 |
36 | private const int ModifiedFilesCount = 50;
37 |
38 | ///
39 | /// delete unnedded installwizard files
40 | ///
41 | public static void CleanUpInstallerFiles()
42 | {
43 | var files = new List
44 | {
45 | "DotNetNuke.install.config",
46 | "DotNetNuke.install.config.resources",
47 | "InstallWizard.aspx",
48 | "InstallWizard.aspx.cs",
49 | "InstallWizard.aspx.designer.cs",
50 | "UpgradeWizard.aspx",
51 | "UpgradeWizard.aspx.cs",
52 | "UpgradeWizard.aspx.designer.cs",
53 | "Install.aspx",
54 | "Install.aspx.cs",
55 | "Install.aspx.designer.cs",
56 | };
57 |
58 | foreach (var file in files)
59 | {
60 | try
61 | {
62 | FileSystemUtils.DeleteFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Install\\" + file));
63 | }
64 | catch (Exception)
65 | {
66 | //do nothing.
67 | }
68 | }
69 | }
70 |
71 | ///
72 | /// search all files in the website for matching text
73 | ///
74 | /// the matching text
75 | /// ienumerable of file names
76 | public static IEnumerable SearchFiles(string searchText)
77 | {
78 | try
79 | {
80 | var fileList = GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.*", SearchOption.AllDirectories);
81 | var queryMatchingFiles =
82 | from file in fileList
83 | let fileText = GetFileText(file)
84 | let fileInfo = new FileInfo(file)
85 | where fileText.IndexOf(searchText, StringComparison.InvariantCultureIgnoreCase) > -1
86 | select fileInfo.Name + " (" + fileInfo.LastWriteTime.ToString(CultureInfo.InvariantCulture) + ")";
87 | return queryMatchingFiles;
88 | }
89 | catch
90 | {
91 | //suppress any unexpected error
92 | }
93 | return null;
94 | }
95 |
96 | ///
97 | /// search all website files for files with a potential dangerous extension
98 | ///
99 | ///
100 | public static IEnumerable FindUnexpectedExtensions(IList invalidFolders)
101 | {
102 | var files = GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.*", SearchOption.AllDirectories, invalidFolders)
103 | .Where(s => s.EndsWith(".asp", StringComparison.InvariantCultureIgnoreCase) || s.EndsWith(".php", StringComparison.InvariantCultureIgnoreCase));
104 | return files;
105 | }
106 |
107 | ///
108 | /// search all website files which are hidden or system.
109 | ///
110 | ///
111 | public static IEnumerable FineHiddenSystemFiles()
112 | {
113 | var files = GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.*", SearchOption.AllDirectories)
114 | .Where(f =>
115 | {
116 | if (Path.GetFileName(f)?.Equals("thumbs.db", StringComparison.OrdinalIgnoreCase) == true)
117 | {
118 | return false;
119 | }
120 |
121 | var attributes = File.GetAttributes(f);
122 | return (attributes & FileAttributes.Hidden) != 0 || (attributes & FileAttributes.System) != 0;
123 | });
124 | return files;
125 | }
126 |
127 | public static string SearchDatabase(string searchText)
128 | {
129 | var results = "";
130 | var dataProvider = DataProvider.Instance();
131 | var rowCount = 0;
132 | try
133 | {
134 | var dr = dataProvider.ExecuteReader("SecurityAnalyzer_SearchAllTables", searchText);
135 | while (dr.Read())
136 | {
137 | rowCount = rowCount + 1;
138 | results = results + dr["ColumnName"] + ":" + dr["ColumnValue"] + " ";
139 | }
140 | }
141 | catch
142 | {
143 | // ignore
144 | }
145 | results = "Database instances Found:" + rowCount + " " + results;
146 | return results;
147 | }
148 |
149 | public static XmlDocument LoadFileSumData()
150 | {
151 | using (
152 | var stream =
153 | Assembly.GetExecutingAssembly()
154 | .GetManifestResourceStream("DNN.Modules.SecurityAnalyzer.Resources.sums.resources"))
155 | {
156 | if (stream != null)
157 | {
158 | var xmlDocument = new XmlDocument();
159 | xmlDocument.Load(stream);
160 |
161 | return xmlDocument;
162 | }
163 | else
164 | {
165 | return null;
166 | }
167 | }
168 | }
169 |
170 | public static string GetFileCheckSum(string fileName)
171 | {
172 | using (var cryptographyProvider = CreateCryptographyProvider())
173 | {
174 | if (cryptographyProvider != null)
175 | {
176 | using (var stream = File.OpenRead(fileName))
177 | {
178 | return BitConverter.ToString(cryptographyProvider.ComputeHash(stream)).Replace("-", "")
179 | .ToLowerInvariant();
180 | }
181 | }
182 | }
183 |
184 | return string.Empty;
185 | }
186 |
187 | public static string GetApplicationVersion()
188 | {
189 | return DotNetNukeContext.Current.Application.Version.ToString(3);
190 | }
191 |
192 | public static string GetApplicationType()
193 | {
194 | switch (DotNetNukeContext.Current.Application.Name)
195 | {
196 | case "DNNCORP.CE":
197 | return "Platform";
198 | case "DNNCORP.XE":
199 | case "DNNCORP.PE":
200 | return "Content";
201 | case "DNNCORP.SOCIAL":
202 | return "Social";
203 | default:
204 | return "Platform";
205 | }
206 | }
207 |
208 | public static IList GetLastModifiedFiles()
209 | {
210 | var files = GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.*", SearchOption.AllDirectories)
211 | .Where(f => !ExcludedFilePathRegexList.Any(r => r.IsMatch(f)))
212 | .Select(f => new FileInfo(f))
213 | .OrderByDescending(f => f.LastWriteTime)
214 | .Take(ModifiedFilesCount).ToList();
215 |
216 | return files;
217 | }
218 |
219 | public static IList GetLastModifiedExecutableFiles()
220 | {
221 | var executableExtensions = new List() {".asp", ".aspx", ".php"};
222 | var files = GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.*", SearchOption.AllDirectories)
223 | .Where(f =>
224 | {
225 | var extension = Path.GetExtension(f);
226 | return extension != null && executableExtensions.Contains(extension.ToLowerInvariant());
227 | }).ToList();
228 | files.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Default.aspx.cs"));
229 | files.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "web.config"));
230 |
231 | var defaultPage = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Default.aspx");
232 | if (!files.Contains(defaultPage))
233 | {
234 | files.Add(defaultPage);
235 | }
236 |
237 | return files
238 | .Select(f => new FileInfo(f))
239 | .OrderByDescending(f => f.LastWriteTime)
240 | .Take(ModifiedFilesCount).ToList();
241 |
242 | }
243 |
244 | private static string GetFileText(string name)
245 | {
246 | var fileContents = String.Empty;
247 | try
248 | {
249 | // If the file has been deleted since we took
250 | // the snapshot, ignore it and return the empty string.
251 | if (IsReadable(name))
252 | {
253 | fileContents = File.ReadAllText(name);
254 | }
255 | }
256 | catch (Exception)
257 | {
258 |
259 | //might be a locking issue
260 | }
261 |
262 | return fileContents;
263 | }
264 |
265 | private static bool IsReadable(string name)
266 | {
267 | if (!File.Exists(name))
268 | {
269 | return false;
270 | }
271 |
272 | var file = new FileInfo(name);
273 | if (file.Length > MaxFileSize) //when file large than 10M, then don't read it.
274 | {
275 | return false;
276 | }
277 |
278 | return true;
279 | }
280 |
281 | private static SHA256 CreateCryptographyProvider()
282 | {
283 | try
284 | {
285 | var property = typeof(CryptoConfig).GetProperty("AllowOnlyFipsAlgorithms", BindingFlags.Public | BindingFlags.Static);
286 | if (property == null)
287 | {
288 | return SHA256.Create();
289 | }
290 |
291 | if ((bool)property.GetValue(null, null))
292 | {
293 | return SHA256.Create("System.Security.Cryptography.SHA256CryptoServiceProvider");
294 | }
295 |
296 | return SHA256.Create("System.Security.Cryptography.SHA256Cng");
297 | }
298 | catch (Exception)
299 | {
300 | return null;
301 | }
302 | }
303 |
304 | ///
305 | /// Recursively finds file
306 | ///
307 | ///
308 | private static IEnumerable GetFiles(string path, string searchPattern, SearchOption searchOption)
309 | {
310 | IList invalidFolders = new List();
311 | return GetFiles(path, searchPattern, searchOption, invalidFolders);
312 | }
313 |
314 | ///
315 | /// Recursively finds file
316 | ///
317 | ///
318 | private static IEnumerable GetFiles(string path, string searchPattern, SearchOption searchOption, IList invalidFolders)
319 | {
320 | try
321 | {
322 | //Looking at the root folder only. There should not be any permission issue here.
323 | var files = Directory.GetFiles(path, searchPattern, SearchOption.TopDirectoryOnly).ToList();
324 |
325 | if (searchOption == SearchOption.AllDirectories)
326 | {
327 | var folders = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly);
328 | foreach (var folder in folders)
329 | {
330 | //recursive call to the same method
331 | var fs = GetFiles(folder, searchPattern, searchOption, invalidFolders);
332 | files.AddRange(fs);
333 | }
334 | }
335 |
336 | return files;
337 | }
338 | catch (Exception)
339 | {
340 | invalidFolders.Add(path);
341 | return new List();
342 | }
343 | }
344 |
345 | //DNN-10258: Site loses ability to edit content after Security Patch install
346 | //DNN-10259: Site loses ability to add pages after Security Patch install
347 | public static bool UpdateTelerikSkinsSettings()
348 | {
349 | const string skinAssemblyKey = "Telerik.Web.SkinsAssembly";
350 | var assemblyFile = Path.Combine(Globals.ApplicationMapPath, "bin\\Telerik.Web.UI.Skins.dll");
351 | if (File.Exists(assemblyFile))
352 | {
353 |
354 | var asmFullName = Assembly.LoadFile(assemblyFile).GetName().ToString();
355 |
356 | var appSetting = Config.GetSetting(skinAssemblyKey);
357 | if (string.IsNullOrEmpty(appSetting) || !appSetting.Equals(asmFullName, StringComparison.InvariantCultureIgnoreCase))
358 | {
359 | //save the current config file
360 | Config.BackupConfig();
361 |
362 | //decrypt the web.config if needed.
363 | string providerName;
364 | var decrypted = Utility.DecryptConfigFile(out providerName);
365 |
366 | //open the web.config
367 | var config = Config.Load();
368 |
369 | Config.AddAppSetting(config, skinAssemblyKey, asmFullName);
370 | Config.Save(config);
371 |
372 | if (decrypted)
373 | {
374 | EncryptConfigFile(providerName);
375 | }
376 |
377 | return true;
378 | }
379 | }
380 |
381 | return false;
382 | }
383 |
384 | public static bool DecryptConfigFile(out string providerName)
385 | {
386 | providerName = string.Empty;
387 | var config = WebConfigurationManager.OpenWebConfiguration("~/");
388 | var section = config.GetSection("appSettings");
389 | if (section != null && section.SectionInformation.IsProtected)
390 | {
391 | providerName = section.SectionInformation.ProtectionProvider.Name;
392 | section.SectionInformation.UnprotectSection();
393 | config.Save();
394 |
395 | return true;
396 | }
397 |
398 | return false;
399 | }
400 |
401 | public static void EncryptConfigFile(string providerName)
402 | {
403 | var config = WebConfigurationManager.OpenWebConfiguration("~/");
404 | var section = config.GetSection("appSettings");
405 | if (section != null)
406 | {
407 | section.SectionInformation.ProtectSection(providerName);
408 | config.Save();
409 | }
410 | }
411 | }
412 | }
--------------------------------------------------------------------------------
/DNN.Modules.SecurityAnalyzer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}
11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
12 | Library
13 | Properties
14 | DNN.Modules.SecurityAnalyzer
15 | DNN.Modules.SecurityAnalyzer
16 | v3.5
17 | true
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | true
28 | full
29 | false
30 | ..\..\..\bin\
31 | DEBUG;TRACE
32 | prompt
33 | 4
34 |
35 |
36 | pdbonly
37 | true
38 | ..\..\..\bin\
39 | TRACE
40 | prompt
41 | 4
42 |
43 |
44 |
45 | False
46 | References\DotNetNuke.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Code
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | ASPXCodeBehind
88 |
89 |
90 | View.ascx
91 | ASPXCodeBehind
92 |
93 |
94 | View.ascx
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | Designer
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | Designer
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | web.config
140 |
141 |
142 | web.config
143 |
144 |
145 |
146 | 10.0
147 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | True
157 | False
158 | 0
159 | /
160 | http://localhost:30900/
161 | True
162 | http://dnndev.me
163 | False
164 | False
165 |
166 |
167 | False
168 |
169 |
170 |
171 |
172 |
173 | zip
174 | SecurityAnalyzer
175 | SecurityAnalyzer
176 | $(SolutionDir)\packages\MSBuildTasks.1.4.0.61\tools
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/DNN.Modules.SecurityAnalyzer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DNN.Modules.SecurityAnalyzer", "DNN.Modules.SecurityAnalyzer.csproj", "{7D61A32C-0F21-453F-A981-BD8E5A3A5304}"
5 | EndProject
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{62D09D51-D869-443F-AD88-04B84DD2915A}"
7 | ProjectSection(SolutionItems) = preProject
8 | .build\MSBuild.Community.Tasks.dll = .build\MSBuild.Community.Tasks.dll
9 | .build\MSBuild.Community.Tasks.targets = .build\MSBuild.Community.Tasks.targets
10 | EndProjectSection
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {7D61A32C-0F21-453F-A981-BD8E5A3A5304}.Release|Any CPU.Build.0 = Release|Any CPU
22 | EndGlobalSection
23 | GlobalSection(SolutionProperties) = preSolution
24 | HideSolutionNode = FALSE
25 | EndGlobalSection
26 | EndGlobal
27 |
--------------------------------------------------------------------------------
/Images/Extensions_16x16_Standard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DNNCommunity/DNN.SecurityAnalyzer/c4fd5bc4cccface170f959ad9d19fa885c5baba6/Images/Extensions_16x16_Standard.png
--------------------------------------------------------------------------------
/Images/Extensions_32x32_Standard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DNNCommunity/DNN.SecurityAnalyzer/c4fd5bc4cccface170f959ad9d19fa885c5baba6/Images/Extensions_32x32_Standard.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 DNN Community
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 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 |
2 |
License
3 | DNN - http://www.dnnsoftware.com
4 | Copyright (c) 2002-2017
5 | by DNN Corporation
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 |
9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 |
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 |