Repository navigation
Conversation
980577a to
bc9523c
Compare
pstaabp
left a comment
There was a problem hiding this comment.
Problems still work. I think this was mainly for getting the tests to run clean.
Can you explain what the vulnerability is?
No, this was actually an important mechanism for making inheritance work in extended contexts. The solution use here (using fully qualified names) is not a general solution, as it requires context authors to take the possibility that they may be extended into account. There are other contexts that use inheritance from a common package like this (e.g., the units context does). Will it be required to be modified in order to allow it to be extended by some other context in the future? If Unfortunately, I don't currently have the time to work out the new approach, and am not sure when I would be able to get to it. But I would encourage you not to make fully qualified method calls when proper inheritance is the natural way to proceed, as it is in the significant-figures context. If this doesn't work with extensions, it is better to fix the extension mechanism rather than change every context that might be extended someday. |
|
The updated |
No need, your description is sufficient. I didn't realize |
|
I will think more about the extension mechanism and how it can be made to work without fully qualified method names. If I remember correctly, the issue arose in the significant-figures context because its implicit multiplication function is complicated and uses a method that doesn't get subclassed during an extension. It may be that the usual overridden classes work correctly, but this special one didn't. It will take some investigation to figure out a new approach. |
|
I agree that for the |
|
I guess I should give full disclosure here. I have overinflated the security issue slightly for this. At this point all production renderings (for webwork2 or the standalone renderer) occur inside of a The issue does occur when rendering a problem directly via a script (such as is done in the unit tests). So as long as we ensure that we only execute trusted problem code in the unit tests, and perhaps give strong warnings to those that use PG in this way that extra precautions should be taking to ensure that untrusted problem code is not executed, then the stripping of the |
The `WWSafe.pm` module is based on version 2.47 of the upstream `Safe.pm` module, which includes a `_clean_stash` method that deletes the `DESTROY`, `AUTOLOAD`, and overload methods defined by compartment code after the compartment code is executed. This is intended to prevent that code from running outside of the safe compartment (for instance when an object is destroyed, since destruction happens outside the compartment), where it would run with the `main::` symbol table rather than the compartment's isolated one. However, this breaks macros that legitimately define such methods. For example, the `AUTOLOAD` method of `context::Extensions::Super` in `contextExtensions.pl` (used by `contextFraction.pl`, `contextUnits.pl`, and `contextSignificantFigures.pl`) is deleted, which breaks any context that extends another context, such as using the Units context together with the SignificantFigures context. The other improvements from the 2.47 update (the `reval`/`rdo` reentrancy handling and the wrapping of code references returned from the compartment) are retained. This is an alternative, perhaps slightly less secure but yet secure enough, approach to fixing the issue created with the `contextExtensions.pl` macro by the updated `WWSafe.pm` module to openwebwork#1564. Note that this completely negates openwebwork#1565 as well. See my comments in openwebwork#1564 (comment) about why this is "secure enough". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The `WWSafe.pm` module is based on version 2.47 of the upstream `Safe.pm` module, which includes a `_clean_stash` method that deletes the `DESTROY`, `AUTOLOAD`, and overload methods defined by compartment code after the compartment code is executed. This is intended to prevent that code from running outside of the safe compartment (for instance when an object is destroyed, since destruction happens outside the compartment), where it would run with the `main::` symbol table rather than the compartment's isolated one. However, this breaks macros that define such methods. For example, the `AUTOLOAD` method of `context::Extensions::Super` in `contextExtensions.pl` (used by `contextFraction.pl`, `contextUnits.pl`, and `contextSignificantFigures.pl`) is deleted, which breaks any context that extends another context, such as using the Units context together with the SignificantFigures context. The other improvements from the 2.47 update (the `reval`/`rdo` reentrancy handling and the wrapping of code references returned from the compartment) are retained. This is an alternative, perhaps slightly less secure but yet secure enough, approach to fixing the issue created with the `contextExtensions.pl` macro by the updated `WWSafe.pm` module to openwebwork#1564. Note that this completely negates openwebwork#1565 as well. See my comments in openwebwork#1564 (comment) about why this is "secure enough". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Yes, that is why I was sad to see it go. I have taken a quick look at the current |
|
OK, I think I have a work-around for the our @ISA = ();
sub super {
my ($self, $method, $context) = @_;
my $selfclass = ref($self);
my $class = $self->superClass($context);
my $code = $class->can($method);
die "Can't locate object method \"$method\" via package \"" .
($selfclass || $self) . '"' . (Value::getCaller() // '') unless $code;
return !$selfclass ? $code : sub {
unshift(@ISA, $class);
my @result = wantarray ? Parser::Eval($code, @_) : (Parser::Eval($code, @_));
shift(@ISA);
die $@ if $@;
return wantarray ? @result : $result[0];
};
}and remove the |
This method was only needed for a context that extends the
SignificantFigures context (for example the Units context via
`context::Units::extending('SignificantFigures')`) because the
`contextSignificantFigures.pl` macro calls the methods of its
`context::SignificantFigures::common` package as `$self->STRING`,
`$self->COPY`, etc. When another context extends the SignificantFigures
context, those calls are made with `$self` blessed into the extension
context's classes, and those classes do not inherit from that package.
So those methods were not found, and the `AUTOLOAD` method was used to
find them in the extended class. Instead the `contextSignificantFigures.pl`
macro now calls those methods with their fully qualified names, so that
they are found regardless of the class of `$self`.
The updated `WWSafe.pm` module based on `Safe.pm` version 2.47 (added in
openwebwork#1520) deletes the `AUTOLOAD` method (as well as the `DELETE` method and
any overloads) in its `_clean_stash` call, and so the current `AUTOLOAD`
method no longer works, and problems using the Units context extending
the SignificantFigures context were broken.
Allowing code that runs in the safe compartment to define a `DESTROY` or
`AUTOLOAD` method or to defined custom overloads is a security
vulnerability that cannot be allowed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bc9523c to
efceaee
Compare
|
Just to be clear, my proposed change to the |
|
Interesting approach. I will try it out. |
|
I've changed the An alternative would be to use |
|
I am seeing an issue with the All tests pass if I instead use the sub super {
my ($self, $method, $context) = @_;
my $selfclass = ref($self);
my $class = $self->superClass($context);
my $code = $class->can($method);
die qq{Can't locate object method "$method" via package "}
. ($selfclass || $self) . '"'
. (Value::getCaller() // '')
unless $code;
return !$selfclass ? $code : sub {
bless $self, $class;
my @result = wantarray ? Parser::Eval($code, @_) : (Parser::Eval($code, @_));
bless $self, $selfclass;
die $@ if $@;
return wantarray ? @result : $result[0];
};
}When using the The unit tests are passing with the |
|
Try removing the |
|
Yeah, that seems to work. I will change this branch to that code. |
parent methods via the `super` call and a temporary modification to the `@ISA` array instead.
This method was only needed for a context that extends the SignificantFigures context (for example the Units context via
context::Units::extending('SignificantFigures')) because thecontextSignificantFigures.plmacro calls the methods of itscontext::SignificantFigures::commonpackage as$self->STRING,$self->COPY, etc. When another context extends the SignificantFigures context, those calls are made with$selfblessed into the extension context's classes, and those classes do not inherit from that package. So those methods were not found, and theAUTOLOADmethod was used to find them in the extended class.Instead theInstead inherited parent methods are looked up with the approach of temporarily modifying thecontextSignificantFigures.plmacro now calls those methods with their fully qualified names, so that they are found regardless of the class of$self.@ISAarray that @dpvc suggested (see #1564 (comment) and ensuing comments).The updated
WWSafe.pmmodule based onSafe.pmversion 2.47 (added in #1520) deletes theAUTOLOADmethod (as well as theDELETEmethod and any overloads) in its_clean_stashcall, and so the currentAUTOLOADmethod no longer works, and problems using the Units context extending the SignificantFigures context were broken.Allowing code that runs in the safe compartment to define a
DESTROYorAUTOLOADmethod or to defined custom overloads is a security vulnerability that cannot be allowed.