a53b9958fa734f73aeffb9ddfe2fbad1ca65f90c galt Mon Jan 30 16:18:41 2017 -0800 Check-in of CSP2 Content-Security-Policy work. All C-language CGIs should now support CSP2 in browser to stop major forms of XSS javascript injection. Javascript on pages is gathered together, and then emitted in a single script block at the end with a nonce that tells the browser, this is js that we generated instead of being injected by a hacker. Both inline script from script blocks and inline js event handlers had to be pulled out and separated. You will not see js sprinkled through-out the page now. Older browsers that support CSP1 or that do not understand CSP at all will still work, just without protection. External js libraries loaded at runtime need to be added to the CSP policy header in src/lib/htmshell.c. diff --git src/inc/cheapcgi.h src/inc/cheapcgi.h index b5a459f..1688d91 100644 --- src/inc/cheapcgi.h +++ src/inc/cheapcgi.h @@ -1,30 +1,47 @@ /* cheapcgi.h - turns variables passed from the web form into * something that C understands. * * This file is copyright 2000 Jim Kent, but license is hereby * granted for all use - public, private or commercial. */ #ifndef CHEAPCGI_H #define CHEAPCGI_H #include "dystring.h" #ifndef HASH_H #include "hash.h" #endif + +//============ javascript inline-separation routines =============== + +void jsInlineFinish(); +/* finish outputting accumulated inline javascript */ + +void jsInline(char *javascript); +/* Add text to output file or memory structure */ + +void jsOnEventById(char *event, char *idText, char *jsText); +/* Add js mapping for inline event */ + +void jsInlineReset(); +/* used by genomeSpace to repeatedly output multiple pages to stdout */ + +//============ END of javascript inline-separation routines =============== + #define COLOR_BG_DEFAULT "#FFFEE8" #define COLOR_BG_ALTDEFAULT "#FFF9D2" #define COLOR_BG_DEFAULT_DARKER "#FCECC0" #define COLOR_BG_DEFAULT_DARKEST "#EED5B7" #define COLOR_BG_GHOST "#EEEEEE" #define COLOR_BG_PALE "#F8F8F8" #define COLOR_BG_HEADER_LTBLUE "#D9E4F8" #define COLOR_DARKGREEN "#008800" #define COLOR_LTGREEN "#CCFFCC" #define COLOR_DARKBLUE "#000088" #define COLOR_BLUE_BUTTON "#91B3E6" #define COLOR_DARKGREY "#666666" #define COLOR_LTGREY "#CCCCCC" #define COLOR_YELLOW "#FFFF00" #define COLOR_LTYELLOW "#FFF380" @@ -231,93 +248,96 @@ * %hexVal. */ void cgiEncodeHash(struct hash *hash, struct dyString *dy); /* Put a cgi-encoding of a string valued hash into dy. Tags are always * alphabetical to make it easier to compare if two hashes are same. */ void cgiMakeButtonWithMsg(char *name, char *value, char *msg); /* Make 'submit' type button. Display msg on mouseover, if present*/ void cgiMakeButtonWithOnClick(char *name, char *value, char *msg, char *onClick); /* Make 'submit' type button, with onclick javascript */ void cgiMakeButton(char *name, char *value); /* Make 'submit' type button. */ -void cgiMakeOnClickButton(char *command, char *value); +void cgiMakeOnClickButton(char *id, char *command, char *value); /* Make 'push' type button with client side onClick (java)script. */ void cgiMakeOnClickSubmitButton(char *command, char *name, char *value); /* Make submit button with both variable name and value with client side * onClick (java)script. */ void cgiMakeOptionalButton(char *name, char *value, boolean disabled); /* Make 'submit' type button that can be disabled. */ void cgiMakeRadioButton(char *name, char *value, boolean checked); /* Make radio type button. A group of radio buttons should have the * same name but different values. The default selection should be * sent with checked on. */ -void cgiMakeOnClickRadioButton(char *name, char *value, boolean checked, - char *command); -/* Make radio type button with onClick command. +void cgiMakeOnEventRadioButtonWithClass(char *name, char *value, boolean checked, + char *class, char *event, char *command); +/* Make radio type button with an event and an optional class attribute. * A group of radio buttons should have the * same name but different values. The default selection should be - * sent with checked on. */ + * sent with checked on. If class is non-null it is included. */ void cgiMakeCheckBoxUtil(char *name, boolean checked, char *msg, char *id); /* Make check box - can be called directly, though it was originally meant * as the common code for all lower level checkbox routines. * However, it's util functionality has been taken over by * cgiMakeCheckBoxWithIdAndOptionalHtml() */ void cgiMakeCheckBox(char *name, boolean checked); /* Make check box. */ void cgiMakeCheckBoxWithMsg(char *name, boolean checked, char *msg); /* Make check box, which includes a msg. */ void cgiMakeCheckBoxWithId(char *name, boolean checked, char *id); /* Make check box, which includes an ID. */ void cgiMakeCheckBoxJS(char *name, boolean checked, char *javascript); /* Make check box with javascript */ void cgiMakeCheckBoxEnabled(char *name, boolean checked, boolean enabled); /* Make check box, optionally enabled/disabled. */ void cgiMakeCheckBoxIdAndJS(char *name, boolean checked, char *id, char *javascript); /* Make check box with ID and javascript. */ +void cgiMakeCheckBoxIdAndMore(char *name, boolean checked, char *id, char *moreHtml); +/* Make check box with ID and extra (non-javascript) html. */ + void cgiMakeCheckBoxFourWay(char *name, boolean checked, boolean enabled, char *id, char *classes, char *moreHtml); /* Make check box - with fourWay functionality (checked/unchecked by enabled/disabled * Also makes a shadow hidden variable that supports the 2 boolean states. */ void cgiMakeTextArea(char *varName, char *initialVal, int rowCount, int columnCount); /* Make a text area with area rowCount X columnCount and with text: intialVal. */ void cgiMakeTextAreaDisableable(char *varName, char *initialVal, int rowCount, int columnCount, boolean disabled); /* Make a text area that can be disabled. The rea has rowCount X * columnCount and with text: intialVal */ void cgiMakeTextVar(char *varName, char *initialVal, int charSize); /* Make a text control filled with initial value. If charSize * is zero it's calculated from initialVal size. */ -void cgiMakeTextVarWithExtraHtml(char *varName, char *initialVal, int width, char *extra); +void cgiMakeTextVarWithExtraHtml(char *varName, char *initialVal, int width, char *event, char *javascript); /* Make a text control filled with initial value. */ void cgiMakeOnKeypressTextVar(char *varName, char *initialVal, int charSize, char *script); /* Make a text control filled with initial value, with a (java)script * to execute every time a key is pressed. If charSize is zero it's * calculated from initialVal size. */ void cgiMakeIntVarWithExtra(char *varName, int initialVal, int maxDigits, char *extra); /* Make a text control filled with initial value and optional extra HTML. */ void cgiMakeIntVar(char *varName, int initialVal, int maxDigits); /* Make a text control filled with initial integer value. */ #define NO_VALUE -96669 @@ -347,66 +367,72 @@ void cgiMakeDoubleVarWithMin(char *varName, double initialVal, char *title, int width, double min); void cgiMakeDoubleVarWithMax(char *varName, double initialVal, char *title, int width, double max); #define cgiMakeDoubleVarNoLimits(varName,initialVal,title,width) \ cgiMakeDoubleVarInRange(varName,initialVal,title,width,NULL,NULL) /* All four of these call cgiMakeDoubleVarInRange() and therefore require utils.js */ void cgiMakeDropListClass(char *name, char *menu[], int menuSize, char *checked, char *class); /* Make a drop-down list with names and style sheet class. */ void cgiMakeDropList(char *name, char *menu[], int menuSize, char *checked); /* Make a drop-down list with names. * uses style "normalText" */ void cgiMakeDropListClassWithStyleAndJavascript(char *name, char *menu[], int menuSize, char *checked, char *class, - char *style,char *javascript); + char *style, struct slPair *events); /* Make a drop-down list with names, text class, style and javascript. */ void cgiMakeDropListClassWithStyle(char *name, char *menu[], int menuSize, char *checked, char *class, char *style); /* Make a drop-down list with names, text class and style. */ void cgiMakeDropListWithVals(char *name, char *menu[], char *values[], int menuSize, char *checked); /* Make a drop-down list with names and values. In this case checked * corresponds to a value, not a menu. */ -void cgiMakeDropListFull(char *name, char *menu[], char *values[], int menuSize, char *checked, char *extraAttribs); +void cgiMakeDropListFullExt(char *name, char *menu[], char *values[], + int menuSize, char *checked, char *event, char *javascript, char *style, char *class); +/* Make a drop-down list with names and values. + * Optionally include values for style and class */ + +void cgiMakeDropListFull(char *name, char *menu[], char *values[], + int menuSize, char *checked, char *event, char *javascript); /* Make a drop-down list with names and values. */ void cgiDropDownWithTextValsAndExtra(char *name, char *text[], char *values[], int count, char *selected, char *extra); /* Make a drop-down list with both text and values. */ char *cgiMakeSelectDropList(boolean multiple, char *name, struct slPair *valsAndLabels, - char *selected, char *anyAll,char *extraClasses, char *extraHtml); + char *selected, char *anyAll,char *extraClasses, char *event, char *javascript, char *style, char *id); // Returns allocated string of HTML defining a drop-down select // (if multiple, REQUIRES ui-dropdownchecklist.js) // valsAndLabels: val (pair->name) must be filled in but label (pair->val) may be NULL. // selected: if not NULL is a val found in the valsAndLabels (multiple then comma delimited list). // If null and anyAll not NULL, that will be selected // anyAll: if not NULL is the string for an initial option. It can contain val and label, // delimited by a comma -// extraHtml: if not NULL contains id, javascript calls and style. -// It does NOT contain class definitions -#define cgiMakeMultiSelectDropList(name,valsAndLabels,selected,anyAll,extraClasses,extraHtml) \ +// event: click, etc. +// javacript: what to execute when the event happens. +#define cgiMakeMultiSelectDropList(name,valsAndLabels,selected,anyAll,extraClasses,event,javascript,style,id) \ cgiMakeSelectDropList(TRUE,(name),(valsAndLabels),(selected),(anyAll),\ - (extraClasses),(extraHtml)) -#define cgiMakeSingleSelectDropList(name,valsAndLabels,selected,anyAll,extraClasses,extraHtml) \ + (extraClasses),(event),(javascript),(style),(id)) +#define cgiMakeSingleSelectDropList(name,valsAndLabels,selected,anyAll,extraClasses,event,javascript,style,id) \ cgiMakeSelectDropList(FALSE,(name),(valsAndLabels),(selected),(anyAll),\ - (extraClasses),(extraHtml)) + (extraClasses),(event),(javascript),(style),(id)) void cgiMakeMultList(char *name, char *menu[], int menuSize, struct slName *checked, int length); /* Make a list of names which can have multiple selections. * Same as drop-down list except "multiple" is added to select tag */ void cgiMakeCheckboxGroup(char *name, char *menu[], int menuSize, struct slName *checked, int tableColumns); /* Make a table of checkboxes that have the same variable name but different * values (same behavior as a multi-select input). */ void cgiMakeCheckboxGroupWithVals(char *name, char *menu[], char *values[], int menuSize, struct slName *checked, int tableColumns); /* Make a table of checkboxes that have the same variable name but different * values (same behavior as a multi-select input), with nice labels in menu[]. */