The annotation processing to deliver BigFatSecuritySwitch (or deferring to
another method) is basically what I'd do.

Provided the build fails, I guess it doesn't really matter whether it's a
method-not-found, or an enforcer-style rule (e.g: No calling @deprecated).
Basically I *know* I'm lazy, and unless the toolchain basically forces me
to fix something, I know I never will. My indolence then means it's hard to
remove old, crufty things.

As to whether using annotations to both provide the machinery for API
manipulation *and* the documentation / 'end-user API' for it I guess is a
judgement call. Personally I rather prefer in my IDE if I type
JenkinsThing<dot> it doesn't provide me with the history of the universe of
methods with annotations my IDE won't understand. But I also appreciate
that there are platform constraints (e.g: you can't tell which java
interface a method was called through, meaning interface-versioning is
quite hard) that mean it's hard to satisfy everyone.

I'll prepare the barricades before someone suggests OSGi or other similar
self-abuse toolkits :-)


On Wed, Sep 16, 2015 at 12:27 PM, Stephen Connolly <
[email protected]> wrote:

> Well @Restricted(DoNotUse.class) should give you a build time failure
> if you are using the Maven toolchain... if you are using the groovy
> toolchain I presume you can add the same checks...
>
> What I think you are thus asking for is something like
>
> @SecureAlternative(name="getFooSecure")
> public Foo getFoo(...) {
> ...
> }
>
> public Foo getFooSecure(...) {
> ...
> }
>
> So that when the annotation is processed the annotated method gets the
> equivalent injected:
>
> if (BigFatSecuritySwitch.isActive()) {
>   return getFooSecure(...);
> }
>
> at the start
>
> If we design the BigFatSecuritySwitch.isActive() method correctly, the
> JVM should be able to inline all the way and remove the cost of the
> branch point.
>
> The downside that I see is that we end up in the nightmare of the
> getInstance() -> getActiveInstance() transition (which should really
> have been adding @NonNull to getInstance() and adding a
> getInstanceUnchecked() method)
>
> So perhaps an even better way would be
>
> @UnsecureAlternative(name="getFooUnsafe", until="1.650")
> public Foo getFoo(...) {
> ...
> }
>
> private Foo getFooUnsafe(...) {
> ...
> }
>
> With the above you inject (as long as Jenkins' pom.xml's version <
> 1.650) the following into getFoo()
>
> if (!BigFatSecuritySwitch.isActive()) {
>   return getFooUnsafe(...);
> }
>
> We could then add an Admin monitor that looks at the until fields on
> Jenkins and tells you if any of your plugins were compiled against a
> version of Jenkins older than the until... similarly the plugin
> manager could alert you for plugins that are compiled against an older
> jenkins than your oldest until... (we could expose the same logic for
> plugin dependencies so that plugins could use the @UnsecureAlternative
> annotation also)
>
> The advantage of @UnsecureAlternative is that we get to move the API
> contracts while allowing people to flick the switch if they don't care
>
> WDYT?
>
> On 16 September 2015 at 11:58, Nigel Magnay <[email protected]>
> wrote:
> > From the perspective of a plugin developer and Jenkins Instance owner,
> who
> > often goes months at a time between re-visiting plugin code, I'd like the
> > following (ymmv, of course!):
> >
> > 1) I'd like the interfaces I build to, to not have at all interface
> methods
> > and fields that are no longer secure / broken. I.E: If I upgrade my POM
> to
> > point to a 'new' version of Jenkins 1.629, I'd like the compile to fail
> if
> > I'm using something that is broken, security or otherwise.
> >
> > Having @Restricted and @Deprecated annotations all over the place just
> means
> > I'm likely never to even notice, let alone actually get around to doing
> the
> > work to update it. Looking at the API becomes a total mess of ancient
> cruft.
> > Every time I see "@deprecated" I just think "oh yeah.. when?"
> >
> > 2) I don't want to have to touch plugins when updating an LTS version,
> and I
> > don't want LTS versions to break 'just because of security'. I'm
> firewalled,
> > and frankly couldn't care less about security - it's just a gigantic ache
> > for me that I'd like a big red button marked 'OFF'.
> >
> > Thus:
> >
> > Could we have a mechanism where Jenkins maintains all the old APIs in the
> > binary (I.E: allows plugins build against older versions of Jenkins to
> > continue to function without change) - but you build against a 'stripped'
> > version of the current, "correct" API?
> >
> > In the example where the signature doesn't change, but the contract
> > potentially does - if it's not reasonable to be able to turn off the
> > security change (big-red-off), then I think the signature should change.
> The
> > interface has been versioned.
> >
> > At least this way you could probably have tight security on installs that
> > need it (If jenkins is Version X, all plugins must be built to that
> version
> > or later, and @Restricted methods can safely fail closing the back door).
> > You could also use the jenkins version the plugin built against to
> control
> > whether your API - by default - applies new semantics or old ones.
> >
> >
> >
> > On Tue, Sep 15, 2015 at 11:39 AM, Stephen Connolly
> > <[email protected]> wrote:
> >>
> >> Those of us who are on the jenkins-cert list have probably seen my
> >> comments about how there needs to be some guidance from the community
> >> on how far SECURITY issue fixes can go.
> >>
> >> I am starting this thread to try and start compiling that guidance.
> >>
> >> The general problem (as I cannot share the specifics outside of the
> >> jenkins-cert list) is as follows:
> >>
> >> * User raises a SECURITY issue from noticing some implicitly defined
> >> API of Jenkins has a hole of some sort
> >> * We have to fix the issue, but fixing it will involve changing the
> >> implicitly defined API and thus risking breaking existing "users" of
> >> the implicitly defined API
> >> * Much heated debate around should we leave the old API present and
> >> try and redirect to the new one (thereby leaving the hole open) or
> >> break existing plugins and close the hole.
> >>
> >> In some cases it is possible to use a system property to re-enable the
> >> hole for those users who are accepting of the risk... but other cases
> >> require changing class structures (this can range from encapsulating
> >> fields to completely reworking the java class that gets returned)
> >>
> >> My view is that a hole is a hole until it is fully plugged, and if
> >> plugging the hole means that some plugins break, well sorry but
> >> SECURITY... now by all means we should seek to minimize that breakage
> >> *while closing the hole*... and where possible we should provide a
> >> System property based switch to re-open the hole for those users who
> >> upgrade and are ok with the risk.
> >>
> >> Let's take a semi-concrete example:
> >>
> >> In order to fix SECURITY-144 we had to change the interface of
> >> h.r.Callable to include the role checking... being pre-java 8 we
> >> cannot use default methods, so this was a backwards incompatible
> >> change... any plugin that does not implement the role checking method
> >> would potentially be broken... as a result - and after much debate -
> >> it was decided that a majority of people implicitly trust their slaves
> >> as much as the master and so the role checking is likely not required
> >> for maybe 60-70% of installations. Thus the role checking ships off by
> >> default and we implemented a way to whitelist plugins that are
> >> compiled without role-checking support. Thus if you have slaves that
> >> are less trusted than the master you can opt-in to the higher security
> >> requirements... if there are plugins that you need that get broken,
> >> you can white-list those specific plugins if you absolutely need to.
> >>
> >> The point here is that we closed the hole. We felt the risk of plugins
> >> being broken was sufficiently high that the hole would not be closed
> >> by default (The plan is to measure the plugins with support for roles
> >> and once above a threshold then turn on secure by default) but when
> >> the security is turned on it is on.
> >>
> >> So what kind of things do we need guidance on:
> >>
> >> * Some methods of some objects allow you to discover information about
> >> other objects that you do not have permission to discover.
> >>     - Do we just protect the ways that we know about and leave the
> >> original method present with a @Restricted(DoNotUse.class) so that
> >> when plugins upgrade their core version they are forced to switch to
> >> the new method; or
> >>     - Do we change the contract of the current method (so it now
> >> returns maybe a null or throws an exception or omits entries from a
> >> collection) so that the method does what it was originally supposed to
> >> do but didn't... this may break existing plugins in fun and exciting
> >> ways
> >>
> >> * Some objects have public fields that are either mutable or of a type
> >> that needs to be changed in order to remove the hole.
> >>     - Do we leave the field as is and just introduce the new accessor
> >> methods - leaves the hole as is... so we have to rely on adding a
> >> stapler action method (since they are higher priority than public
> >> fields) to mask that route to discovery via Web and hope that there
> >> are no other routes to that field...
> >>     - Do we say kill that field, you shouldn't have been using it (oh
> >> and let's hire a hitman to find the lazy developer who made a public
> >> field rather than use their IDE to generate getters and setters) and
> >> risk breaking any plugins that actually use the field.
> >>
> >> * Some HTTP requests can be used for more than their original intended
> >> purpose. Jenkins Admins may well have discovered this and - rather
> >> than thinking oh look a security issue - used such back doors to do
> >> important things for their instance
> >>     - Do we try and make such back-door usage as safe as possible -
> >> which in a sense makes this side-usage officially part of the API of
> >> that HTTP request
> >>     - Do we lock the HTTP request down to its original intended
> >> purpose and break any side-effect usage that Jenkins Admins were
> >> hijacking?
> >>
> >> There are probably other classes of guidance required, but my brain is
> >> melted trying to derive the classes from the issues I am aware of so I
> >> cannot think of any others at the moment.
> >>
> >> It all boils down to the question:
> >>
> >> Which is more important, maintaining backwards compatibility or fixing
> >> the security hole.
> >>
> >> My view is that fixing the security hole trumps backwards
> >> compatibility, if we have to break a few plugins or a Jenkins admin
> >> has to find a different way to solve their problem... well sorry but
> >> SECURITY... that doesn't mean we should start by breaking backwards
> >> compatibility, rather we should do everything we can to close the hole
> >> while maintaining backwards compatibility... but when that isn't
> >> enough to close the hole (and usually it is not enough BTW)... well we
> >> need to close the hole.
> >>
> >> Over to you!
> >>
> >> --
> >> You received this message because you are subscribed to the Google
> Groups
> >> "Jenkins Developers" group.
> >> To unsubscribe from this group and stop receiving emails from it, send
> an
> >> email to [email protected].
> >> To view this discussion on the web visit
> >>
> https://groups.google.com/d/msgid/jenkinsci-dev/CA%2BnPnMw6rhFBDP-jjqaaNN8YZoxT1kqGUXR1F9hvDT6s%2B01_Bw%40mail.gmail.com
> .
> >> For more options, visit https://groups.google.com/d/optout.
> >
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Jenkins Developers" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to [email protected].
> > To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/jenkinsci-dev/CAPYP83R8yd%3DD%3D%2BeQdoGVCgsOk4_YyuXn7K4ePqZe4DLdQhL%2Bxg%40mail.gmail.com
> .
> >
> > For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Jenkins Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jenkinsci-dev/CA%2BnPnMyxdOjQyRZ2QUBqOrW791nzQPuP%3DK5CmEWszhJTzynC6A%40mail.gmail.com
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jenkinsci-dev/CAPYP83R3k8W5Hxq7FdKjpdA0VBMoLyV%3D5ehX%2BNHbGH4uVmcnyQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to