Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit812d72c

Browse files
authored
fix: sanitize app status summary (#19075)
Fixes#18875
1 parent29486f9 commit812d72c

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

‎coderd/util/strings/strings.go‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ package strings
22

33
import (
44
"fmt"
5+
"strconv"
56
"strings"
7+
"unicode"
8+
9+
"github.com/acarl005/stripansi"
10+
"github.com/microcosm-cc/bluemonday"
611
)
712

813
// JoinWithConjunction joins a slice of strings with commas except for the last
@@ -28,3 +33,38 @@ func Truncate(s string, n int) string {
2833
}
2934
returns[:n]
3035
}
36+
37+
varbmPolicy=bluemonday.StrictPolicy()
38+
39+
// UISanitize sanitizes a string for display in the UI.
40+
// The following transformations are applied, in order:
41+
// - HTML tags are removed using bluemonday's strict policy.
42+
// - ANSI escape codes are stripped using stripansi.
43+
// - Consecutive backslashes are replaced with a single backslash.
44+
// - Non-printable characters are removed.
45+
// - Whitespace characters are replaced with spaces.
46+
// - Multiple spaces are collapsed into a single space.
47+
// - Leading and trailing whitespace is trimmed.
48+
funcUISanitize(instring)string {
49+
ifunq,err:=strconv.Unquote(`"`+in+`"`);err==nil {
50+
in=unq
51+
}
52+
in=bmPolicy.Sanitize(in)
53+
in=stripansi.Strip(in)
54+
varb strings.Builder
55+
varspaceSeenbool
56+
for_,r:=rangein {
57+
ifunicode.IsSpace(r) {
58+
if!spaceSeen {
59+
_,_=b.WriteRune(' ')
60+
spaceSeen=true
61+
}
62+
continue
63+
}
64+
spaceSeen=false
65+
ifunicode.IsPrint(r) {
66+
_,_=b.WriteRune(r)
67+
}
68+
}
69+
returnstrings.TrimSpace(b.String())
70+
}

‎coderd/util/strings/strings_test.go‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package strings_test
33
import (
44
"testing"
55

6+
"github.com/stretchr/testify/assert"
67
"github.com/stretchr/testify/require"
78

89
"github.com/coder/coder/v2/coderd/util/strings"
@@ -37,3 +38,41 @@ func TestTruncate(t *testing.T) {
3738
})
3839
}
3940
}
41+
42+
funcTestUISanitize(t*testing.T) {
43+
t.Parallel()
44+
45+
for_,tt:=range []struct {
46+
sstring
47+
expectedstring
48+
}{
49+
{"normal text","normal text"},
50+
{"\tfoo\r\\nbar ","foo bar"},
51+
{"通常のテキスト","通常のテキスト"},
52+
{"foo\nbar","foo bar"},
53+
{"foo\tbar","foo bar"},
54+
{"foo\rbar","foo bar"},
55+
{"foo\x00bar","foobar"},
56+
{"\u202Eabc","abc"},
57+
{"\u200Bzero width","zero width"},
58+
{"foo\x1b[31mred\x1b[0mbar","fooredbar"},
59+
{"foo\u0008bar","foobar"},
60+
{"foo\x07bar","foobar"},
61+
{"foo\uFEFFbar","foobar"},
62+
{"<a href='#"diff-e99e8d46008f3a35d8be0d02f24a58546a44af5e150a402c76773924baaa2c99-39-63-0" data-selected="false" role="gridcell" tabindex="-1" valign="top">
63+
{"<style>body{display:none}</style>",""},
64+
{"<html>HTML</html>","HTML"},
65+
{"<br>line break","line break"},
66+
{"<link rel='stylesheet' href='evil.css'>",""},
67+
{"<img src=1 onerror=alert(1)>",""},
68+
{"<!-- comment -->visible","visible"},
69+
{"<script>alert('xss')</script>",""},
70+
{"<iframe src='evil.com'></iframe>",""},
71+
} {
72+
t.Run(tt.expected,func(t*testing.T) {
73+
t.Parallel()
74+
actual:=strings.UISanitize(tt.s)
75+
assert.Equal(t,tt.expected,actual)
76+
})
77+
}
78+
}

‎coderd/workspaceagents.go‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/coder/coder/v2/coderd/rbac/policy"
4242
"github.com/coder/coder/v2/coderd/telemetry"
4343
maputil"github.com/coder/coder/v2/coderd/util/maps"
44+
strutil"github.com/coder/coder/v2/coderd/util/strings"
4445
"github.com/coder/coder/v2/coderd/wspubsub"
4546
"github.com/coder/coder/v2/codersdk"
4647
"github.com/coder/coder/v2/codersdk/agentsdk"
@@ -383,6 +384,9 @@ func (api *API) patchWorkspaceAgentAppStatus(rw http.ResponseWriter, r *http.Req
383384
return
384385
}
385386

387+
// Treat the message as untrusted input.
388+
cleaned:=strutil.UISanitize(req.Message)
389+
386390
// nolint:gocritic // This is a system restricted operation.
387391
_,err=api.Database.InsertWorkspaceAppStatus(dbauthz.AsSystemRestricted(ctx), database.InsertWorkspaceAppStatusParams{
388392
ID:uuid.New(),
@@ -391,7 +395,7 @@ func (api *API) patchWorkspaceAgentAppStatus(rw http.ResponseWriter, r *http.Req
391395
AgentID:workspaceAgent.ID,
392396
AppID:app.ID,
393397
State:database.WorkspaceAppStatusState(req.State),
394-
Message:req.Message,
398+
Message:cleaned,
395399
Uri: sql.NullString{
396400
String:req.URI,
397401
Valid:req.URI!="",

‎codersdk/toolsdk/toolsdk.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ ONLY report an "idle" or "failure" state if you have FULLY completed the task.
229229
Properties:map[string]any{
230230
"summary":map[string]any{
231231
"type":"string",
232-
"description":"A concise summary of your current progress on the task. This must be less than 160 characters in length.",
232+
"description":"A concise summary of your current progress on the task. This must be less than 160 characters in length and must not include newlines or other control characters.",
233233
},
234234
"link":map[string]any{
235235
"type":"string",

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ require (
365365
github.com/mdlayher/netlinkv1.7.2// indirect
366366
github.com/mdlayher/sdnotifyv1.0.0// indirect
367367
github.com/mdlayher/socketv0.5.0// indirect
368-
github.com/microcosm-cc/bluemondayv1.0.27// indirect
368+
github.com/microcosm-cc/bluemondayv1.0.27
369369
github.com/miekg/dnsv1.1.57// indirect
370370
github.com/mitchellh/copystructurev1.2.0// indirect
371371
github.com/mitchellh/go-homedirv1.1.0// indirect

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp