Sebros/fixes (#8141)

* Encoding translated user inputs

* Ensure the media whitelist is enforced
This commit is contained in:
Benedek Farkas
2018-12-03 14:17:10 +01:00
committed by GitHub
parent bb6c8ed624
commit ff20581899
31 changed files with 143 additions and 92 deletions

View File

@@ -1,8 +1,10 @@
using System.Linq; using System.Linq;
using System.Web;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents.Settings; using Orchard.Core.Contents.Settings;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.Html;
using Orchard.Security; using Orchard.Security;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
@@ -44,7 +46,7 @@ namespace Orchard.Core.Contents {
var createRouteValues = cim.CreateRouteValues; var createRouteValues = cim.CreateRouteValues;
// review: the display name should be a LocalizedString // review: the display name should be a LocalizedString
if (createRouteValues.Any()) if (createRouteValues.Any())
menu.Add(T(contentTypeDefinition.DisplayName), "5", item => item.Action(cim.CreateRouteValues["Action"] as string, cim.CreateRouteValues["Controller"] as string, cim.CreateRouteValues) menu.Add(T.Encode(contentTypeDefinition.DisplayName), "5", item => item.Action(cim.CreateRouteValues["Action"] as string, cim.CreateRouteValues["Controller"] as string, cim.CreateRouteValues)
// Apply "CreateContent" permission for the content type // Apply "CreateContent" permission for the content type
.Permission(DynamicPermissions.CreateDynamicPermission(DynamicPermissions.PermissionTemplates[Permissions.CreateContent.Name], contentTypeDefinition))); .Permission(DynamicPermissions.CreateDynamicPermission(DynamicPermissions.PermissionTemplates[Permissions.CreateContent.Name], contentTypeDefinition)));
} }

View File

@@ -19,7 +19,7 @@
@helper MainFileUrl(Asset asset, Func<Asset, string> mainFileUrl, string linkText) { @helper MainFileUrl(Asset asset, Func<Asset, string> mainFileUrl, string linkText) {
if (!String.IsNullOrEmpty(mainFileUrl(asset))) { if (!String.IsNullOrEmpty(mainFileUrl(asset))) {
<a href="@mainFileUrl(asset)">@T(linkText)</a> <a href="@mainFileUrl(asset)">@T.Encode(linkText)</a>
} }
} }

View File

