Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
79bdd440
Unverified
Commit
79bdd440
authored
Dec 24, 2021
by
NGPixel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: force download of unsafe extensions
parent
57b56d3a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
33 additions
and
2 deletions
+33
-2
admin-security.vue
client/components/admin/admin-security.vue
+14
-0
data.yml
server/app/data.yml
+1
-0
site.js
server/graph/resolvers/site.js
+4
-2
site.graphql
server/graph/schemas/site.graphql
+2
-0
asset.js
server/helpers/asset.js
+5
-0
assets.js
server/models/assets.js
+7
-0
No files found.
client/components/admin/admin-security.vue
View file @
79bdd440
...
...
@@ -151,6 +151,15 @@
persistent-hint
hint='Should SVG uploads be scanned for vulnerabilities and stripped of any potentially unsafe content.'
)
v-divider.mt-3
v-switch(
inset
label='Force Download of Unsafe Extensions'
color='primary'
v-model='config.uploadForceDownload'
persistent-hint
hint='Should non-image files be forced as downloads when accessed directly. This prevents potential XSS attacks via unsafe file extensions uploads.'
)
v-card.mt-3.animated.fadeInUp.wait-p2s
v-toolbar(flat, color='primary', dark, dense)
...
...
@@ -252,6 +261,7 @@ export default {
uploadMaxFileSize
:
0
,
uploadMaxFiles
:
0
,
uploadScanSVG
:
true
,
uploadForceDownload
:
true
,
securityOpenRedirect
:
true
,
securityIframe
:
true
,
securityReferrerPolicy
:
true
,
...
...
@@ -297,6 +307,7 @@ export default {
$uploadMaxFileSize: Int
$uploadMaxFiles: Int
$uploadScanSVG: Boolean
$uploadForceDownload: Boolean
$securityOpenRedirect: Boolean
$securityIframe: Boolean
$securityReferrerPolicy: Boolean
...
...
@@ -319,6 +330,7 @@ export default {
uploadMaxFileSize: $uploadMaxFileSize,
uploadMaxFiles: $uploadMaxFiles,
uploadScanSVG: $uploadScanSVG
uploadForceDownload: $uploadForceDownload,
securityOpenRedirect: $securityOpenRedirect,
securityIframe: $securityIframe,
securityReferrerPolicy: $securityReferrerPolicy,
...
...
@@ -350,6 +362,7 @@ export default {
uploadMaxFileSize
:
_
.
toSafeInteger
(
_
.
get
(
this
.
config
,
'uploadMaxFileSize'
,
0
)),
uploadMaxFiles
:
_
.
toSafeInteger
(
_
.
get
(
this
.
config
,
'uploadMaxFiles'
,
0
)),
uploadScanSVG
:
_
.
get
(
this
.
config
,
'uploadScanSVG'
,
false
),
uploadForceDownload
:
_
.
get
(
this
.
config
,
'uploadForceDownload'
,
false
),
securityOpenRedirect
:
_
.
get
(
this
.
config
,
'securityOpenRedirect'
,
false
),
securityIframe
:
_
.
get
(
this
.
config
,
'securityIframe'
,
false
),
securityReferrerPolicy
:
_
.
get
(
this
.
config
,
'securityReferrerPolicy'
,
false
),
...
...
@@ -402,6 +415,7 @@ export default {
uploadMaxFileSize
uploadMaxFiles
uploadScanSVG
uploadForceDownload
securityOpenRedirect
securityIframe
securityReferrerPolicy
...
...
server/app/data.yml
View file @
79bdd440
...
...
@@ -81,6 +81,7 @@ defaults:
maxFileSize
:
5242880
maxFiles
:
10
scanSVG
:
true
forceDownload
:
true
flags
:
ldapdebug
:
false
sqllog
:
false
...
...
server/graph/resolvers/site.js
View file @
79bdd440
...
...
@@ -30,7 +30,8 @@ module.exports = {
authJwtRenewablePeriod
:
WIKI
.
config
.
auth
.
tokenRenewal
,
uploadMaxFileSize
:
WIKI
.
config
.
uploads
.
maxFileSize
,
uploadMaxFiles
:
WIKI
.
config
.
uploads
.
maxFiles
,
uploadScanSVG
:
WIKI
.
config
.
uploads
.
scanSVG
uploadScanSVG
:
WIKI
.
config
.
uploads
.
scanSVG
,
uploadForceDownload
:
WIKI
.
config
.
uploads
.
forceDownload
}
}
},
...
...
@@ -99,7 +100,8 @@ module.exports = {
WIKI
.
config
.
uploads
=
{
maxFileSize
:
_
.
get
(
args
,
'uploadMaxFileSize'
,
WIKI
.
config
.
uploads
.
maxFileSize
),
maxFiles
:
_
.
get
(
args
,
'uploadMaxFiles'
,
WIKI
.
config
.
uploads
.
maxFiles
),
scanSVG
:
_
.
get
(
args
,
'uploadScanSVG'
,
WIKI
.
config
.
uploads
.
scanSVG
)
scanSVG
:
_
.
get
(
args
,
'uploadScanSVG'
,
WIKI
.
config
.
uploads
.
scanSVG
),
forceDownload
:
_
.
get
(
args
,
'uploadForceDownload'
,
WIKI
.
config
.
uploads
.
forceDownload
)
}
await
WIKI
.
configSvc
.
saveToDb
([
'host'
,
'title'
,
'company'
,
'contentLicense'
,
'seo'
,
'logoUrl'
,
'auth'
,
'features'
,
'security'
,
'uploads'
])
...
...
server/graph/schemas/site.graphql
View file @
79bdd440
...
...
@@ -55,6 +55,7 @@ type SiteMutation {
uploadMaxFileSize
:
Int
uploadMaxFiles
:
Int
uploadScanSVG
:
Boolean
uploadForceDownload
:
Boolean
):
DefaultResponse
@
auth
(
requires
:
[
"
manage
:
system
"
])
}
...
...
@@ -95,4 +96,5 @@ type SiteConfig {
uploadMaxFileSize
:
Int
uploadMaxFiles
:
Int
uploadScanSVG
:
Boolean
uploadForceDownload
:
Boolean
}
server/helpers/asset.js
View file @
79bdd440
const
crypto
=
require
(
'crypto'
)
const
path
=
require
(
'path'
)
module
.
exports
=
{
/**
...
...
@@ -6,5 +7,9 @@ module.exports = {
*/
generateHash
(
assetPath
)
{
return
crypto
.
createHash
(
'sha1'
).
update
(
assetPath
).
digest
(
'hex'
)
},
getPathInfo
(
assetPath
)
{
return
path
.
parse
(
assetPath
.
toLowerCase
())
}
}
server/models/assets.js
View file @
79bdd440
...
...
@@ -168,8 +168,15 @@ module.exports = class Asset extends Model {
static
async
getAsset
(
assetPath
,
res
)
{
try
{
const
fileInfo
=
assetHelper
.
getPathInfo
(
assetPath
)
const
fileHash
=
assetHelper
.
generateHash
(
assetPath
)
const
cachePath
=
path
.
resolve
(
WIKI
.
ROOTPATH
,
WIKI
.
config
.
dataPath
,
`cache/
${
fileHash
}
.dat`
)
// Force unsafe extensions to download
if
(
WIKI
.
config
.
uploads
.
forceDownload
&&
!
[
'.png'
,
'.apng'
,
'.jpg'
,
'.jpeg'
,
'.gif'
,
'.bmp'
,
'.webp'
,
'.svg'
].
includes
(
fileInfo
.
ext
))
{
res
.
set
(
'Content-disposition'
,
'attachment; filename='
+
fileInfo
.
base
)
}
if
(
await
WIKI
.
models
.
assets
.
getAssetFromCache
(
assetPath
,
cachePath
,
res
))
{
return
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment