Skip to content

Fix a vulnerability in Statistics.pm and the macro PGstatisticsmacros.pl. #1220

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

drgrice1
Copy link
Member

Fix a vulnerability in Statistics.pm and the macro PGstatisticsmacros.pl.

This vulnerability allows a problem to write to any location or overwrite any file that the server has write permission to.

The problem is that the write_array_to_CSV method of the Statistics.pm module takes a file name as its first argument and writes to that file without question.

To fix this the method instead uses the new WeBWorK::PG::IO::saveDataToFile method added in #1219 which refuses to write anything outside of the html temporary directory.

Note that the make_csv_alias method of the Statistics.pm module was dropped because it uses an invalid approach to creating a unique file name and is not needed. So there is no need for the Statistics package to even be an object. Now there is just the method write_array_to_CSV.

Previously the insertDataLink method of PGstatisticsmacros.pl accepted the $PG object for its first argument. That first argument is still accepted, but is dropped if given, and there is no need to pass that argument anymore. The macro has direct access to the $PG variable so it is not a needed parameter.

Also, a new optional last argument to the insertDataLink is accepted. If provide this argument must be a reference to a hash, and the key/value pairs in that hash will be added as attributes to the HTML a tak that is returned. If this parameter is not provided or it is but does not contain a download attribute, then a default download attribute with value data.csv will be added.

Note that the insertDataLink method is not used by any problem in the OPL or Contrib. Furthermore, nothing in the Statistics.pm module is directly used by any problem in OPL or Contrib. Backwards compatibility is maintained for the insertDataLink method for anyone that may have been using it, but not for the Statistics.pm module. It was not intended that the module be used directly anyway.

This fixes the second of the three ways that I know of for a problem to directly write to anywhere that the server has permission to do so.

@drgrice1
Copy link
Member Author

drgrice1 commented Mar 25, 2025

Attached are two problems to test this with.
PGstatisticsmacrosTests.zip

The pgstatistics-write-csv.pg problem can be used to test that things work with develop or main and with this pull request. You will need to comment out or delete the second part in the BEGIN_PGML/END_PGML section to test with develop or main though.

The pg-statistics-vulnerability.pg file demonstrates the vulnerability. It will write a badfile.csv file to the courses directory. With minor modification it would write any file with whatever contents are desired though.

@drgrice1
Copy link
Member Author

By the way, don't expect an immediate pull request for the third way that I know of that a problem can write a file wherever it wants to that the server has write permissions for. That one will take quite a bit more work.

@pstaabp
Copy link
Member

pstaabp commented Mar 27, 2025

I see the second problem poses a problem and this fixes that.

Just to clarify, Is the second problem as an example of using the insertDataLink without the $PG passing as the first argument?

@drgrice1
Copy link
Member Author

The pgstatistics-write-csv.pg problem is an example of using the insertDataLink method both with and without passing $PG as the first argument. In the BEGIN_PGML/END_PGML section of that problem there are two calls to insertDataLink. The first passes the $PG parameter, and the second doesn't. It does not demonstrate the vulnerability. The other problem does.

@drgrice1 drgrice1 force-pushed the statisticsmacros-vulnerability branch 2 times, most recently from bdb8cff to 6a4fb39 Compare April 1, 2025 20:15
@drgrice1 drgrice1 force-pushed the statisticsmacros-vulnerability branch from 6a4fb39 to f9029e0 Compare April 8, 2025 15:00
Copy link
Member

@pstaabp pstaabp left a comment

Choose a reason for hiding this comment

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

Relooking after the other PR went it. Looks good.

…ros.pl`.

This vulnerability allows a problem to write to any location or
overwrite any file that the server has write permission to.

The problem is that the `write_array_to_CSV` method of the
`Statistics.pm` module takes a file name as its first argument and
writes to that file without question.

To fix this the method instead uses the new `WeBWorK::PG::IO::saveDataToFile`
method which refuses to write anything outside of the html temporary
directory.

Note that the `make_csv_alias` method of the `Statistics.pm` module was
dropped because it uses an invalid approach to creating a unique file
name and is not needed.  So there is no need for the `Statistics`
package to even be an object.  Now there is just the method
`write_array_to_CSV`.

Previously the `insertDataLink` method of `PGstatisticsmacros.pl`
accepted the `$PG` object for its first argument.  That first argument
is still accepted, but is dropped if given, and there is no need to pass
that argument anymore. The macro has direct access to the `$PG` variable
so it is not a needed parameter.

Also, a new optional last argument to the `insertDataLink` is accepted.
If provide this argument must be a reference to a hash, and the
key/value pairs in that hash will be added as attributes to the HTML `a`
tak that is returned. If this parameter is not provided or it is but
does not contain a `download` attribute, then a default `download`
attribute with value `data.csv` will be added.

Note that the `insertDataLink` method is not used by any problem in the
OPL or Contrib.  Furthermore, nothing in the `Statistics.pm` module is
directly used by any problem in OPL or Contrib. Backwards compatibility
is maintained for the `insertDataLink` method for anyone that may have
been using it, but not for the `Statistics.pm` module.  It was not
intended that the module be used directly anyway.

This fixes the second of the three ways that I know of for a problem to
directly write to anywhere that the server has permission to do so.
@drgrice1 drgrice1 force-pushed the statisticsmacros-vulnerability branch from f9029e0 to 7d32d6e Compare April 8, 2025 23:13
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.

2 participants