声纳规则中关于 Spring 的 “@RequestMapping” 方法应该是 “public” 的准确吗?

huangapple go评论71阅读模式
英文:

Is the Sonar rule for Spring '"@RequestMapping" methods should be "public"' accurate?

问题

以下是翻译好的内容:

有一个适用于 Spring 的声纳规则,规定:“@RequestMapping”方法应该是“public”。

并且给出了以下示例:

@RequestMapping("/greet", method = GET)
private String greet(String greetee) {  // 非合规

@RequestMapping("/greet", method = GET)
public String greet(String greetee) {  // 合规

以下是给出的原因:

将敏感方法标记为私有方法可能看起来是控制调用此类代码的一种好方法。然而,不是所有的 Spring 框架都会忽略方法的可见性。例如,如果您尝试通过将敏感的、私有的 @RequestMapping 方法标记为 @Secured 来控制对其的 web 访问...它仍然会被调用,无论用户是否有权限访问它。这是因为非公共方法不会应用 AOP 代理。

对于私有方法,这听起来是合理的,但对于默认(包保护)可见性是否真的成立呢?

即:

@RequestMapping("/greet", method = GET)
String greet(String greetee) {

来源:https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-3751

编辑:只是为了澄清,我并不是在问 @RequestMapping 方法是否必须是 public,它并不是必须的。请参阅 spring-restbucks 获取示例。

我在问的是,将方法声明为 package-private 而不是 public,是否真的是一个漏洞,正如 Sonar 所建议的那样。

编辑 2:我在这里创建了一个项目,以尝试演示它:https://github.com/barrycommins/boot2-security

测试表明 @PreAuthorize 规则适用于控制器方法,即使它是包私有的。是否应该如此,以及是否可靠,我不太确定。

英文:

There's a sonar rule for Spring that states: "@RequestMapping" methods should be "public"

And gives these examples:

@RequestMapping("/greet", method = GET)
private String greet(String greetee) {  // Noncompliant

@RequestMapping("/greet", method = GET)
public String greet(String greetee) {  // Compliant

These are the reasons given:

> marking a sensitive method private may seem like a good way to control how such code is called. Unfortunately, not all Spring frameworks ignore visibility in this way. For instance, if you've tried to control web access to your sensitive, private, @RequestMapping method by marking it @Secured ... it will still be called, whether or not the user is authorized to access it. That's because AOP proxies are not applied to non-public methods."

This seems reasonable for private methods, but does it really hold true for default (package-protected) visibility?

i.e.

@RequestMapping("/greet", method = GET)
String greet(String greetee) { 

Source: https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-3751

edit: just to clarify, I'm not asking if a @RequestMapping method has to be public, it doesn't. See spring-restbucks for an example

I'm asking if declaring the method as package-private rather than public is really a vulnerability, as suggested by Sonar.

edit 2: I created a project here to try to demonstrate it: https://github.com/barrycommins/boot2-security

The tests show that the @PreAuthorize rules are applied to the controller method, even though it is package private.
Whether that should be the case, and whether it's reliable, I'm not sure.

答案1

得分: 1

从我所看到的情况来看,似乎评论和现有答案试图解决细节问题,而这并不是真正的您的问题。

我要做一些假设,因为我还没有调查过这个问题的细节。我只会根据我在这里看到的内容来理解这个问题。

在我看来,错误信息试图传达的关键是,如果实际上不是这样,就不应该将某些内容标记为非公开。我认为这是有争议的,但这就是错误消息在我看来传达的内容。

添加 @RequestMapping 注解的整个目的是为了使该方法能够从服务外部被调用。实际上,这意味着该方法只能从服务外部被调用。如果您将该方法声明为包私有方法,那会导致意图混淆。

另一方面,我现在能够看到一个将带有 @RequestMapping 的方法标记为“私有”的论点。如果该方法确实只会从服务外部被调用,而不会从任何应用程序代码(不包括框架代码)中调用,除了使用“私有”还能如何表达这一点呢?

英文:

From what I can see, it seems like the comments and the existing answer are trying to address the details, when that isn't really your question.

I'm going to make some assumptions, because I haven't investigated the details of this issue. I'm just going to read into this what I see here.

In my opinion, the key thing the error message is trying to convey is that you shouldn't label something non-public if it actually isn't. I think this is debatable, but that is what the error message is saying, again, in my opinion.

The entire point of adding a @RequestMapping annotation is to prepare that method for being called from outside the service. In fact, it implies that the method is ONLY called from outside the service. If you declare that method as package private, that presents a confusing intent.

On the other hand, I can now see an argument to mark methods with @RequestMapping as "private". If the method will truly only ever be called from outside the service, and not from any application code (excluding framework code), how else could you express that except with "private"?

huangapple
  • 本文由 发表于 2020年10月6日 21:16:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64226612.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定