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

Fixed XSS vulnerability in week 3 #27

Merged
merged 1 commit into from
Apr 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ config.js
node_modules/
aclImdb/
testdb/
.idea/
74 changes: 45 additions & 29 deletions week3-apis-data/09_google_sheets/sketch.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,51 @@
// [ { label: apple, number: 9 }, { label: pear, number: 4 }, { label: orange, number: 3 } ]

function setup() {
// This is the URL for my google sheet
// The sheet is generated from this form: http://goo.gl/forms/0X67GZJTZJ
// The sheet must set to File --> Published for the Web
var url = 'https://docs.google.com/spreadsheets/d/1YQ7js53a5Gdidi3XS5HxkDvHWgmAS1kCCi9NnmH7Uc0/pubhtml';

// Tabletop expects some settings
var settings = {
key: url, // The url of the published google sheet
callback: gotData, // A callback for when the data comes in
simpleSheet: true // This makes things simpler for just a single worksheet of rows
}

// Make the request
Tabletop.init(settings);

// The data comes back as an array of objects
// Each object contains all the data for one row of the sheet
// See comment above
function gotData(data) {
// Look at the data in the console
console.log(data);

// Make an HTML list
var list = createElement('ol');
list.parent('data');
for (var i = 0; i < data.length; i++) {
var item = createElement('li', data[i].label + ': ' + data[i].Number + ", submited at " + data[i].Timestamp);
item.parent(list);
// This is the URL for my google sheet
// The sheet is generated from this form: http://goo.gl/forms/0X67GZJTZJ
// The sheet must set to File --> Published for the Web
var url = 'https://docs.google.com/spreadsheets/d/1YQ7js53a5Gdidi3XS5HxkDvHWgmAS1kCCi9NnmH7Uc0/pubhtml';

// Tabletop expects some settings
var settings = {
key: url, // The url of the published google sheet
callback: gotData, // A callback for when the data comes in
simpleSheet: true // This makes things simpler for just a single worksheet of rows
};

// Make the request
Tabletop.init(settings);

// The data comes back as an array of objects
// Each object contains all the data for one row of the sheet
// See comment above
function gotData(data) {
// Look at the data in the console
console.log(data);

// Make an HTML list
var list = createElement('ol');
list.parent('data');
for (var i = 0; i < data.length; i++) {

var label = data[i].label;
var number = data[i].Number;
var timestamp = data[i].Timestamp;

// Sanitize user input with RegEx:
// - Stop users from injecting malicious Javascript into the page via the values spreadsheet
// - Check if values are indeed what the say to be.
// What prevents a user from putting letters into the Numbers column? Nothing...
if (
/^[a-zA-Z0-9 ]*$/.test(label) // Check if label is indeed a label (only letters, numbers and spaces)
&& /^[0-9,.]*$/.test(number) // Check if number consists of only digits, dots and commas
&& /^((\d{1,2}\/){2}\d{4} \d{1,2}(:\d{2}){2})?$/.test(timestamp) // MM/DD/YYYY hh:mm:ss
) {
// Input passed all tests, add it to the page
var item = createElement('li', label + ': ' + number + ", submited at " + timestamp);
item.parent(list);
}
}
}
}
}

102 changes: 56 additions & 46 deletions week3-apis-data/10_google_sheets_madlibs/sketch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,68 +4,78 @@


function setup() {
noCanvas();
noCanvas();

// This is the URL for my google sheet
// The sheet is generated from this form: http://goo.gl/forms/0X67GZJTZJ
// The sheet must set to File --> Published for the Web
var url = 'https://docs.google.com/spreadsheets/d/1PCuj_nEiwfbd_5pm9aWLWjbRs2mP6v8C45BbWl6WTn0/pubhtml';
// This is the URL for my google sheet
// The sheet is generated from this form: http://goo.gl/forms/0X67GZJTZJ
// The sheet must set to File --> Published for the Web
var url = 'https://docs.google.com/spreadsheets/d/1PCuj_nEiwfbd_5pm9aWLWjbRs2mP6v8C45BbWl6WTn0/pubhtml';


// Make the request
// Make the request

var button = select('#generate');
button.mousePressed(madlibber);
var button = select('#generate');
button.mousePressed(madlibber);

function madlibber() {
function madlibber() {

// I'm forming my own special syntax for how to substitute
// this will help the regex and replace function
var txt = '"$Exclamation$!" she said $Adverb$ as she jumped into her convertible $Noun$ '
+ 'and drove off with her $Adjective$ $Noun$.';
// I'm forming my own special syntax for how to substitute
// this will help the regex and replace function
var txt = '"$Exclamation$!" she said $Adverb$ as she jumped into her convertible $Noun$ '
+ 'and drove off with her $Adjective$ $Noun$.';

// Tabletop expects some settings
var settings = {
key: url, // The url of the published google sheet
callback: gotData, // A callback for when the data comes in
simpleSheet: true // This makes things simpler for just a single worksheet of rows
}
// Tabletop expects some settings
var settings = {
key: url, // The url of the published google sheet
callback: gotData, // A callback for when the data comes in
simpleSheet: true // This makes things simpler for just a single worksheet of rows
};

// Get the data
Tabletop.init(settings);
// Get the data
Tabletop.init(settings);

// The data comes back as an array of objects
// Each object contains all the data for one row of the sheet
// See comment above
function gotData(data) {
// The data comes back as an array of objects
// Each object contains all the data for one row of the sheet
// See comment above
function gotData(data) {

// Run the replace function with a callback
var madlib = txt.replace(/\$(.*?)\$/g, replacer);
// Run the replace function with a callback
var madlib = txt.replace(/\$(.*?)\$/g, replacer);


// This function replaces words
function replacer(match, what) {
// Pick a random entry
var i = floor(random(data.length));
// This function replaces words
function replacer(match, what) {
// Pick a random entry
var i = floor(random(data.length));

// Now get the
var newtext = data[i][what];
// Now get the
var newtext = data[i][what];

if (what === 'Exclamation') {
newtext = newtext.replace(/^(.)/, capitalize);
function capitalize(match, firstLetter) {
return firstLetter.toUpperCase();
}
}
// Check for malicious Javascript code inserted via the spreadsheet
// Users are only allowed to input a mix of letters, digits, spaces and standard punctuation
if (!/^[a-zA-Z0-9,.!? ]*$/.test(newtext)) {

return newtext;
}
var par = createP(madlib);
par.parent('madlib');
par.class('text');
}
// User input doesn't match our criteria
// Call this function recursively to get a different replacement text
return replacer(match, what);
}

if (what === 'Exclamation') {
newtext = newtext.replace(/^(.)/, capitalize);
function capitalize(match, firstLetter) {
return firstLetter.toUpperCase();
}
}

return newtext;
}

}
var par = createP(madlib);
par.parent('madlib');
par.class('text');
}


}
}