Skip to content
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

XSS vulnerabilities in from, to and range parameters. #95

Open
rsdoiel opened this issue Jan 23, 2020 · 17 comments
Open

XSS vulnerabilities in from, to and range parameters. #95

rsdoiel opened this issue Jan 23, 2020 · 17 comments

Comments

@rsdoiel
Copy link

rsdoiel commented Jan 23, 2020

There is an XSS vunerablity in the "from", "to" and "range" GET parameters for URLs accessing IRStats2 1.0.1 as well as IRStats2 1.1
under EPrints 3.3.

Example paths

    /cgi/stats/report/requests?from=&range=</script><svg/onLoad=prompt(0)>
    /cgi/stats/report/requests?from=&to=</script><svg/onLoad=prompt(0)>
    /cgi/stats/report/requests?from=&range=</script><svg/onLoad=prompt(0)>
    /cgi/stats/report/requests?from=</script><svg/onLoad=prompt(0)>
    /cgi/stats/report/requests?from=</script><svg/onLoad="console.log('Bad news')">

Before processing "from", "to", "range" the values need to be sanitized (e.g. the < and > stripped at a minimum). Not sure where this should happen in the Perl code.

Is IRStats2 being maintained (last update appears to be 2017 and two pull requests are unanswered)?

Thanks,

Robert

@jesusbagpuss
Copy link
Contributor

Hi @rsdoiel ,
The method EPrints::Plugin::Stats::Context::to_json is used in EPrints::Plugin::Stats::View::Table to embed values into a call to some javascript, which looks like where the issue is.

The real fix would be to validate the values on their way in, in EPrints::Plugin::Stats::Context::parse_context.

At a glance, the list of @FIELDS at the top of the Context module could all be validatable by looking things up against the config, or simple RegExps (e.g. for dates).

Does that help initially?

I can't comment on the maintenance of this module.
There is a fork of IRStats in the eprintug area (https://github.com/eprintsug/irstats2/) that looks to be ahead of this one, but I'm not sure which, if either is the most maintained.

PS There's also this comment: https://github.com/eprints/irstats2/blob/master/lib/plugins/EPrints/Plugin/Stats/Context.pm#L365 ..!?

@mpbraendle
Copy link

Regarding maintenance, we had implemented locally implemented many GUI changes especially for better usability, responsive GUI and improving accessibility, as well as new reports for citation, journal/publisher and Open Access statistics.
See https://www.zora.uzh.ch/cgi/stats/report for a live demo.
Some of the code was contributed back here:
https://github.com/eprintsug/OpenAccessType
https://github.com/eprintsug/IRStats2-Citation

@jesusbagpuss
Copy link
Contributor

More investigation:
For 'range', it can be \d+[dmy], or a year \d{4}.
In EPrints::Plugin::Stats::Utils there are some validation routines, but these apparently aren't always invoked, or don't strip 'bad' values.

@jesusbagpuss
Copy link
Contributor

jesusbagpuss commented Jan 24, 2020

(just some notes for reference):
Params read in from request:
https://github.com/eprints/irstats2/blob/master/lib/plugins/EPrints/Plugin/Stats/Context.pm#L96

  • could sanitise them all here (html entities-wise at least).

Fields referenced during parse_context:

  • irs2report: ???
  • set_name: use part of this logic: EPrints::Plugin::Stats::Context::has_valid_set
  • set_value: as above
  • from: \d{4} or \d{6} or \d{8}
  • to: \d{4} or \d{6} or \d{8}
  • range: year or \d+[dmy]
  • datatype: what EPrints::Plugin::Stats::Processor have as their 'provides' param. Could use something like EPrints::Plugin::Stats::Handler->{processors_map}->{"$datatype"}
  • datafilter: values set in config, things like archive full_text open_access (or undef). Possibly not used as a request param
  • grouping: I think EPrints::Plugin::Stats::Sets::set_exists may be able to validate this value (which is also called by EPrints::Plugin::Stats::Context::has_valid_set).
  • cache: is this used?

NB ran out of time reviewing these - anyone else feel free to chip in, or I'll continue when I get a spare moment!

@rsdoiel
Copy link
Author

rsdoiel commented Jan 24, 2020

I'll figure out a simple patch, make a diff and attach it here (hopefully next week).

My current plan it to strip '<' and '>' in the linked loop example for processing the session variables. That'll solve the injection risk. Thank you everyone for the help.

All the best,

Robert

@mpbraendle
Copy link

In many cases we use https://metacpan.org/pod/CGI::IDS for securing CGI scripts . This library covers many more attack vectors than the one with '<' '>' and is worth having a look at it.

@rsdoiel
Copy link
Author

rsdoiel commented Jan 24, 2020

Will take a look, thanks Robert

@jesusbagpuss
Copy link
Contributor

@rsdoiel - just wondering if you got anywhere with this? I could take a look today at creating some validation methods.

@rsdoiel
Copy link
Author

rsdoiel commented Feb 4, 2020 via email

@jenswitzel
Copy link

Did anyone fix this? CGI::IDS does not "ring the bell"!

@rsdoiel
Copy link
Author

rsdoiel commented Jul 1, 2020

I don't think this has been solved, I know I haven't had a chance to pursue the suggested fixes. EPrints for us is in maintenance only mode. Caltech Library is not doing active development inside EPrints or with the EPrints plugin system. Our mid-range plans is to have a stats system that works across our mix of repository systems so ultimately I think IRStats will be replaced at Caltech Library. All the best, Robert

@jenswitzel
Copy link

Thanks. I fixed it with CGI::IDS, parsing the filter parameters.

@jenswitzel
Copy link

Here is a solution: https://github.com/eprintsug/IDS

@liamgh
Copy link

liamgh commented Jul 24, 2020

Did a bit of PHP inspired regex to solve this issue and came up with this:
In Context.pm at about line 92:

	# Then check URI parameters, priority over the rest
	foreach( $session->param() )
	{
		next if( !$FIELDSMAP{$_} ); 
		my $value = $session->param( "$_" );
		$value =~ s/[<>\/\\;=\&\?\%\'[:cntrl:]]//gm;
		$self->{$_} = $value;
	}

Not perfect but seems to filter out trouble makers.

@graingert
Copy link

@graingert
Copy link

graingert commented Aug 12, 2020

@liamgh ^

@jesusbagpuss
Copy link
Contributor

Possible fixes added to https://github.com/eprintsug/irstats2/tree/issue-17-xss

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

No branches or pull requests

6 participants