Skip to content

Commit 692af2e

Browse files
committed
Limit lengths of OAuth client and bearer login names
To mitigate potential DoS.
1 parent 6746e1a commit 692af2e

File tree

6 files changed

+59
-3
lines changed

6 files changed

+59
-3
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
### Changed
1111
- Change no-op methods in `Shield::Hash` to `abstract def`s
1212

13+
### Fixed
14+
- Limit lengths of OAuth client and bearer login names to mitigate potential DoS
15+
1316
## [1.2.0] - 2024-07-05
1417

1518
### Fixed

docs/14-I18N.md

+1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ en:
200200
name_invalid: Name is not valid
201201
name_not_allowed: The provided name is not allowed
202202
name_required: Name is required
203+
name_too_long: Name cannot be longer than %{max} characters
203204
password_length_invalid: Password must be between %{min} and %{max} characters long
204205
password_notify_required: Password notification was not set
205206
password_required: Password is required

spec/shield/operations/mixins/validate_bearer_login_spec.cr

+16
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,22 @@ describe Shield::ValidateBearerLogin do
9191
end
9292
end
9393

94+
it "rejects long name" do
95+
user = UserFactory.create
96+
97+
SaveBearerLogin.create(params(
98+
user_id: user.id,
99+
active_at: Time.utc,
100+
name: "t" * 300,
101+
token_digest: "abc",
102+
scopes: [BearerScope.new(Api::Posts::Index).to_s]
103+
)) do |operation, bearer_login|
104+
bearer_login.should be_nil
105+
106+
operation.name.should have_error("operation.error.name_too_long")
107+
end
108+
end
109+
94110
it "requires a valid name format" do
95111
user = UserFactory.create
96112

spec/shield/operations/mixins/validate_oauth_client_spec.cr

+18
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ describe Shield::ValidateOauthClient do
100100
end
101101
end
102102

103+
it "rejects long name" do
104+
user = UserFactory.create
105+
106+
SaveOauthClient.create(
107+
params(
108+
active_at: Time.utc,
109+
name: "c" * 300,
110+
secret_digest: "a1b2c3",
111+
user_id: user.id
112+
),
113+
redirect_uris: ["https://example.com/oauth/callback"],
114+
) do |operation, oauth_client|
115+
oauth_client.should be_nil
116+
117+
operation.name.should have_error("operation.error.name_too_long")
118+
end
119+
end
120+
103121
it "requires a valid name format" do
104122
user = UserFactory.create
105123

src/shield/operations/mixins/validate_bearer_login.cr

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ module Shield::ValidateBearerLogin
55
before_save do
66
ensure_scopes_unique
77

8-
validate_name_required
98
validate_user_id_required
9+
10+
validate_name_required
11+
validate_name_length
1012
validate_name_valid
1113
validate_name_unique
1214

@@ -27,6 +29,14 @@ module Shield::ValidateBearerLogin
2729
validate_required name, message: Rex.t(:"operation.error.name_required")
2830
end
2931

32+
private def validate_name_length
33+
max = 255
34+
35+
validate_size_of name,
36+
max: max,
37+
message: Rex.t(:"operation.error.name_too_long", max: max)
38+
end
39+
3040
private def validate_user_id_required
3141
validate_required user_id,
3242
message: Rex.t(:"operation.error.user_id_required")

src/shield/operations/mixins/validate_oauth_client.cr

+10-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Shield::ValidateOauthClient
77
limit_redirect_uris_count
88

99
validate_name_required
10+
validate_name_length
1011
validate_name_unique
1112
validate_name_valid
1213
validate_name_allowed
@@ -22,8 +23,15 @@ module Shield::ValidateOauthClient
2223
include Lucille::ValidateUserExists
2324

2425
private def validate_name_required
25-
validate_required name,
26-
message: Rex.t(:"operation.error.name_required")
26+
validate_required name, message: Rex.t(:"operation.error.name_required")
27+
end
28+
29+
private def validate_name_length
30+
max = 255
31+
32+
validate_size_of name,
33+
max: max,
34+
message: Rex.t(:"operation.error.name_too_long", max: max)
2735
end
2836

2937
private def validate_name_unique

0 commit comments

Comments
 (0)