validatorjs / validator.js Goto Github PK
View Code? Open in Web Editor NEWString validation
License: MIT License
String validation
License: MIT License
I would love to see some UUID validation like...
/^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}$/
.. or something ;-)
When running my custom 'validState' validation, the param 'str' comes out as undefined.
https://gist.github.com/2004334
Any idea?
This segment in validator-min.js breaks the sanitizing of "aaa<a>bbb</a>", producing "aaaundefined>bbb</a>" as a result.
(around line 23, column 6460):
b=b.replace(/<\w+.*?(?=>|<|$)/gi,function(a,b){}),
This code is not found on validator.js.
To test:
in a project including validator run:
var x=require('./node_modules/validator/validator-min.js')
x.sanitize('aaa<a>bbb</a>').xss()
Expected output:
'aaa<a>bbb</a>'
Actual output:
'aaaundefined>bbb</a>'
"in" is a reserved word in javascript. Wouldn't it be cleaner to rename the in()-method into something like inList() ?
I know this is a big chunk of functionality and would probably change the plumbing a lot, but it would be nice to see async validation in node-validator. What I mean is something like this:
// Validator that checks database records async
Validator.addAsync('userExists', function (value, message, callback) {
User.findOne({username: value, function(err, user) {
if (err || !user) {
callback(message, false); // invalid
} else {
callback(message, true);
}
});
}
// We use it like so:
Validator.check('[email protected]').userExists(); // And it should behave the same way as the other validators
Do you think something like this might be possible? It would enable me to get rid of so many nested callbacks... :)
The readme mentions in a browser to use validator-min.js. Just so we're clear this is exactly the same as validator.js just minified for convenience?
Are there any other dependencies for client-side usage?
I seem to get:
ReferenceError: str is not defined
http://localhost:6002/static/js/validator-min.js?q=1305296710
Line 23
I include that on a page, and in console test check('abc').isInt() etc..
I tried to look in test folder to see if any examples of client side usage but nothing
A string like:
sanitize("Bob&&Alice" ).xss();
gets a semicolon inserted and turns into "Bob&&Alice;".
It's just a string and not javascript. How do I prevent this? Thanks.
I'm applying xss sanitization to user input and I'm having problems with numeric entities:
> sanitize("Don"t").xss();
'Don"t'
> sanitize("Don't").xss();
'Don&#;39t'
Notice the second example producing an incorrect entity.
this pass the validator.sanitize('field').xss();
<img src="http://foo.bar.jpg">
Hi Chris,
had some trouble with the isDate() check. I had a look at the regex and it themes like it would expect something like MM/DD/YYYY but when the regex part is successful the next part fails .
Could you have a look at it and maybe include it in your test file.
Cheers,
Nico
The current documentation doesn't really address when xss() is appropriate. Having looked at the source code, it appears to be appropriate only when you intend to display the user's input to others without entity escaping. That makes sense if you're allowing users to edit things with a rich text editor, or encouraging the use of HTML tags, but it doesn't make sense if you're going to entity escape at output time.
For instance it would never make sense to use the xss() filter on a blog post title - those should just be entity escaped; if a user types a < or > there it is presumably meant to appear as such.
"Remove common XSS attack vectors from user-supplied HTML" would be a better description. It's worth mentioning that entity escaping is a better solution when it is not your goal to allow any HTML in the first place.
Thanks for an excellent validation library!
Looks like there's three problems:
Global leak with out
, should be var out = '';
Regexp replace uses $out
instead of out
.
Regexp is not valid, back references can't be used in character classes.
Perhaps it's intended to be /\s*[a-z\-]+\s*=\s*(\042|\047)(?:(?!\1).*?)\1/gi
.
However, that results in the following behavior:
> var s = require('./lib');
> s.sanitize("<a href=\"javascript:alert('xss')\">some text</a>").xss();
'<a \'xss\')">some text</a>'
The isUrl()
validator rejects URLs with hostnames that don't contain dots, like localhost
, for example:
http://localhost:8000/en-US/badges/badge/test-day-hero/awards/9.json
Here's a quick runthrough:
% git clone git://github.com/chriso/node-validator.git
Cloning into node-validator...
remote: Counting objects: 848, done.
remote: Compressing objects: 100% (311/311), done.
remote: Total 848 (delta 570), reused 805 (delta 534)
Receiving objects: 100% (848/848), 135.66 KiB, done.
Resolving deltas: 100% (570/570), done.
% cd node-validator
% node
> validator = require('validator')
{ entities: { encode: [Function], decode: [Function] },
xssClean: [Function],
Validator: [Function],
Filter: [Function],
convert: [Function],
sanitize: [Function],
assert: [Function],
validate: [Function],
check: [Function] }
> my_url = 'http://localhost:8000/en-US/badges/badge/test-day-hero/awards/9.json'
'http://localhost:8000/en-US/badges/badge/test-day-hero/awards/9.json'
> validator.check(my_url).isUrl()
Error: Invalid URL
at [object Object].error (/Users/lorchard/devel/mozilla/badger2/tmp/node-validator/validator.js:538:15)
at [object Object].isUrl (/Users/lorchard/devel/mozilla/badger2/tmp/node-validator/validator.js:559:25)
at repl:1:26
at REPLServer.eval (repl.js:80:21)
at Interface.<anonymous> (repl.js:182:12)
at Interface.emit (events.js:67:17)
at Interface._onLine (readline.js:162:10)
at Interface._line (readline.js:426:8)
at Interface._ttyWrite (readline.js:603:14)
at ReadStream.<anonymous> (readline.js:82:12)
>
Would you consider rewriting the 'for(var i in compact_words)' (line97) to a normal for loop (perhaps all array iterators)?
Or add an ".hasOwnProperty" check?
The current code crashes under Node.js in combination with several other modules that extend the Array object since your iterator will try to do a ".split" on the extended properties which happen to be functions.
This issue is a reference to express-validator/express-validator#5.
Can support be added for this?
I'd like to suggest a more callback oriented API, without constant reconstruction of a validator object whenever validation has to occur. Especially if you get a lot of requests, you do not want to create a new validator object each time:
var v = require('validator');
v.check('str', function() {
//str is not an integer
}).isInt();
This makes sure that no new validator object has to be instantiated on each request (if one needs specific error behavior for each request) and that no try catch logic is needed.
Would isBoolean() be a good validator?
Some fields only accepts true or false (checkboxes).
The .xss() method crashes with
URIError: URI malformed
at decodeURIComponent (native)
at Object.clean (.../node_modules/validator/lib/xss.js:67:11)
at [object Object].xss .../node_modules/validator/lib/filter.js:19:21)
when called on any string that contains '%'.
"npm install validator" will not work.
I'm using npm 0.3.18
node 0.4.7
hello chriso,
i like your library and have used it in some node projects. kudos to you
i am interested in using the rules of the validator directly without method chaining.
your current code attaches all functions directly to the prototype.
i would like it if the validation functions would be decoupled from the actual validator class.
this would make it possible to reuse them more easily.
if you are interested, i will fork and come back to you with a pull request
I had some funky issues with moving the code in the entities variable, such as ­ (the soft hyphen) disappearing (JSLint says this is an unsafe character and I can see why now), as well as a weird session with closure compiler converting the html escaped symbols and literal characters to \ufffd in one pass (possibly more ­ behavior), so I thought it was best all around to just use a native escape.
Also, I fixed nbsp with the proper escape code which was originally was using a space, not sure if that was intentional or not.
Here's a fixed up entities.
var entities = {
' ': '\u00a0',
'¡': '\u00a1',
'¢': '\u00a2',
'£': '\u00a3',
'¤': '\u20ac',
'¥': '\u00a5',
'¦': '\u0160',
'§': '\u00a7',
'¨': '\u0161',
'©': '\u00a9',
'ª': '\u00aa',
'«': '\u00ab',
'¬': '\u00ac',
'': '\u00ad',
'®': '\u00ae',
'¯': '\u00af',
'°': '\u00b0',
'±': '\u00b1',
'²': '\u00b2',
'³': '\u00b3',
'´': '\u017d',
'µ': '\u00b5',
'¶': '\u00b6',
'·': '\u00b7',
'¸': '\u017e',
'¹': '\u00b9',
'º': '\u00ba',
'»': '\u00bb',
'¼': '\u0152',
'½': '\u0153',
'¾': '\u0178',
'¿': '\u00bf',
'À': '\u00c0',
'Á': '\u00c1',
'Â': '\u00c2',
'Ã': '\u00c3',
'Ä': '\u00c4',
'Å': '\u00c5',
'Æ': '\u00c6',
'Ç': '\u00c7',
'È': '\u00c8',
'É': '\u00c9',
'Ê': '\u00ca',
'Ë': '\u00cb',
'Ì': '\u00cc',
'Í': '\u00cd',
'Î': '\u00ce',
'Ï': '\u00cf',
'Ð': '\u00d0',
'Ñ': '\u00d1',
'Ò': '\u00d2',
'Ó': '\u00d3',
'Ô': '\u00d4',
'Õ': '\u00d5',
'Ö': '\u00d6',
'×': '\u00d7',
'Ø': '\u00d8',
'Ù': '\u00d9',
'Ú': '\u00da',
'Û': '\u00db',
'Ü': '\u00dc',
'Ý': '\u00dd',
'Þ': '\u00de',
'ß': '\u00df',
'à': '\u00e0',
'á': '\u00e1',
'â': '\u00e2',
'ã': '\u00e3',
'ä': '\u00e4',
'å': '\u00e5',
'æ': '\u00e6',
'ç': '\u00e7',
'è': '\u00e8',
'é': '\u00e9',
'ê': '\u00ea',
'ë': '\u00eb',
'ì': '\u00ec',
'í': '\u00ed',
'î': '\u00ee',
'ï': '\u00ef',
'ð': '\u00f0',
'ñ': '\u00f1',
'ò': '\u00f2',
'ó': '\u00f3',
'ô': '\u00f4',
'õ': '\u00f5',
'ö': '\u00f6',
'÷': '\u00f7',
'ø': '\u00f8',
'ù': '\u00f9',
'ú': '\u00fa',
'û': '\u00fb',
'ü': '\u00fc',
'ý': '\u00fd',
'þ': '\u00fe',
'ÿ': '\u00ff',
'"': '\u0022',
'<': '\u003c',
'>': '\u003e',
''': '\u0027',
'−': '\u2212',
'ˆ': '\u02c6',
'˜': '\u02dc',
'Š': '\u0160',
'‹': '\u2039',
'Œ': '\u0152',
'‘': '\u2018',
'’': '\u2019',
'“': '\u201c',
'”': '\u201d',
'•': '\u2022',
'–': '\u2013',
'—': '\u2014',
'™': '\u2122',
'š': '\u0161',
'›': '\u203a',
'œ': '\u0153',
'Ÿ': '\u0178',
'ƒ': '\u0192',
'Α': '\u0391',
'Β': '\u0392',
'Γ': '\u0393',
'Δ': '\u0394',
'Ε': '\u0395',
'Ζ': '\u0396',
'Η': '\u0397',
'Θ': '\u0398',
'Ι': '\u0399',
'Κ': '\u039a',
'Λ': '\u039b',
'Μ': '\u039c',
'Ν': '\u039d',
'Ξ': '\u039e',
'Ο': '\u039f',
'Π': '\u03a0',
'Ρ': '\u03a1',
'Σ': '\u03a3',
'Τ': '\u03a4',
'Υ': '\u03a5',
'Φ': '\u03a6',
'Χ': '\u03a7',
'Ψ': '\u03a8',
'Ω': '\u03a9',
'α': '\u03b1',
'β': '\u03b2',
'γ': '\u03b3',
'δ': '\u03b4',
'ε': '\u03b5',
'ζ': '\u03b6',
'η': '\u03b7',
'θ': '\u03b8',
'ι': '\u03b9',
'κ': '\u03ba',
'λ': '\u03bb',
'μ': '\u03bc',
'ν': '\u03bd',
'ξ': '\u03be',
'ο': '\u03bf',
'π': '\u03c0',
'ρ': '\u03c1',
'ς': '\u03c2',
'σ': '\u03c3',
'τ': '\u03c4',
'υ': '\u03c5',
'φ': '\u03c6',
'χ': '\u03c7',
'ψ': '\u03c8',
'ω': '\u03c9',
'ϑ': '\u03d1',
'ϒ': '\u03d2',
'ϖ': '\u03d6',
' ': '\u2002',
' ': '\u2003',
' ': '\u2009',
'': '\u200c',
'': '\u200d',
'': '\u200e',
'': '\u200f',
'‚': '\u201a',
'„': '\u201e',
'†': '\u2020',
'‡': '\u2021',
'…': '\u2026',
'‰': '\u2030',
'′': '\u2032',
'″': '\u2033',
'‾': '\u203e',
'⁄': '\u2044',
'€': '\u20ac',
'ℑ': '\u2111',
'℘': '\u2118',
'ℜ': '\u211c',
'ℵ': '\u2135',
'←': '\u2190',
'↑': '\u2191',
'→': '\u2192',
'↓': '\u2193',
'↔': '\u2194',
'↵': '\u21b5',
'⇐': '\u21d0',
'⇑': '\u21d1',
'⇒': '\u21d2',
'⇓': '\u21d3',
'⇔': '\u21d4',
'∀': '\u2200',
'∂': '\u2202',
'∃': '\u2203',
'∅': '\u2205',
'∇': '\u2207',
'∈': '\u2208',
'∉': '\u2209',
'∋': '\u220b',
'∏': '\u220f',
'∑': '\u2211',
'∗': '\u2217',
'√': '\u221a',
'∝': '\u221d',
'∞': '\u221e',
'∠': '\u2220',
'∧': '\u2227',
'∨': '\u2228',
'∩': '\u2229',
'∪': '\u222a',
'∫': '\u222b',
'∴': '\u2234',
'∼': '\u223c',
'≅': '\u2245',
'≈': '\u2248',
'≠': '\u2260',
'≡': '\u2261',
'≤': '\u2264',
'≥': '\u2265',
'⊂': '\u2282',
'⊃': '\u2283',
'⊄': '\u2284',
'⊆': '\u2286',
'⊇': '\u2287',
'⊕': '\u2295',
'⊗': '\u2297',
'⊥': '\u22a5',
'⋅': '\u22c5',
'⌈': '\u2308',
'⌉': '\u2309',
'⌊': '\u230a',
'⌋': '\u230b',
'⟨': '\u2329',
'⟩': '\u232a',
'◊': '\u25ca',
'♠': '\u2660',
'♣': '\u2663',
'♥': '\u2665',
'♦': '\u2666'
};
Great work on this library, it's pretty sweet.
One thing I noticed though is that the text: I <3 this
Becomes: I undefined
When passed through .xss()
I tried looking, but couldn't find what was breaking it. If I find it, I'll submit a patch.
Does anyone else think that it would be handy to provide an easy way to override the default error messages?
eg,
the event handler does not get stripped out by xss()
although I could use entityEncode() as a workaround to prevent all HTML..
not sure if this is a bug or a documentation thing, I just assumed it should work.
v.check('1234').len(5)
"String is too large"
It should say "String is too small" instead.
I got the message "Invalid number" when I run this line.
require('validator').check(0).isInt()
Zero isn't int? Or I must input just string value?
It's ok when this line.
require('validator').check(100).isInt()
Hello,
I define some prototypes in a file (array and string), and when this file is required, I have the next error while I do "sanitize(a).xss();" :
has no method 'split'
at Object.clean (/home/mod/modygo/node_modules/validator/lib/xss.js:102:42)
at [object Object].xss (/home/mod/modygo/node_modules/validator/lib/filter.js:32:21)
at Object. (/home/mod/modygo/temp.js:21:21)
at Module._compile (module.js:411:26)
at Object..js (module.js:417:10)
at Module.load (module.js:343:31)
at Function._load (module.js:302:12)
at Array. (module.js:430:10)
at EventEmitter._tickCallback (node.js:126:26)
Can you please help me?
Thanks,
Philippe
Hi, I found a missing var in validators.js while I was writing test with mocha.
There is no pattern variable in arguments, so must be declared in the function.
at line 104
isuuid: function(str, version) {
++ var pattern = ''
if (version == 3 || version == 'v3') {
Regards.
I can see the fix for issue #32 in xss.js, but it doesn't appear to be included in the combined validator.js file - am I missing something?
Is it possible to use this library on the frontend in the future?
I've ran a test using a string of "false", whereas it matched the this.str =='false'
check.
Therefore it should have set the variable to false, (e.g. this.modify(false);
).
Instead, it set it to true.
I think it might be better for an empty string to pass tests such as "isAlpha", "isLowercase" etc, as you can add always add "notEmpty".
I noticed that you have this._errors = [];
in check(), but it appears to be unused unless you override the Validator.prototype.error()
handler to push to that array after an error.
Frankly, what's the point of throwing an error after every single check? In most cases you would want to run a batch of individual check()s and then do something with the errors.
Consider this:
var v = new Validator();
v.check(data.a, 'error message').notNull().len(6);
v.check(data.b, 'error message').notNull().is(/^[a-z]+$/);
v.check(data.c, 'error message').notNull().isEmail();
v.check(data.d, 'error message').notNull().isInt();
if(v.errors)
{
// handle accumulated errors
}
I think this format would allow Validator to be far more flexible.
If you don't want to change the API that much, maybe something like this?
var v = require('validator');
var check = v.check;
v.captureErrors(); // Errors will start accumulating to that error array. If this isn't called, each individual check() throws an error like normal
check(data.a, 'error message').notNull().len(6);
check(data.b, 'error message').notNull().is(/^[a-z]+$/);
check(data.c, 'error message').notNull().isEmail();
check(data.d, 'error message').notNull().isInt();
if(v.errors)
{
// handle accumulated errors
}
v.flushErrors(); // Helper method for clearing out the array error.
Let me know what you think of this. I can form a pull request with these changes if you'd like.
if credit card number have space, isCreditCard can't replace it....
i check the code ( validator.js line 299 ), there is line like this...
this.str.replace(/[^0-9]+/g, ''); //remove all dashes, spaces, etc.
but this line doesn't work...
See #39
Chriso, I found a bug in the isUrl validator, where it thinks that the following string is a valid URL:
"1." or "123." or "asd."
The bug is an (i think) extraneous question mark after the TLD group, unless this is intentional.
I just get here, and view the source code, great work, but just one question, why not put toDate
, toDateTime
in Filter?
According to the document, isUUID is correct.
validators.js: 104
-- isuuid: function(str, version)
++ isUUID: function(str, version)
Regards.
Hi, I`m doing something like this:
try {
var foo = sanitize('foo 55 bar').toInt();
console.log('After sanitize', foo); // NaN
check(foo).notEmpty(); // Not throwing an error
} catch(e) {
console.log(e);
}
check(foo).notEmpty() not throwing an error if foo = NaN. As "NaN" is mathematical error, i think check(foo).notEmpty() should throw an error.
I think it can be fixed like that:
Validator.prototype.notEmpty = function() {
if (!this.str) {
this.error(this.msg || 'String is empty');
}
if (this.str.match(/^[\s\t\r\n]*$/)) {
this.error(this.msg || 'String is whitespace');
}
return this;
}
Thanks.
I'll admit that I'm being rather picky here, but many computer users don't know what "strings" are. I'd really love to present the user with the node-validator default error message, but "String is too short" is not quite what I'd like to present to the user. "Value is too short" is a bit better.
All this computer jargon about strings and threads... people will think we are sewing, not programming.
I'd fork and submit a pull request, but it's such a small change. Thoughts?
It would be nice to provide a chain() and value() like functionality (similar to underscore.js)
where you would be able to do stuff like
someString = validator.sanitize(someString).chain().xss().entityEncode().value();
Perhaps outside the current scope but I feel like it could be helpful in certain cases.
Thanks.
It's be good if either the error messages were defined as variables on the Validator object or if perhaps they were able to be customised somehow.
Use case:
Trying to write tests that my models validate correctly, I need to validate against arbitrary strings that just happen to be spat out by the program, and will break if you ever update those error messages. I don't actually care about the content of the message, just that the right message has been thrown, but currently I'm forced to test against the content of the message.
Perhaps the last param of each check call could be a 'custom message' param.
Additionally, it'd make i18n easier.
I've been checking out your xss code and wonder if it is not too aggressive.
As far as I know, the only thing you need to do is:
<a href=javascript:alert(1)>XXX</a>
to normal htmlEg <script>
will become <script>
Thus, you do not have to remove<script>
or check for other html elements.. you simply html encode these.
You seem to be doing a lot more unneeded procedures. Am I wrong here in that there are more steps involved then the two listed above?
Thanks a lot for your hard work.
I assume that "" is empty, thus it should not pass notEmpty()
check('ad>[email protected]').isEmail() does not throw.
It would be consistent if the following methods were renamed to:
not() -> isNot()
notNull() -> isNotNull()
notEmpty() -> isNotEmpty()
notContains() -> doesNotContain()
reqex() -> isRegExp() // Follow Javascript convention
notRegex() -> isNotRegExp()
len() -> hasLength()
notIn() -> isNotIn()
max() -> isMax()
min() -> isMin()
len() -> hasLength() or hasLengthOf()
In this way it reads like english just like all the other methods.
I was going to implement this myself and make a pull request but I didn't know how to run the tests. How are they run and what testing library is it? (Mocha is a good one, simple to write, read and run. Good for collaboration)
I've created a custom error function to allow the all validations to run as a chain and collect the errors into an array (currently they short circuit on the first error).
Along the way I noticed that there's already an _errors array defined on the validator, but I don't see where it's used. Was the initial idea to collect all errors on the chain into the _errors array? Maybe I missed something.
This condition in Validator.prototype.check don't converts objects without length fild into empty strings:
this.str = (str == null || (isNaN(str) && str.length == undefined)) ? '' : str;
Is it really necessarry?
isNull
and notNull
are implemented in this way
notNull: function(str) {
return str !== '';
},
isNull: function(str) {
return str === '';
},
which checks if the string is empty and not if the object is null.
Wouldn't be
isNull: function(str) {
return str === null;
},
notNull: function(str) {
return !validators.isNull(str);
}
be more consistent with the validation name?
I saw this as a TODO
so I figured I'd post it as an issue.
https://github.com/chriso/node-validator/blob/master/lib/xss.js#L182
What were your plans for this?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.