@@ -71,14 +71,14 @@
@helper ThumbnailUpload(string caption) { @helper ThumbnailUpload(string caption) {
<fieldset> <fieldset>
<label>@T(caption)</label> <label>@T.Encode(caption)</label>
@AsyncUpload("ThumbnailFile", Html.FieldNameFor(m => m.WamsThumbnail), Model.WamsThumbnail, allowedExtensions : null) @AsyncUpload("ThumbnailFile", Html.FieldNameFor(m => m.WamsThumbnail), Model.WamsThumbnail, allowedExtensions : null)
</fieldset> </fieldset>
} }
@helper SubtitleUpload(string caption) { @helper SubtitleUpload(string caption) {
<fieldset> <fieldset>
<label>@T(caption)</label> <label>@T.Encode(caption)</label>
@if (Model.SubtitleLanguages.Any()) { @if (Model.SubtitleLanguages.Any()) {
@AsyncUpload("SubtitleFile", Html.FieldNameFor(m => m.WamsSubtitle), Model.WamsSubtitle) @AsyncUpload("SubtitleFile", Html.FieldNameFor(m => m.WamsSubtitle), Model.WamsSubtitle)
<div> <div>

View File

@@ -11,7 +11,7 @@
<fieldset data-upload-accept-file-types="@acceptFileTypes" <fieldset data-upload-accept-file-types="@acceptFileTypes"
data-upload-fallback-url="@Url.Action("Upload", "Media", new { area = "Orchard.Azure.MediaServices" })" data-upload-fallback-url="@Url.Action("Upload", "Media", new { area = "Orchard.Azure.MediaServices" })"
data-generate-asset-url="@Url.Action("GenerateWamsAsset", "Asset", new { area = "Orchard.Azure.MediaServices" })"> data-generate-asset-url="@Url.Action("GenerateWamsAsset", "Asset", new { area = "Orchard.Azure.MediaServices" })">
<label>@T(caption)</label> <label>@T.Encode(caption)</label>
<input type="hidden" name="@String.Format("{0}.OriginalFileName", prefix)" value="@tempFileViewModel.OriginalFileName" /> <input type="hidden" name="@String.Format("{0}.OriginalFileName", prefix)" value="@tempFileViewModel.OriginalFileName" />
<input type="hidden" name="@String.Format("{0}.TemporaryFileName", prefix)" value="@tempFileViewModel.TemporaryFileName" /> <input type="hidden" name="@String.Format("{0}.TemporaryFileName", prefix)" value="@tempFileViewModel.TemporaryFileName" />
<input type="hidden" name="@String.Format("{0}.FileSize", prefix)" value="@tempFileViewModel.FileSize" /> <input type="hidden" name="@String.Format("{0}.FileSize", prefix)" value="@tempFileViewModel.FileSize" />
@@ -36,7 +36,7 @@
@helper ThumbnailUpload(string caption) { @helper ThumbnailUpload(string caption) {
<fieldset> <fieldset>
<label>@T(caption)</label> <label>@T.Encode(caption)</label>
<input class="sync-upload-input" name="ThumbnailFile.Proxied" type="file" /> <input class="sync-upload-input" name="ThumbnailFile.Proxied" type="file" />
</fieldset> </fieldset>
} }

View File

@@ -14,7 +14,7 @@
<tbody> <tbody>
@foreach (var locator in locators) { @foreach (var locator in locators) {
<tr> <tr>
<td>@T(locator.Name)</td> <td>@T.Encode(locator.Name)</td>
<td>@locator.Id</td> <td>@locator.Id</td>
<td><a href="@locator.Url" target="_blank">@locator.Url</a></td> <td><a href="@locator.Url" target="_blank">@locator.Url</a></td>
</tr> </tr>

View File

@@ -2,7 +2,7 @@
<div class="summary"> <div class="summary">
<div class="properties"> <div class="properties">
<h3>@Model.DisplayName</h3> <h3>@Model.DisplayName</h3>
@if(!string.IsNullOrWhiteSpace(Model.Description)) {<span class="hint">@T(Model.Description)</span>} @if(!string.IsNullOrWhiteSpace(Model.Description)) {<span class="hint">@T(Html.Encode(Model.Description))</span>}
</div> </div>
<div class="related"> <div class="related">
@Html.ActionLink(T("Edit").ToString(), "EditPart", new { area = "Orchard.ContentTypes", id = Model.Name }) @Html.ActionLink(T("Edit").ToString(), "EditPart", new { area = "Orchard.ContentTypes", id = Model.Name })

View File

@@ -1,5 +1,4 @@
@model Orchard.Fields.Fields.BooleanField @model Orchard.Fields.Fields.BooleanField
@using Orchard.Utility.Extensions;
@using Orchard.Fields.Settings; @using Orchard.Fields.Settings;
@{ @{
var settings = Model.PartFieldDefinition.Settings.GetModel<BooleanFieldSettings>(); var settings = Model.PartFieldDefinition.Settings.GetModel<BooleanFieldSettings>();
@@ -9,22 +8,22 @@
@switch (settings.SelectionMode) { @switch (settings.SelectionMode) {
case SelectionMode.Checkbox: case SelectionMode.Checkbox:
<input type="checkbox" id="@(Html.FieldIdFor(m => m.Value))" value="true" name="@Html.FieldNameFor(m => m.Value)" @if(Model.Value.HasValue && Model.Value.Value) { <text>checked="checked"</text> } /><input name="@Html.FieldNameFor(m => m.Value)" type="hidden" value="false" /> <input type="checkbox" id="@(Html.FieldIdFor(m => m.Value))" value="true" name="@Html.FieldNameFor(m => m.Value)" @if(Model.Value.HasValue && Model.Value.Value) { <text>checked="checked"</text> } /><input name="@Html.FieldNameFor(m => m.Value)" type="hidden" value="false" />
<label class="forcheckbox" for="@(Html.FieldIdFor(m => m.Value))">@T(settings.OnLabel)</label> <label class="forcheckbox" for="@(Html.FieldIdFor(m => m.Value))">@T.Encode(settings.OnLabel)</label>
break; break;
case SelectionMode.Radiobutton: case SelectionMode.Radiobutton:
if (settings.Optional) { if (settings.Optional) {
<div> <div>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-unknown" value="" @if(!Model.Value.HasValue) { <text>checked="checked"</text> } /> <input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-unknown" value="" @if(!Model.Value.HasValue) { <text>checked="checked"</text> } />
<label for="radio-unknown" class="forcheckbox">@T(settings.NotSetLabel)</label> <label for="radio-unknown" class="forcheckbox">@T.Encode(settings.NotSetLabel)</label>
</div> </div>
} }
<div> <div>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-true" value="true" @if (Model.Value.HasValue && Model.Value.Value) { <text>checked="checked"</text> } /> <input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-true" value="true" @if (Model.Value.HasValue && Model.Value.Value) { <text>checked="checked"</text> } />
<label for="radio-true" class="forcheckbox">@T(settings.OnLabel)</label> <label for="radio-true" class="forcheckbox">@T.Encode(settings.OnLabel)</label>
</div> </div>
<div> <div>
<input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-false" value="false" @if (Model.Value.HasValue && !Model.Value.Value) { <text>checked="checked"</text> } /> <input type="radio" name="@Html.FieldNameFor(m => m.Value)" id="radio-false" value="false" @if (Model.Value.HasValue && !Model.Value.Value) { <text>checked="checked"</text> } />
<label for="radio-false" class="forcheckbox">@T(settings.OffLabel)</label> <label for="radio-false" class="forcheckbox">@T.Encode(settings.OffLabel)</label>
</div> </div>
break; break;
case SelectionMode.Dropdown: case SelectionMode.Dropdown:

View File

@@ -33,7 +33,7 @@
if (!string.IsNullOrWhiteSpace(option)) { if (!string.IsNullOrWhiteSpace(option)) {
<div> <div>
<input type="checkbox" name="@Html.FieldNameFor(m => m.SelectedValues)" value="@option" @((Model.SelectedValues != null && Model.SelectedValues.Contains(option)) ? "checked=\"checked\"" : "") class="check-box" id="@Html.FieldIdFor(m => m.SelectedValues)-@index" /> <input type="checkbox" name="@Html.FieldNameFor(m => m.SelectedValues)" value="@option" @((Model.SelectedValues != null && Model.SelectedValues.Contains(option)) ? "checked=\"checked\"" : "") class="check-box" id="@Html.FieldIdFor(m => m.SelectedValues)-@index" />
<label class="forcheckbox" for="@Html.FieldIdFor(m => m.SelectedValues)-@index">@T(option)</label> <label class="forcheckbox" for="@Html.FieldIdFor(m => m.SelectedValues)-@index">@option</label>
</div> </div>
} }
} }

View File

@@ -1,9 +1,7 @@
@using Orchard.Fields.Settings; @{
@using Orchard.Utility.Extensions;
@{
string value = (string)Model.ContentField.Value; string value = (string)Model.ContentField.Value;
if (!string.IsNullOrEmpty(value)) { if (!string.IsNullOrEmpty(value)) {
string name = Model.ContentField.DisplayName; string name = Model.ContentField.DisplayName;
<p class="text-field">@T(name): @value</p> <p class="text-field">@T.Encode(name): @value</p>
} }
} }

View File

@@ -94,6 +94,13 @@ namespace Orchard.ImageEditor.Controllers {
return HttpNotFound(); return HttpNotFound();
} }
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
// skip file if the allowed extensions is defined and doesn't match
if (!settings.IsFileAllowed(Path.GetFileName(media.FileName))) {
return Json(false);
}
var image = media.As<ImagePart>(); var image = media.As<ImagePart>();
content = content.Substring(signature.Length); content = content.Substring(signature.Length);

View File

@@ -11,6 +11,7 @@ using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters; using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Helpers; using Orchard.Layouts.Helpers;
using Orchard.Layouts.Services; using Orchard.Layouts.Services;
using Orchard.Mvc.Html;
namespace Orchard.Layouts.Providers { namespace Orchard.Layouts.Providers {
public class ContentFieldElementHarvester : Component, IElementHarvester { public class ContentFieldElementHarvester : Component, IElementHarvester {
@@ -44,7 +45,7 @@ namespace Orchard.Layouts.Providers {
var field = tuple.Item2; var field = tuple.Item2;
var name = String.Format("{0}.{1}", part.Name, field.Name); var name = String.Format("{0}.{1}", part.Name, field.Name);
var displayName = field.DisplayName; var displayName = field.DisplayName;
yield return new ElementDescriptor(elementType, name, T(displayName), T(field.DisplayName), contentFieldElement.Category) { yield return new ElementDescriptor(elementType, name, T.Encode(displayName), T.Encode(field.DisplayName), contentFieldElement.Category) {
Displaying = displayContext => Displaying(displayContext), Displaying = displayContext => Displaying(displayContext),
ToolboxIcon = "\uf1b2" ToolboxIcon = "\uf1b2"
}; };

View File

@@ -10,6 +10,7 @@ using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters; using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Services; using Orchard.Layouts.Services;
using Orchard.Layouts.Settings; using Orchard.Layouts.Settings;
using Orchard.Mvc.Html;
using Orchard.Utility.Extensions; using Orchard.Utility.Extensions;
namespace Orchard.Layouts.Providers { namespace Orchard.Layouts.Providers {
@@ -37,8 +38,8 @@ namespace Orchard.Layouts.Providers {
var partSettings = contentPart.Settings.TryGetModel<ContentPartSettings>(); var partSettings = contentPart.Settings.TryGetModel<ContentPartSettings>();
var partDescription = partSettings != null ? partSettings.Description : null; var partDescription = partSettings != null ? partSettings.Description : null;
var description = T(!String.IsNullOrWhiteSpace(partDescription) ? partDescription : contentPart.Name); var description = T.Encode(!String.IsNullOrWhiteSpace(partDescription) ? partDescription : contentPart.Name);
return new ElementDescriptor(elementType, contentPart.Name, T(contentPart.Name.CamelFriendly()), description, contentPartElement.Category) { return new ElementDescriptor(elementType, contentPart.Name, T.Encode(contentPart.Name.CamelFriendly()), description, contentPartElement.Category) {
Displaying = displayContext => Displaying(displayContext), Displaying = displayContext => Displaying(displayContext),
ToolboxIcon = "\uf1b2", ToolboxIcon = "\uf1b2",
StateBag = new Dictionary<string, object> { StateBag = new Dictionary<string, object> {

View File

@@ -14,6 +14,7 @@ using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Helpers; using Orchard.Layouts.Helpers;
using Orchard.Layouts.Settings; using Orchard.Layouts.Settings;
using Orchard.Layouts.ViewModels; using Orchard.Layouts.ViewModels;
using Orchard.Mvc.Html;
using ContentItem = Orchard.ContentManagement.ContentItem; using ContentItem = Orchard.ContentManagement.ContentItem;
namespace Orchard.Layouts.Providers { namespace Orchard.Layouts.Providers {
@@ -30,7 +31,7 @@ namespace Orchard.Layouts.Providers {
return contentTypeDefinitions.Select(contentTypeDefinition => { return contentTypeDefinitions.Select(contentTypeDefinition => {
var settings = contentTypeDefinition.Settings; var settings = contentTypeDefinition.Settings;
var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName; var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName;
return new ElementDescriptor(typeof (PlaceableContentItem), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category: "Content Items") { return new ElementDescriptor(typeof (PlaceableContentItem), contentTypeDefinition.Name, T.Encode(contentTypeDefinition.DisplayName), T.Encode(description), category: "Content Items") {
Displaying = Displaying, Displaying = Displaying,
Editor = Editor, Editor = Editor,
UpdateEditor = UpdateEditor, UpdateEditor = UpdateEditor,

View File

@@ -1 +1 @@
<span>@T(Model.Text.ToString())</span> <span>@T(Html.Encode(Model.Text.ToString()))</span>

View File

@@ -1 +1 @@
<a href="@Url.Content((string)Model.Url)">@T(Model.Text.ToString())</a> <a href="@Url.Content((string)Model.Url)">@T(Html.Encode(Model.Text.ToString()))</a>

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.ContentManagement; using Orchard.ContentManagement;
@@ -286,6 +287,13 @@ namespace Orchard.MediaLibrary.Controllers {
var newFileName = _mediaLibraryService.GetUniqueFilename(media.FolderPath, media.FileName); var newFileName = _mediaLibraryService.GetUniqueFilename(media.FolderPath, media.FileName);
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
// skip file if the allowed extensions is defined and doesn't match
if (!settings.IsFileAllowed(Path.GetFileName(newFileName))) {
return Json(false);
}
_mediaLibraryService.CopyFile(media.FolderPath, media.FileName, media.FolderPath, newFileName); _mediaLibraryService.CopyFile(media.FolderPath, media.FileName, media.FolderPath, newFileName);
var clonedContentItem = Services.ContentManager.Clone(media.ContentItem); var clonedContentItem = Services.ContentManager.Clone(media.ContentItem);

View File

@@ -73,9 +73,6 @@ namespace Orchard.MediaLibrary.Controllers {
var statuses = new List<object>(); var statuses = new List<object>();
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>(); var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
// Loop through each file in the request // Loop through each file in the request
for (int i = 0; i < HttpContext.Request.Files.Count; i++) { for (int i = 0; i < HttpContext.Request.Files.Count; i++) {
@@ -89,14 +86,12 @@ namespace Orchard.MediaLibrary.Controllers {
} }
// skip file if the allowed extensions is defined and doesn't match // skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) { if (!settings.IsFileAllowed(filename)) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) { statuses.Add(new {
statuses.Add(new { error = T("This file is not allowed: {0}", filename).Text,
error = T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text, progress = 1.0,
progress = 1.0, });
}); continue;
continue;
}
} }
try { try {
@@ -143,10 +138,7 @@ namespace Orchard.MediaLibrary.Controllers {
var statuses = new List<object>(); var statuses = new List<object>();
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>(); var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
// Loop through each file in the request // Loop through each file in the request
for (int i = 0; i < HttpContext.Request.Files.Count; i++) { for (int i = 0; i < HttpContext.Request.Files.Count; i++) {
// Pointer to file // Pointer to file
@@ -159,14 +151,12 @@ namespace Orchard.MediaLibrary.Controllers {
} }
// skip file if the allowed extensions is defined and doesn't match // skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) { if (!settings.IsFileAllowed(filename)) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) { statuses.Add(new {
statuses.Add(new { error = T("This file is not allowed: {0}", filename).Text,
error = T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text, progress = 1.0,
progress = 1.0, });
}); continue;
continue;
}
} }
try { try {

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Logging; using Orchard.Logging;
using Orchard.MediaLibrary.Models; using Orchard.MediaLibrary.Models;
@@ -200,7 +201,16 @@ namespace Orchard.MediaLibrary.Controllers {
if(!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, media.FolderPath)) { if(!_mediaLibraryService.CheckMediaFolderPermission(Permissions.DeleteMediaContent, media.FolderPath)) {
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
} }
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var uniqueFilename = _mediaLibraryService.GetUniqueFilename(folderPath, media.FileName); var uniqueFilename = _mediaLibraryService.GetUniqueFilename(folderPath, media.FileName);
// skip file if the allowed extensions is defined and doesn't match
if (!settings.IsFileAllowed(Path.GetFileName(uniqueFilename))) {
continue;
}
_mediaLibraryService.MoveFile(media.FolderPath, media.FileName, folderPath, uniqueFilename); _mediaLibraryService.MoveFile(media.FolderPath, media.FileName, folderPath, uniqueFilename);
media.FileName = uniqueFilename; media.FileName = uniqueFilename;
} }

View File

@@ -3,14 +3,13 @@ using System.IO;
using System.Net; using System.Net;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.FileSystems.Media;
using Orchard.Localization;
using Orchard.MediaLibrary.Models;
using Orchard.MediaLibrary.Services; using Orchard.MediaLibrary.Services;
using Orchard.MediaLibrary.ViewModels; using Orchard.MediaLibrary.ViewModels;
using Orchard.Themes; using Orchard.Themes;
using Orchard.UI.Admin; using Orchard.UI.Admin;
using Orchard.FileSystems.Media;
using Orchard.MediaLibrary.Models;
using System.Linq;
using Orchard.Localization;
namespace Orchard.MediaLibrary.Controllers { namespace Orchard.MediaLibrary.Controllers {
[Admin, Themed(false)] [Admin, Themed(false)]
@@ -71,18 +70,13 @@ namespace Orchard.MediaLibrary.Controllers {
} }
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>(); var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
try { try {
var filename = Path.GetFileName(url); var filename = Path.GetFileName(url);
// skip file if the allowed extensions is defined and doesn't match // skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) { if (!settings.IsFileAllowed(filename)) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) { throw new Exception(T("This file is not allowed: {0}", filename).Text);
throw new Exception(T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text);
}
} }
var buffer = new WebClient().DownloadData(url); var buffer = new WebClient().DownloadData(url);
@@ -115,18 +109,13 @@ namespace Orchard.MediaLibrary.Controllers {
} }
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>(); var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
try { try {
var filename = Path.GetFileName(url); var filename = Path.GetFileName(url);
// skip file if the allowed extensions is defined and doesn't match // skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) { if (!settings.IsFileAllowed(filename)) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) { throw new Exception(T("This file is not allowed: {0}", filename).Text);
throw new Exception(T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text);
}
} }
var buffer = new WebClient().DownloadData(url); var buffer = new WebClient().DownloadData(url);

View File

@@ -1,4 +1,6 @@
using Orchard.ContentManagement; using System;
using System.Linq;
using Orchard.ContentManagement;
namespace Orchard.MediaLibrary.Models { namespace Orchard.MediaLibrary.Models {
public class MediaLibrarySettingsPart : ContentPart { public class MediaLibrarySettingsPart : ContentPart {
@@ -10,5 +12,27 @@ namespace Orchard.MediaLibrary.Models {
get { return this.Retrieve(x => x.UploadAllowedFileTypeWhitelist); } get { return this.Retrieve(x => x.UploadAllowedFileTypeWhitelist); }
set { this.Store(x => x.UploadAllowedFileTypeWhitelist, value); } set { this.Store(x => x.UploadAllowedFileTypeWhitelist, value); }
} }
public bool IsFileAllowed(string filename) {
var allowedExtensions = (UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."))
.ToArray();
// skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) {
return false;
}
}
// web.config files are always ignored, even if the white list includes it
if (String.Equals(filename, "web.config", StringComparison.OrdinalIgnoreCase)) {
return false;
}
return true;
}
} }
} }

View File

@@ -7,12 +7,14 @@ using Orchard.ContentManagement;
using Orchard.Core.XmlRpc; using Orchard.Core.XmlRpc;
using Orchard.Core.XmlRpc.Models; using Orchard.Core.XmlRpc.Models;
using Orchard.Localization; using Orchard.Localization;
using Orchard.MediaLibrary.Models;
using Orchard.Mvc.Extensions; using Orchard.Mvc.Extensions;
using Orchard.Security; using Orchard.Security;
namespace Orchard.MediaLibrary.Services { namespace Orchard.MediaLibrary.Services {
public class XmlRpcHandler : IXmlRpcHandler { public class XmlRpcHandler : IXmlRpcHandler {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IOrchardServices _orchardServices;
private readonly IMembershipService _membershipService; private readonly IMembershipService _membershipService;
private readonly IAuthorizationService _authorizationService; private readonly IAuthorizationService _authorizationService;
private readonly IMediaLibraryService _mediaLibraryService; private readonly IMediaLibraryService _mediaLibraryService;
@@ -23,13 +25,14 @@ namespace Orchard.MediaLibrary.Services {
IAuthorizationService authorizationService, IAuthorizationService authorizationService,
IMediaLibraryService mediaLibraryService, IMediaLibraryService mediaLibraryService,
RouteCollection routeCollection, RouteCollection routeCollection,
IContentManager contentManager) { IContentManager contentManager,
IOrchardServices orchardServices) {
_membershipService = membershipService; _membershipService = membershipService;
_authorizationService = authorizationService; _authorizationService = authorizationService;
_mediaLibraryService = mediaLibraryService; _mediaLibraryService = mediaLibraryService;
_routeCollection = routeCollection; _routeCollection = routeCollection;
_contentManager = contentManager; _contentManager = contentManager;
_orchardServices = orchardServices;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
@@ -78,21 +81,30 @@ namespace Orchard.MediaLibrary.Services {
directoryName = Path.Combine(_mediaLibraryService.GetRootedFolderPath(directoryName)); directoryName = Path.Combine(_mediaLibraryService.GetRootedFolderPath(directoryName));
} }
var filename = Path.GetFileName(name);
try { try {
// delete the file if it already exists, e.g. an updated image in a blog post // delete the file if it already exists, e.g. an updated image in a blog post
// it's safe to delete the file as each content item gets a specific folder // it's safe to delete the file as each content item gets a specific folder
_mediaLibraryService.DeleteFile(directoryName, Path.GetFileName(name)); _mediaLibraryService.DeleteFile(directoryName, filename);
} }
catch { catch {
// current way to delete a file if it exists // current way to delete a file if it exists
} }
string publicUrl = _mediaLibraryService.UploadMediaFile(directoryName, Path.GetFileName(name), bits); string publicUrl = _mediaLibraryService.UploadMediaFile(directoryName, filename, bits);
var mediaPart = _mediaLibraryService.ImportMedia(directoryName, Path.GetFileName(name));
try { var settings = _orchardServices.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
_contentManager.Create(mediaPart);
} // skip file if the allowed extensions is defined and doesn't match
catch { if (settings.IsFileAllowed(filename)) {
var mediaPart = _mediaLibraryService.ImportMedia(directoryName, filename);
try {
_contentManager.Create(mediaPart);
}
catch {
}
} }
return new XRpcStruct() // Some clients require all optional attributes to be declared Wordpress responds in this way as well. return new XRpcStruct() // Some clients require all optional attributes to be declared Wordpress responds in this way as well.

View File

@@ -1,9 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.Html;
using Orchard.Roles.Models; using Orchard.Roles.Models;
using Orchard.Security; using Orchard.Security;
using Orchard.Workflows.Models; using Orchard.Workflows.Models;
@@ -38,7 +40,7 @@ namespace Orchard.Roles.Activities {
} }
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) { public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
return GetActions(activityContext).Select(action => T(action)); return GetActions(activityContext).Select(action => T.Encode(action));
} }
public override bool CanExecute(WorkflowContext workflowContext, ActivityContext activityContext) { public override bool CanExecute(WorkflowContext workflowContext, ActivityContext activityContext) {
@@ -48,7 +50,7 @@ namespace Orchard.Roles.Activities {
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) { public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
if (ActionIsValid(workflowContext, activityContext) && UserIsInRole(activityContext)) { if (ActionIsValid(workflowContext, activityContext) && UserIsInRole(activityContext)) {
yield return T(workflowContext.Tokens["UserTask.Action"].ToString()); yield return T.Encode(workflowContext.Tokens["UserTask.Action"].ToString());
} }
} }

View File

@@ -2,7 +2,7 @@
@using Orchard.Workflows.Helpers @using Orchard.Workflows.Helpers
@{ @{
var name = (string)Model.Name; var name = (string)Model.Name;
var outcomes = ((string)Model.State.Actions).FormatOutcomesJson(); var outcomes = ((string)Model.State.Actions).FormatOutcomesJson(T);
} }
<div class="event activity-@name.HtmlClassify()" title="@Model.Description" data-outcomes="@outcomes"> <div class="event activity-@name.HtmlClassify()" title="@Model.Description" data-outcomes="@outcomes">

View File

@@ -5,6 +5,6 @@
<fieldset class="usertask-button"> <fieldset class="usertask-button">
@foreach (var action in actions) { @foreach (var action in actions) {
<button type="submit" name="submit.Save" value="usertask-@action">@T(action)</button> <button type="submit" name="submit.Save" value="usertask-@action">@T(Html.Encode(action))</button>
} }
</fieldset> </fieldset>

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.Html;
using Orchard.Scripting.CSharp.Services; using Orchard.Scripting.CSharp.Services;
using Orchard.Workflows.Models; using Orchard.Workflows.Models;
using Orchard.Workflows.Services; using Orchard.Workflows.Services;
@@ -41,7 +42,7 @@ namespace Orchard.Scripting.CSharp.Activities {
} }
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) { public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
return GetOutcomes(activityContext).Select(outcome => T(outcome)); return GetOutcomes(activityContext).Select(outcome => T.Encode(outcome));
} }
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) { public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
@@ -62,7 +63,7 @@ namespace Orchard.Scripting.CSharp.Activities {
_csharpService.Run(script); _csharpService.Run(script);
yield return T(Convert.ToString(outcome)); yield return T.Encode(Convert.ToString(outcome));
} }
private IEnumerable<string> GetOutcomes(ActivityContext context) { private IEnumerable<string> GetOutcomes(ActivityContext context) {

View File

@@ -12,7 +12,7 @@
<label for="@Html.FieldIdFor(m => m.SelectedTermId)">@T("Parent term")</label> <label for="@Html.FieldIdFor(m => m.SelectedTermId)">@T("Parent term")</label>
<select name="@Html.FieldNameFor(m => m.SelectedTermId)" id="@Html.FieldIdFor(m => m.SelectedTermId)"> <select name="@Html.FieldNameFor(m => m.SelectedTermId)" id="@Html.FieldIdFor(m => m.SelectedTermId)">
@foreach (var term in Model.Terms) { @foreach (var term in Model.Terms) {
<option value="@term.Id">@T(term.Name)</option> <option value="@term.Id">@T.Encode(term.Name)</option>
} }
</select> </select>

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Web;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects; using Orchard.ContentManagement.Aspects;
using Orchard.ContentManagement.MetaData.Models; using Orchard.ContentManagement.MetaData.Models;
@@ -12,6 +13,7 @@ using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements; using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Framework.Harvesters; using Orchard.Layouts.Framework.Harvesters;
using Orchard.Layouts.Helpers; using Orchard.Layouts.Helpers;
using Orchard.Mvc.Html;
using Orchard.Security; using Orchard.Security;
using Orchard.Widgets.Layouts.Elements; using Orchard.Widgets.Layouts.Elements;
using Orchard.Widgets.ViewModels; using Orchard.Widgets.ViewModels;
@@ -34,7 +36,7 @@ namespace Orchard.Widgets.Layouts.Providers {
return contentTypeDefinitions.Select(contentTypeDefinition => { return contentTypeDefinitions.Select(contentTypeDefinition => {
var settings = contentTypeDefinition.Settings; var settings = contentTypeDefinition.Settings;
var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName; var description = settings.ContainsKey("Description") ? settings["Description"] : contentTypeDefinition.DisplayName;
return new ElementDescriptor(typeof (Widget), contentTypeDefinition.Name, T(contentTypeDefinition.DisplayName), T(description), category: "Widgets") { return new ElementDescriptor(typeof (Widget), contentTypeDefinition.Name, T.Encode(contentTypeDefinition.DisplayName), T.Encode(description), category: "Widgets") {
Displaying = Displaying, Displaying = Displaying,
Editor = Editor, Editor = Editor,
UpdateEditor = UpdateEditor, UpdateEditor = UpdateEditor,

View File

@@ -25,7 +25,7 @@
var currentLayerId = @Model.CurrentLayer.Id; var currentLayerId = @Model.CurrentLayer.Id;
var layers = [ var layers = [
@foreach (var layer in layers) { @foreach (var layer in layers) {
<text>{"name":"@layer.Name","description":"@EncodeLineBreaks(layer.Description)","id":@layer.Id}@(layer != layers.Last() ? "," : "")</text> <text>{"name":"@HttpUtility.JavaScriptStringEncode(layer.Name)","description":"@HttpUtility.JavaScriptStringEncode(EncodeLineBreaks(layer.Description))","id":@layer.Id}@(layer != layers.Last() ? "," : "")</text>
} }
]; ];
var visWrapper = $("#widgets-layer-visibility"); var visWrapper = $("#widgets-layer-visibility");

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc.Html;
using Orchard.Workflows.Models; using Orchard.Workflows.Models;
using Orchard.Workflows.Services; using Orchard.Workflows.Services;
@@ -19,11 +20,11 @@ namespace Orchard.Workflows.Activities {
} }
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) { public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
return GetBranches(activityContext).Select(x => T(x)); return GetBranches(activityContext).Select(x => T.Encode(x));
} }
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) { public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
return GetBranches(activityContext).Select(x => T(x)); return GetBranches(activityContext).Select(x => T.Encode(x));
} }
public override string Name { public override string Name {

View File

@@ -1,6 +1,8 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Web; using System.Web;
using Orchard.Localization;
using Orchard.Mvc.Html;
namespace Orchard.Workflows.Helpers { namespace Orchard.Workflows.Helpers {
public static class OutcomeSerializerExtensions { public static class OutcomeSerializerExtensions {
@@ -8,22 +10,18 @@ namespace Orchard.Workflows.Helpers {
/// Returns a JSON formatted string. /// Returns a JSON formatted string.
/// </summary> /// </summary>
/// <param name="outcomesText">A comma separated string containing outcomes.</param> /// <param name="outcomesText">A comma separated string containing outcomes.</param>
public static string FormatOutcomesJson(this string outcomesText) { public static string FormatOutcomesJson(this string outcomesText, Localizer T) {
var items = outcomesText != null var items = outcomesText != null
? outcomesText.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()) ? outcomesText.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim())
: Enumerable.Empty<string>(); : Enumerable.Empty<string>();
var query = var query =
from item in items from item in items
let outcome = Encode(item) let outcome = HttpUtility.JavaScriptStringEncode(T.Encode(item).ToString())
select "{Id:'" + outcome + "', Label:'" + outcome + "'}"; select "{Id:'" + outcome + "', Label:'" + outcome + "'}";
var outcomes = String.Join(",", query); var outcomes = String.Join(",", query);
return outcomes; return outcomes;
} }
private static string Encode(string value) {
return HttpUtility.JavaScriptStringEncode(value);
}
} }
} }

View File

@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using System.Web;
using Orchard.Localization; using Orchard.Localization;
namespace Orchard.Localization { namespace Orchard.Localization {
@@ -28,5 +29,9 @@ namespace Orchard.Mvc.Html {
return T(textPlural, new object[] {count}.Concat(args).ToArray()); return T(textPlural, new object[] {count}.Concat(args).ToArray());
} }
} }
public static LocalizedString Encode(this Localizer T, string unsecureText) {
return T(HttpUtility.HtmlEncode(unsecureText));
}
} }
} }