Skip to content

๐Ÿ› fix : OAuth2 ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URI ํ™˜๊ฒฝ๋ณ„ ์ž๋™ ์„ ํƒ#45

Merged
ThreeeJ merged 2 commits into
mainfrom
fix/#44
May 11, 2026
Merged

๐Ÿ› fix : OAuth2 ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URI ํ™˜๊ฒฝ๋ณ„ ์ž๋™ ์„ ํƒ#45
ThreeeJ merged 2 commits into
mainfrom
fix/#44

Conversation

@ThreeeJ

@ThreeeJ ThreeeJ commented May 11, 2026

Copy link
Copy Markdown
Contributor

๐Ÿ” ๊ด€๋ จ ์ด์Šˆ


โœ… ์ž‘์—… ๋ถ„๋ฅ˜

  • ๋ฒ„๊ทธ ์ˆ˜์ •
  • ์‹ ๊ทœ ๊ธฐ๋Šฅ
  • ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ๋ณ€๊ฒฝ
  • ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง
  • ๊ธฐ๋Šฅ ์ˆ˜์ •

โœจ ์ž‘์—… ๋‚ด์šฉ

  • application.properties์˜ app.oauth2.front-redirect-uri๋ฅผ .local / .deploy ๋‘ ๊ฐœ๋กœ ๋ถ„๋ฆฌ
  • CookieOAuth2AuthorizationRequestRepository์— REDIRECT_TARGET_COOKIE ์ƒ์ˆ˜ ์ถ”๊ฐ€
  • OAuth ์‹œ์ž‘ ์‹œ์ (saveAuthorizationRequest)์—์„œ ์š”์ฒญ์˜ Referer ํ—ค๋”๋ฅผ ๋ณด๊ณ  "local" ๋˜๋Š” "deploy"๋ฅผ ์ฟ ํ‚ค์— ์ €์žฅ
  • OAuth2LoginSuccessHandler์—์„œ ์œ„ ์ฟ ํ‚ค๋ฅผ ์ฝ์–ด ํ™˜๊ฒฝ๋ณ„ ํ”„๋ก ํŠธ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URI๋ฅผ ์„ ํƒ, ์‚ฌ์šฉ ํ›„ ์ฟ ํ‚ค ์‚ญ์ œ
  • Referer๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ(๋ธŒ๋ผ์šฐ์ € ์ •์ฑ…, ์ฃผ์†Œ์ฐฝ ์ง์ ‘ ์ž…๋ ฅ ๋“ฑ) deploy๋กœ ํด๋ฐฑ

๐Ÿ‘ฅ ์ „๋‹ฌ์‚ฌํ•ญ


โœ… ์ฒดํฌ๋ฆฌ์ŠคํŠธ

  • ์ฝ”๋“œ๊ฐ€ ์ปดํŒŒ์ผ ๋ฐ ๋นŒ๋“œ๋จ
  • ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•จ
  • ๊ด€๋ จ ๋ฌธ์„œ๊ฐ€ ์—…๋ฐ์ดํŠธ๋จ
  • ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ํ™•์ธํ•จ

๐Ÿ“ธ ์Šคํฌ๋ฆฐ์ƒท


๐Ÿ’ก ๋ฐฐ์šด ๊ฒƒ / ์‹œ๋„ํ•œ ๊ฒƒ / ๊ณ ๋ฏผํ•œ ์ 

@ThreeeJ ThreeeJ self-assigned this May 11, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces dynamic OAuth2 redirect URI selection by identifying whether the request originates from a local or deployed environment. It achieves this by checking the 'Referer' header in the CookieOAuth2AuthorizationRequestRepository and storing the target environment in a cookie, which is then used by the OAuth2LoginSuccessHandler to determine the final redirect URL. Review feedback suggested improving the security of the environment detection logic to prevent spoofing via the 'Referer' header and recommended using constants instead of hardcoded strings for better maintainability and consistency across the codebase.

implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {

private static final String COOKIE_NAME = "oauth2_auth_request";
public static final String REDIRECT_TARGET_COOKIE = "redirect_target";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

"local" ๋ฐ "deploy"์™€ ๊ฐ™์€ ํ™˜๊ฒฝ ์‹๋ณ„ ๋ฌธ์ž์—ด์„ ์ƒ์ˆ˜๋กœ ์ •์˜ํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋ฉด ์˜คํƒ€๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  OAuth2LoginSuccessHandler ๋“ฑ ๋‹ค๋ฅธ ํด๋ž˜์Šค์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Suggested change
public static final String REDIRECT_TARGET_COOKIE = "redirect_target";
public static final String REDIRECT_TARGET_COOKIE = "redirect_target";
public static final String TARGET_LOCAL = "local";
public static final String TARGET_DEPLOY = "deploy";


// Referer ํ—ค๋”๋กœ ์ถœ๋ฐœ์ง€(local/deploy) ํŒ๋‹จ ํ›„ ์ฟ ํ‚ค ์ €์žฅ
String referer = request.getHeader("Referer");
String target = (referer != null && referer.contains("localhost")) ? "local" : "deploy";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

referer.contains("localhost") ์กฐ๊ฑด์€ http://attacker.com/localhost์™€ ๊ฐ™์ด ๋„๋ฉ”์ธ์ด ์•„๋‹Œ ๊ฒฝ๋กœ์— localhost๊ฐ€ ํฌํ•จ๋œ ๊ฒฝ์šฐ์—๋„ ์˜๋„์น˜ ์•Š๊ฒŒ local ํ™˜๊ฒฝ์œผ๋กœ ์˜คํŒํ•  ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. startsWith๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ŠคํŠธ ๋ถ€๋ถ„์„ ๋ณด๋‹ค ๋ช…ํ™•ํ•˜๊ฒŒ ๊ฒ€์‚ฌํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

Suggested change
String target = (referer != null && referer.contains("localhost")) ? "local" : "deploy";
String target = (referer != null && (referer.startsWith("http://localhost") || referer.startsWith("https://localhost"))) ? TARGET_LOCAL : TARGET_DEPLOY;

Comment on lines +46 to +47
.orElse("deploy");
String redirectUri = "local".equals(target) ? localRedirectUri : deployRedirectUri;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

ํ•˜๋“œ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด ๋Œ€์‹  CookieOAuth2AuthorizationRequestRepository์— ์ •์˜๋œ ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ด๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

Suggested change
.orElse("deploy");
String redirectUri = "local".equals(target) ? localRedirectUri : deployRedirectUri;
.orElse(CookieOAuth2AuthorizationRequestRepository.TARGET_DEPLOY);
String redirectUri = CookieOAuth2AuthorizationRequestRepository.TARGET_LOCAL.equals(target) ? localRedirectUri : deployRedirectUri;

@ThreeeJ ThreeeJ merged commit ea77aaf into main May 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix : OAuth2 ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ URI ํ™˜๊ฒฝ๋ณ„ ์ž๋™ ์„ ํƒ

1 participant