Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
fa4ec0a0
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
fa4ec0a0
编写于
10月 18, 2019
作者:
D
Daniel Beck
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[JENKINS-59849]
上级
5b3ea20b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
88 addition
and
5 deletion
+88
-5
core/src/main/java/jenkins/security/ResourceDomainRootAction.java
.../main/java/jenkins/security/ResourceDomainRootAction.java
+10
-5
test/src/test/java/jenkins/security/ResourceDomainTest.java
test/src/test/java/jenkins/security/ResourceDomainTest.java
+78
-0
未找到文件。
core/src/main/java/jenkins/security/ResourceDomainRootAction.java
浏览文件 @
fa4ec0a0
...
...
@@ -23,6 +23,7 @@
*/
package
jenkins.security
;
import
com.google.common.annotations.VisibleForTesting
;
import
hudson.Extension
;
import
hudson.ExtensionList
;
import
hudson.Util
;
...
...
@@ -51,6 +52,7 @@ import java.util.Arrays;
import
java.util.Base64
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
java.util.stream.Collectors
;
import
static
java
.
time
.
Instant
.*;
import
static
java
.
time
.
temporal
.
ChronoUnit
.
MINUTES
;
...
...
@@ -147,7 +149,7 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
// Unsure whether this can happen -- just be safe here
restOfPath
=
"/"
+
restOfPath
;
}
return
resourceRootUrl
+
getUrlName
()
+
"/"
+
token
.
encode
()
+
restOfPath
;
return
resourceRootUrl
+
getUrlName
()
+
"/"
+
token
.
encode
()
+
Arrays
.
stream
(
restOfPath
.
split
(
"[/]"
)).
map
(
Util:
:
rawEncode
).
collect
(
Collectors
.
joining
(
"/"
))
;
}
private
static
String
getResourceRootUrl
()
{
...
...
@@ -165,7 +167,7 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
@CheckForNull
public
Token
getToken
(
@Nonnull
DirectoryBrowserSupport
dbs
,
@Nonnull
StaplerRequest
req
)
{
// This is the "restOfPath" of the DirectoryBrowserSupport, i.e. the directory/file/pattern "inside" the DBS.
final
String
dbsFile
=
req
.
getRestOfPath
();
final
String
dbsFile
=
req
.
get
Original
RestOfPath
();
// Now get the 'restOfUrl' after the top-level ancestor (which is the Jenkins singleton).
// In other words, this is the complete URL after Jenkins handled the top-level request.
...
...
@@ -222,7 +224,8 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
try
(
ACLContext
ignored
=
ACL
.
as
(
auth
))
{
try
{
Stapler
.
getCurrent
().
invoke
(
req
,
rsp
,
Jenkins
.
get
(),
requestUrlSuffix
+
restOfPath
);
String
path
=
requestUrlSuffix
+
Arrays
.
stream
(
restOfPath
.
split
(
"[/]"
)).
map
(
Util:
:
rawEncode
).
collect
(
Collectors
.
joining
(
"/"
));
Stapler
.
getCurrent
().
invoke
(
req
,
rsp
,
Jenkins
.
get
(),
path
);
}
catch
(
Exception
ex
)
{
// cf. UnwrapSecurityExceptionFilter
Throwable
cause
=
ex
.
getCause
();
...
...
@@ -263,7 +266,9 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
private
String
path
;
private
String
username
;
private
Instant
timestamp
;
private
Token
(
String
path
,
@Nullable
String
username
,
Instant
timestamp
)
{
@VisibleForTesting
Token
(
String
path
,
@Nullable
String
username
,
Instant
timestamp
)
{
this
.
path
=
path
;
this
.
username
=
Util
.
fixNull
(
username
);
this
.
timestamp
=
timestamp
;
...
...
@@ -277,8 +282,8 @@ public class ResourceDomainRootAction implements UnprotectedRootAction {
}
private
static
Token
decode
(
String
value
)
{
byte
[]
byteValue
=
Base64
.
getUrlDecoder
().
decode
(
value
);
try
{
byte
[]
byteValue
=
Base64
.
getUrlDecoder
().
decode
(
value
);
byte
[]
mac
=
Arrays
.
copyOf
(
byteValue
,
32
);
byte
[]
restBytes
=
Arrays
.
copyOfRange
(
byteValue
,
32
,
byteValue
.
length
);
String
rest
=
new
String
(
restBytes
,
StandardCharsets
.
UTF_8
);
...
...
test/src/test/java/jenkins/security/ResourceDomainTest.java
浏览文件 @
fa4ec0a0
...
...
@@ -3,9 +3,11 @@ package jenkins.security;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.html.HtmlPage
;
import
hudson.ExtensionList
;
import
hudson.FilePath
;
import
hudson.model.DirectoryBrowserSupport
;
import
hudson.model.FreeStyleProject
;
import
hudson.model.Item
;
import
hudson.model.UnprotectedRootAction
;
import
jenkins.model.Jenkins
;
import
jenkins.model.JenkinsLocationConfiguration
;
import
org.junit.Assert
;
...
...
@@ -17,8 +19,12 @@ import org.jvnet.hudson.test.For;
import
org.jvnet.hudson.test.Issue
;
import
org.jvnet.hudson.test.JenkinsRule
;
import
org.jvnet.hudson.test.MockAuthorizationStrategy
;
import
org.jvnet.hudson.test.TestExtension
;
import
org.kohsuke.stapler.HttpResponse
;
import
javax.annotation.CheckForNull
;
import
java.net.URL
;
import
java.time.Instant
;
import
java.util.UUID
;
@Issue
(
"JENKINS-41891"
)
...
...
@@ -279,4 +285,76 @@ public class ResourceDomainTest {
}
Assert
.
assertFalse
(
monitor
.
isActivated
());
}
@Test
public
void
testRedirectUrls
()
throws
Exception
{
ResourceDomainRootAction
rootAction
=
ResourceDomainRootAction
.
get
();
String
url
=
rootAction
.
getRedirectUrl
(
new
ResourceDomainRootAction
.
Token
(
"foo"
,
"bar"
,
Instant
.
now
()),
"foo bar baz"
);
Assert
.
assertFalse
(
"urlencoded"
,
url
.
contains
(
" "
));
}
@Test
@Issue
(
"JENKINS-59849"
)
public
void
testUrlEncoding
()
throws
Exception
{
FreeStyleProject
project
=
j
.
createFreeStyleProject
();
project
.
getBuildersList
().
add
(
new
CreateFileBuilder
(
"This has spaces and is 100% evil.html"
,
"<html><body>the content</body></html>"
));
project
.
save
();
j
.
buildAndAssertSuccess
(
project
);
JenkinsRule
.
WebClient
webClient
=
j
.
createWebClient
();
webClient
.
setThrowExceptionOnFailingStatusCode
(
false
);
webClient
.
setRedirectEnabled
(
true
);
HtmlPage
page
=
webClient
.
getPage
(
project
,
"ws/This%20has%20spaces%20and%20is%20100%25%20evil.html"
);
Assert
.
assertEquals
(
"page is found"
,
200
,
page
.
getWebResponse
().
getStatusCode
());
Assert
.
assertTrue
(
"page content is as expected"
,
page
.
getWebResponse
().
getContentAsString
().
contains
(
"the content"
));
URL
url
=
page
.
getUrl
();
Assert
.
assertTrue
(
"page is served by resource domain"
,
url
.
toString
().
contains
(
"/static-files/"
));
}
@Test
@Issue
(
"JENKINS-59849"
)
public
void
testMoreUrlEncoding
()
throws
Exception
{
JenkinsRule
.
WebClient
webClient
=
j
.
createWebClient
();
webClient
.
setThrowExceptionOnFailingStatusCode
(
false
);
webClient
.
setRedirectEnabled
(
true
);
Page
page
=
webClient
.
goTo
(
"100%25%20evil/%20100%25%20evil%20content%20.html"
);
Assert
.
assertEquals
(
"page is found"
,
200
,
page
.
getWebResponse
().
getStatusCode
());
Assert
.
assertTrue
(
"page content is as expected"
,
page
.
getWebResponse
().
getContentAsString
().
contains
(
"this is the content"
));
URL
url
=
page
.
getUrl
();
Assert
.
assertTrue
(
"page is served by resource domain"
,
url
.
toString
().
contains
(
"/static-files/"
));
}
@TestExtension
public
static
class
RootActionImpl
implements
UnprotectedRootAction
{
@CheckForNull
@Override
public
String
getIconFileName
()
{
return
null
;
}
@CheckForNull
@Override
public
String
getDisplayName
()
{
return
null
;
}
@CheckForNull
@Override
public
String
getUrlName
()
{
return
"100% evil"
;
}
public
HttpResponse
doDynamic
()
throws
Exception
{
Jenkins
jenkins
=
Jenkins
.
get
();
FilePath
tempDir
=
jenkins
.
getRootPath
().
createTempDir
(
"root"
,
"tmp"
);
tempDir
.
child
(
" 100% evil content .html"
).
write
(
"this is the content"
,
"UTF-8"
);
return
new
DirectoryBrowserSupport
(
jenkins
,
tempDir
,
"title"
,
""
,
false
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录