Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Coder
code-server
提交
975dd13d
C
code-server
项目概览
镜像
/
Coder
/
code-server
2022-09-21 03:15:05同步失败
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
code-server
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
975dd13d
编写于
7月 01, 2021
作者:
J
Joe Previte
提交者:
GitHub
7月 01, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3695 from cdr/jsjoeio-sanitize-error-msg
fix: escape error.message on login failure
上级
faa896c1
c0e123a8
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
70 addition
and
6 deletion
+70
-6
src/node/http.ts
src/node/http.ts
+4
-3
src/node/routes/login.ts
src/node/routes/login.ts
+5
-3
src/node/util.ts
src/node/util.ts
+14
-0
test/unit/node/util.test.ts
test/unit/node/util.test.ts
+8
-0
test/unit/routes/login.test.ts
test/unit/routes/login.test.ts
+39
-0
未找到文件。
src/node/http.ts
浏览文件 @
975dd13d
...
...
@@ -7,7 +7,7 @@ import { normalize, Options } from "../common/util"
import
{
AuthType
,
DefaultedArgs
}
from
"
./cli
"
import
{
commit
,
rootPath
}
from
"
./constants
"
import
{
Heart
}
from
"
./heart
"
import
{
getPasswordMethod
,
IsCookieValidArgs
,
isCookieValid
,
sanitizeString
}
from
"
./util
"
import
{
getPasswordMethod
,
IsCookieValidArgs
,
isCookieValid
,
sanitizeString
,
escapeHtml
}
from
"
./util
"
declare
global
{
// eslint-disable-next-line @typescript-eslint/no-namespace
...
...
@@ -35,7 +35,7 @@ export const replaceTemplates = <T extends object>(
...
extraOpts
,
}
return
content
.
replace
(
/{{TO}}/g
,
(
typeof
req
.
query
.
to
===
"
string
"
&&
req
.
query
.
to
)
||
"
/
"
)
.
replace
(
/{{TO}}/g
,
(
typeof
req
.
query
.
to
===
"
string
"
&&
escapeHtml
(
req
.
query
.
to
)
)
||
"
/
"
)
.
replace
(
/{{BASE}}/g
,
options
.
base
)
.
replace
(
/{{CS_STATIC_BASE}}/g
,
options
.
csStaticBase
)
.
replace
(
/"{{OPTIONS}}"/
,
`'
${
JSON
.
stringify
(
options
)}
'`
)
...
...
@@ -100,7 +100,8 @@ export const relativeRoot = (req: express.Request): string => {
}
/**
* Redirect relatively to `/${to}`. Query variables will be preserved.
* Redirect relatively to `/${to}`. Query variables on the current URI will be preserved.
* `to` should be a simple path without any query parameters
* `override` will merge with the existing query (use `undefined` to unset).
*/
export
const
redirect
=
(
...
...
src/node/routes/login.ts
浏览文件 @
975dd13d
...
...
@@ -4,7 +4,7 @@ import { RateLimiter as Limiter } from "limiter"
import
*
as
path
from
"
path
"
import
{
rootPath
}
from
"
../constants
"
import
{
authenticated
,
getCookieDomain
,
redirect
,
replaceTemplates
}
from
"
../http
"
import
{
getPasswordMethod
,
handlePasswordValidation
,
humanPath
,
sanitizeString
}
from
"
../util
"
import
{
getPasswordMethod
,
handlePasswordValidation
,
humanPath
,
sanitizeString
,
escapeHtml
}
from
"
../util
"
export
enum
Cookie
{
Key
=
"
key
"
,
...
...
@@ -36,11 +36,12 @@ const getRoot = async (req: Request, error?: Error): Promise<string> => {
}
else
if
(
req
.
args
.
usingEnvHashedPassword
)
{
passwordMsg
=
"
Password was set from $HASHED_PASSWORD.
"
}
return
replaceTemplates
(
req
,
content
.
replace
(
/{{PASSWORD_MSG}}/g
,
passwordMsg
)
.
replace
(
/{{ERROR}}/
,
error
?
`<div class="error">
${
e
rror
.
message
}
</div>`
:
""
),
.
replace
(
/{{ERROR}}/
,
error
?
`<div class="error">
${
e
scapeHtml
(
error
.
message
)
}
</div>`
:
""
),
)
}
...
...
@@ -111,6 +112,7 @@ router.post("/", async (req, res) => {
throw
new
Error
(
"
Incorrect password
"
)
}
catch
(
error
)
{
res
.
send
(
await
getRoot
(
req
,
error
))
const
renderedHtml
=
await
getRoot
(
req
,
error
)
res
.
send
(
renderedHtml
)
}
})
src/node/util.ts
浏览文件 @
975dd13d
...
...
@@ -508,3 +508,17 @@ export const isFile = async (path: string): Promise<boolean> => {
return
false
}
}
/**
* Escapes any HTML string special characters, like &, <, >, ", and '.
*
* Source: https://stackoverflow.com/a/6234804/3015595
**/
export
function
escapeHtml
(
unsafe
:
string
):
string
{
return
unsafe
.
replace
(
/&/g
,
"
&
"
)
.
replace
(
/</g
,
"
<
"
)
.
replace
(
/>/g
,
"
>
"
)
.
replace
(
/"/g
,
"
"
"
)
.
replace
(
/'/g
,
"
'
"
)
}
test/unit/node/util.test.ts
浏览文件 @
975dd13d
...
...
@@ -445,3 +445,11 @@ describe("onLine", () => {
expect
(
await
received
).
toEqual
(
expected
)
})
})
describe
(
"
escapeHtml
"
,
()
=>
{
it
(
"
should escape HTML
"
,
()
=>
{
expect
(
util
.
escapeHtml
(
`<div class="error">"'ello & world"</div>`
)).
toBe
(
"
<div class="error">"'ello & world"</div>
"
,
)
})
})
test/unit/routes/login.test.ts
浏览文件 @
975dd13d
import
{
RateLimiter
}
from
"
../../../src/node/routes/login
"
import
*
as
httpserver
from
"
../../utils/httpserver
"
import
*
as
integration
from
"
../../utils/integration
"
describe
(
"
login
"
,
()
=>
{
describe
(
"
RateLimiter
"
,
()
=>
{
...
...
@@ -34,4 +36,41 @@ describe("login", () => {
expect
(
limiter
.
removeToken
()).
toBe
(
false
)
})
})
describe
(
"
/login
"
,
()
=>
{
let
_codeServer
:
httpserver
.
HttpServer
|
undefined
function
codeServer
():
httpserver
.
HttpServer
{
if
(
!
_codeServer
)
{
throw
new
Error
(
"
tried to use code-server before setting it up
"
)
}
return
_codeServer
}
// Store whatever might be in here so we can restore it afterward.
// TODO: We should probably pass this as an argument somehow instead of
// manipulating the environment.
const
previousEnvPassword
=
process
.
env
.
PASSWORD
beforeEach
(
async
()
=>
{
process
.
env
.
PASSWORD
=
"
test
"
_codeServer
=
await
integration
.
setup
([
"
--auth=password
"
],
""
)
})
afterEach
(
async
()
=>
{
process
.
env
.
PASSWORD
=
previousEnvPassword
if
(
_codeServer
)
{
await
_codeServer
.
close
()
_codeServer
=
undefined
}
})
it
(
"
should return HTML with 'Missing password' message
"
,
async
()
=>
{
const
resp
=
await
codeServer
().
fetch
(
"
/login
"
,
{
method
:
"
POST
"
})
expect
(
resp
.
status
).
toBe
(
200
)
const
htmlContent
=
await
resp
.
text
()
expect
(
htmlContent
).
toContain
(
"
Missing password
"
)
})
})
})
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录