Forum Moderators: coopster

Message Too Old, No Replies

Security Considerations with User Input

Is striptags() enough?

         

Nick_W

8:17 am on Feb 26, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi all,

I'm messing around with a system where a user can insert CSS into the <head> of a 'test page'.

Is striptags() enough or is there anything else I need be mindfull of?

Many thanks

Nick

andreasfriedrich

11:55 am on Feb 26, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



How about a little CSS [w3.org] parser that checks the CSS [w3.org] to be valid as well. There is a user comment on the PHP [php.net] website that has a CSS [w3.org] parser. Add some code to check for valid properties and values and you are done ;). You can then even format the CSS [w3.org] quite nicely.

Checking the CSS [w3.org] code is simply a matter of having a look at the CSS2 grammar [w3.org] and then having a simple preg_match() [php.net] to check whether the properties and values contain anything else.

Andreas

Nick_W

12:04 pm on Feb 26, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for your thoughts Andreas.

I don't think I'd know how to create a parser, can you tell me where that user comment is?

Thanks

Nick

andreasfriedrich

12:55 pm on Feb 26, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It can be found at [php.net ]. Look for the comment by "michael at ettl". This is a rather simple parser that will not work that good with more complex selectors like body > div.class. This will be returned as
$aCSS["body>div.class"]["property"];
.

The basic idea is splitting the CSS [w3.org] code on }. This will give you an array of CSS [w3.org] statements. When you loop over these statements you would then have to decide whether a statement is a at-rule [w3.org] or a rule set [w3.org]. This would be done by deleting any leading whitespace off of each statement and then check for the at-keyword (@) immediately (i.e. no whitespace allowed) followed by an identifier [w3.org]. You could use preg_match("'^\s*@([A-Za-z0-9]¦[^\0-\177]¦\\[0-9a-f]{1,6}[ \n\r\t\f]?¦\\[ -~\200-\4177777])+'") for that.

When your statement is a rule set [w3.org] you would the split it on { to separate the selector [w3.org] from the declaration block. Then you would parse the selector [w3.org] by splitting the parts on whitespace. The declarations in the declaration block are separated by splitting on the semicolon. You would then loop over these declarations. Any such declaration may be either empty or consist of a property, some possible whitespace, followed by a colon (:), some possible whitespace, followed by a value. The property is an identifier [w3.org] so you already know how to check for those. Short of implementing a fully featured CSS [w3.org] parser there is little for you to do to check the values since each CSS2 [w3.org] property has its own syntactic and semantic restrictions on the values it accepts. So I´d just that is falls within this [a-z0-9-]¦{nonascii}¦{escape} range.

After that you are ready and done. And you will have implemented a much nicer parser than the one you will find on the PHP [php.net] site. Even if you just implement a subset of what I outlined above it will be a lot nicer.

HTH Andreas