Skip to content

Commit 3e2ae11

Browse files
committed
Tightening security in APIs
1 parent 08bfd5f commit 3e2ae11

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

src/Core/Api/AssetsController.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Collections.Generic;
88
using System.Threading.Tasks;
99
using System.Linq;
10+
using Microsoft.AspNetCore.Authorization;
1011

1112
namespace Core.Api
1213
{
@@ -40,20 +41,20 @@ public async Task<AssetsModel> Get(int page = 1, string filter = "", string sear
4041
{
4142
if (filter == "filterImages")
4243
{
43-
items = await _store.Find(a => a.AssetType == AssetType.Image, pager);
44+
items = await _store.Find(a => a.AssetType == AssetType.Image, pager, "", !User.Identity.IsAuthenticated);
4445
}
4546
else if (filter == "filterAttachments")
4647
{
47-
items = await _store.Find(a => a.AssetType == AssetType.Attachment, pager);
48+
items = await _store.Find(a => a.AssetType == AssetType.Attachment, pager, "", !User.Identity.IsAuthenticated);
4849
}
4950
else
5051
{
51-
items = await _store.Find(null, pager);
52+
items = await _store.Find(null, pager, "", !User.Identity.IsAuthenticated);
5253
}
5354
}
5455
else
5556
{
56-
items = await _store.Find(a => a.Title.Contains(search), pager);
57+
items = await _store.Find(a => a.Title.Contains(search), pager, "", !User.Identity.IsAuthenticated);
5758
}
5859

5960
if (page < 1 || page > pager.LastPage)
@@ -110,11 +111,12 @@ public async Task<AssetItem> Pick(string type, string asset, string post)
110111
}
111112

112113
/// <summary>
113-
/// Upload file(s) to user data store
114+
/// Upload file(s) to user data store, authentication required
114115
/// </summary>
115116
/// <param name="files">Selected files</param>
116117
/// <returns>Success or internal error</returns>
117118
[HttpPost("upload")]
119+
[Authorize]
118120
public async Task<IActionResult> Upload(ICollection<IFormFile> files)
119121
{
120122
try
@@ -137,6 +139,7 @@ public async Task<IActionResult> Upload(ICollection<IFormFile> files)
137139
/// <param name="url">Relative URL of the file to remove</param>
138140
/// <returns></returns>
139141
[HttpDelete("remove")]
142+
[Authorize]
140143
public IActionResult Remove(string url)
141144
{
142145
try

src/Core/CoreAPI.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Core/Extensions/StringExtensions.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,22 @@ static string RemoveExtraHyphen(string text)
212212
return text;
213213
}
214214

215+
public static string SanitizePath(this string str)
216+
{
217+
if (str.Contains("..") || str.Contains("//"))
218+
throw new ApplicationException("Invalid directory path");
219+
220+
return str;
221+
}
222+
223+
public static string SanitizeFileName(this string str)
224+
{
225+
if (str.Contains("..") || str.Contains("//") || str.Count(x => x == '.') > 1)
226+
throw new ApplicationException("Invalid file name");
227+
228+
return str;
229+
}
230+
215231
#endregion
216232
}
217233
}

src/Core/Services/StorageService.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public interface IStorageService
3232

3333
string GetHtmlTemplate(string template);
3434

35-
Task<IEnumerable<AssetItem>> Find(Func<AssetItem, bool> predicate, Pager pager, string path = "");
35+
Task<IEnumerable<AssetItem>> Find(Func<AssetItem, bool> predicate, Pager pager, string path = "", bool sanitize = false);
3636

3737
Task Reset();
3838
}
@@ -254,7 +254,7 @@ public async Task<AssetItem> UploadFromWeb(Uri requestUri, string root, string p
254254
}
255255
}
256256

257-
public async Task<IEnumerable<AssetItem>> Find(Func<AssetItem, bool> predicate, Pager pager, string path = "")
257+
public async Task<IEnumerable<AssetItem>> Find(Func<AssetItem, bool> predicate, Pager pager, string path = "", bool sanitize = false)
258258
{
259259
var skip = pager.CurrentPage * pager.ItemsPerPage - pager.ItemsPerPage;
260260
var files = GetAssets(path);
@@ -267,6 +267,14 @@ public async Task<IEnumerable<AssetItem>> Find(Func<AssetItem, bool> predicate,
267267

268268
var page = items.Skip(skip).Take(pager.ItemsPerPage).ToList();
269269

270+
if (sanitize)
271+
{
272+
foreach (var p in page)
273+
{
274+
p.Path = "";
275+
}
276+
}
277+
270278
return await Task.FromResult(page);
271279
}
272280

@@ -331,6 +339,8 @@ public async Task Reset()
331339

332340
void VerifyPath(string path)
333341
{
342+
path = path.SanitizePath();
343+
334344
if (!string.IsNullOrEmpty(path))
335345
{
336346
var dir = Path.Combine(Location, path);
@@ -373,7 +383,7 @@ string GetFileName(string fileName)
373383
Random rnd = new Random();
374384
fileName = fileName.Replace("mceclip0", rnd.Next(100000, 999999).ToString());
375385
}
376-
return fileName;
386+
return fileName.SanitizeFileName();
377387
}
378388

379389
string GetUrl(string path, string root)
@@ -444,7 +454,7 @@ string TitleFromUri(Uri uri)
444454

445455
title = title.Replace(" ", "-");
446456

447-
return title.Replace("/", "");
457+
return title.Replace("/", "").SanitizeFileName();
448458
}
449459

450460
List<AssetItem> MapFilesToAssets(IList<string> assets)

0 commit comments

Comments
 (0)