eslint-plugin-jwt-security 2.3.1 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,93 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requireAudienceValidation = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- const utils_1 = require("../../utils");
6
- exports.requireAudienceValidation = (0, eslint_devkit_1.createRule)({
7
- name: 'require-audience-validation',
8
- meta: {
9
- type: 'problem',
10
- docs: {
11
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-audience-validation.md',
12
- description: 'Require audience (aud) claim validation in JWT verify operations',
13
- cwe: 'CWE-287',
14
- cvss: 9.8,
15
- },
16
- fixable: undefined,
17
- hasSuggestions: false,
18
- messages: {
19
- missingAudienceValidation: (0, eslint_devkit_1.formatLLMMessage)({
20
- icon: eslint_devkit_1.MessageIcons.SECURITY,
21
- issueName: 'Missing Audience Validation',
22
- cwe: 'CWE-287',
23
- description: 'JWT verification without audience validation accepts tokens intended for other services',
24
- severity: 'MEDIUM',
25
- fix: 'Add audience option: { audience: "https://api.example.com" }',
26
- documentationLink: 'https://tools.ietf.org/html/rfc8725',
27
- }),
28
- },
29
- schema: [
30
- {
31
- type: 'object',
32
- properties: {
33
- knownAudiences: {
34
- type: 'array',
35
- items: { type: 'string' },
36
- default: [],
37
- description: 'Known valid audiences to suggest',
38
- },
39
- trustedSanitizers: {
40
- type: 'array',
41
- items: { type: 'string' },
42
- default: [],
43
- },
44
- trustedAnnotations: {
45
- type: 'array',
46
- items: { type: 'string' },
47
- default: [],
48
- },
49
- strictMode: {
50
- type: 'boolean',
51
- default: false,
52
- },
53
- },
54
- additionalProperties: false,
55
- },
56
- ],
57
- },
58
- defaultOptions: [
59
- {
60
- knownAudiences: [],
61
- trustedSanitizers: [],
62
- trustedAnnotations: [],
63
- strictMode: false,
64
- },
65
- ],
66
- create(context) {
67
- return {
68
- CallExpression(node) {
69
- if (!(0, utils_1.isVerifyOperation)(node)) {
70
- return;
71
- }
72
- if (node.arguments.length < 2) {
73
- return;
74
- }
75
- const optionsArg = (0, utils_1.getOptionsArgument)(node, 2);
76
- if (!optionsArg) {
77
- context.report({
78
- node,
79
- messageId: 'missingAudienceValidation',
80
- });
81
- return;
82
- }
83
- if (!(0, utils_1.hasOption)(optionsArg, 'audience') && !(0, utils_1.hasOption)(optionsArg, 'aud')) {
84
- context.report({
85
- node: optionsArg,
86
- messageId: 'missingAudienceValidation',
87
- });
88
- }
89
- },
90
- };
91
- },
92
- });
93
- exports.default = exports.requireAudienceValidation;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireAudienceValidation=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");exports.requireAudienceValidation=(0,eslint_devkit_1.createRule)({name:"require-audience-validation",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-audience-validation.md",description:"Require audience (aud) claim validation in JWT verify operations",cwe:"CWE-287",cvss:9.8},fixable:void 0,hasSuggestions:false,messages:{missingAudienceValidation:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing Audience Validation",cwe:"CWE-287",description:"JWT verification without audience validation accepts tokens intended for other services",severity:"MEDIUM",fix:'Add audience option: { audience: "https://api.example.com" }',documentationLink:"https://tools.ietf.org/html/rfc8725"})},schema:[{type:"object",properties:{knownAudiences:{type:"array",items:{type:"string"},default:[],description:"Known valid audiences to suggest"},trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{knownAudiences:[],trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){return{CallExpression(node){if(!(0,utils_1.isVerifyOperation)(node)){return}if(node.arguments.length<2){return}const optionsArg=(0,utils_1.getOptionsArgument)(node,2);if(!optionsArg){context.report({node,messageId:"missingAudienceValidation"});return}if(!(0,utils_1.hasOption)(optionsArg,"audience")&&!(0,utils_1.hasOption)(optionsArg,"aud")){context.report({node:optionsArg,messageId:"missingAudienceValidation"})}}}}});exports.default=exports.requireAudienceValidation;
@@ -1,120 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requireExpiration = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- const utils_1 = require("../../utils");
6
- exports.requireExpiration = (0, eslint_devkit_1.createRule)({
7
- name: 'require-expiration',
8
- meta: {
9
- type: 'problem',
10
- docs: {
11
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-expiration.md',
12
- description: 'Require expiration claim (exp) or expiresIn option in JWT signing',
13
- cwe: 'CWE-613',
14
- cvss: 5.4,
15
- },
16
- hasSuggestions: true,
17
- messages: {
18
- missingExpiration: (0, eslint_devkit_1.formatLLMMessage)({
19
- icon: eslint_devkit_1.MessageIcons.SECURITY,
20
- issueName: 'Missing JWT Expiration',
21
- cwe: 'CWE-613',
22
- description: 'JWT without expiration is valid forever, increasing exposure window',
23
- severity: 'MEDIUM',
24
- fix: 'Add expiresIn: "1h" or exp claim to payload',
25
- documentationLink: 'https://tools.ietf.org/html/rfc8725',
26
- }),
27
- addExpiration: (0, eslint_devkit_1.formatLLMMessage)({
28
- icon: eslint_devkit_1.MessageIcons.INFO,
29
- issueName: 'Add Expiration',
30
- description: 'Add expiration to limit token lifetime',
31
- severity: 'LOW',
32
- fix: 'jwt.sign(payload, secret, { expiresIn: "1h" })',
33
- documentationLink: 'https://www.npmjs.com/package/jsonwebtoken',
34
- }),
35
- },
36
- schema: [
37
- {
38
- type: 'object',
39
- properties: {
40
- maxExpirationSeconds: {
41
- type: 'integer',
42
- default: 86400,
43
- description: 'Maximum allowed expiration time in seconds (24h default)',
44
- },
45
- trustedSanitizers: {
46
- type: 'array',
47
- items: { type: 'string' },
48
- default: [],
49
- },
50
- trustedAnnotations: {
51
- type: 'array',
52
- items: { type: 'string' },
53
- default: [],
54
- },
55
- strictMode: {
56
- type: 'boolean',
57
- default: false,
58
- },
59
- },
60
- additionalProperties: false,
61
- },
62
- ],
63
- },
64
- defaultOptions: [
65
- {
66
- maxExpirationSeconds: 86400,
67
- trustedSanitizers: [],
68
- trustedAnnotations: [],
69
- strictMode: false,
70
- },
71
- ],
72
- create(context) {
73
- const payloadHasExp = (payloadNode) => {
74
- if (payloadNode.type !== 'ObjectExpression') {
75
- return false;
76
- }
77
- return payloadNode.properties.some((prop) => prop.type === 'Property' &&
78
- prop.key.type === 'Identifier' &&
79
- prop.key.name === 'exp');
80
- };
81
- return {
82
- CallExpression(node) {
83
- if (!(0, utils_1.isSignOperation)(node)) {
84
- return;
85
- }
86
- if (node.arguments.length < 1) {
87
- return;
88
- }
89
- const payloadArg = node.arguments[0];
90
- const optionsArg = (0, utils_1.getOptionsArgument)(node, 2);
91
- if (payloadHasExp(payloadArg)) {
92
- return;
93
- }
94
- if (optionsArg && (0, utils_1.hasOption)(optionsArg, 'expiresIn')) {
95
- return;
96
- }
97
- const optionsArg3 = node.arguments[2];
98
- context.report({
99
- node,
100
- messageId: 'missingExpiration',
101
- suggest: [
102
- {
103
- messageId: 'addExpiration',
104
- fix(fixer) {
105
- const sourceCode = context.sourceCode;
106
- if (optionsArg3 && optionsArg3.type === eslint_devkit_1.AST_NODE_TYPES.ObjectExpression) {
107
- const openBrace = sourceCode.getFirstToken(optionsArg3);
108
- return fixer.insertTextAfter(openBrace, ' expiresIn: \'1h\',');
109
- }
110
- const lastArg = node.arguments[node.arguments.length - 1];
111
- return fixer.insertTextAfter(lastArg, ', { expiresIn: \'1h\' }');
112
- },
113
- },
114
- ],
115
- });
116
- },
117
- };
118
- },
119
- });
120
- exports.default = exports.requireExpiration;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireExpiration=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");exports.requireExpiration=(0,eslint_devkit_1.createRule)({name:"require-expiration",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-expiration.md",description:"Require expiration claim (exp) or expiresIn option in JWT signing",cwe:"CWE-613",cvss:5.4},hasSuggestions:true,messages:{missingExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing JWT Expiration",cwe:"CWE-613",description:"JWT without expiration is valid forever, increasing exposure window",severity:"MEDIUM",fix:'Add expiresIn: "1h" or exp claim to payload',documentationLink:"https://tools.ietf.org/html/rfc8725"}),addExpiration:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Expiration",description:"Add expiration to limit token lifetime",severity:"LOW",fix:'jwt.sign(payload, secret, { expiresIn: "1h" })',documentationLink:"https://www.npmjs.com/package/jsonwebtoken"})},schema:[{type:"object",properties:{maxExpirationSeconds:{type:"integer",default:86400,description:"Maximum allowed expiration time in seconds (24h default)"},trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{maxExpirationSeconds:86400,trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){const payloadHasExp=payloadNode=>{if(payloadNode.type!=="ObjectExpression"){return false}return payloadNode.properties.some(prop=>prop.type==="Property"&&prop.key.type==="Identifier"&&prop.key.name==="exp")};return{CallExpression(node){if(!(0,utils_1.isSignOperation)(node)){return}if(node.arguments.length<1){return}const payloadArg=node.arguments[0];const optionsArg=(0,utils_1.getOptionsArgument)(node,2);if(payloadHasExp(payloadArg)){return}if(optionsArg&&(0,utils_1.hasOption)(optionsArg,"expiresIn")){return}const optionsArg3=node.arguments[2];context.report({node,messageId:"missingExpiration",suggest:[{messageId:"addExpiration",fix(fixer){const sourceCode=context.sourceCode;if(optionsArg3&&optionsArg3.type===eslint_devkit_1.AST_NODE_TYPES.ObjectExpression){const openBrace=sourceCode.getFirstToken(optionsArg3);return fixer.insertTextAfter(openBrace," expiresIn: '1h',")}const lastArg=node.arguments[node.arguments.length-1];return fixer.insertTextAfter(lastArg,", { expiresIn: '1h' }")}}]})}}}});exports.default=exports.requireExpiration;
@@ -1,92 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requireIssuedAt = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- const utils_1 = require("../../utils");
6
- exports.requireIssuedAt = (0, eslint_devkit_1.createRule)({
7
- name: 'require-issued-at',
8
- meta: {
9
- type: 'problem',
10
- docs: {
11
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-issued-at.md',
12
- description: 'Require iat (issued at) claim for token freshness validation',
13
- cwe: 'CWE-294',
14
- cvss: 5,
15
- },
16
- fixable: undefined,
17
- hasSuggestions: false,
18
- messages: {
19
- missingIssuedAt: (0, eslint_devkit_1.formatLLMMessage)({
20
- icon: eslint_devkit_1.MessageIcons.SECURITY,
21
- issueName: 'Missing Issued At Claim',
22
- cwe: 'CWE-294',
23
- description: 'JWT without iat claim cannot be validated for freshness, enabling replay attacks',
24
- severity: 'MEDIUM',
25
- fix: 'Add iat claim to payload or use library option that adds it automatically',
26
- documentationLink: 'https://securitypattern.com/post/jwt-back-to-the-future',
27
- }),
28
- },
29
- schema: [
30
- {
31
- type: 'object',
32
- properties: {
33
- trustedSanitizers: {
34
- type: 'array',
35
- items: { type: 'string' },
36
- default: [],
37
- },
38
- trustedAnnotations: {
39
- type: 'array',
40
- items: { type: 'string' },
41
- default: [],
42
- },
43
- strictMode: {
44
- type: 'boolean',
45
- default: false,
46
- },
47
- },
48
- additionalProperties: false,
49
- },
50
- ],
51
- },
52
- defaultOptions: [
53
- {
54
- trustedSanitizers: [],
55
- trustedAnnotations: [],
56
- strictMode: false,
57
- },
58
- ],
59
- create(context) {
60
- const payloadHasIat = (payloadNode) => {
61
- if (payloadNode.type !== 'ObjectExpression') {
62
- return false;
63
- }
64
- return payloadNode.properties.some((prop) => prop.type === 'Property' &&
65
- prop.key.type === 'Identifier' &&
66
- prop.key.name === 'iat');
67
- };
68
- return {
69
- CallExpression(node) {
70
- if (!(0, utils_1.isSignOperation)(node)) {
71
- return;
72
- }
73
- if (node.arguments.length < 1) {
74
- return;
75
- }
76
- const payloadArg = node.arguments[0];
77
- const optionsArg = (0, utils_1.getOptionsArgument)(node, 2);
78
- if (payloadHasIat(payloadArg)) {
79
- return;
80
- }
81
- if (optionsArg && (0, utils_1.hasOption)(optionsArg, 'noTimestamp')) {
82
- context.report({
83
- node: optionsArg,
84
- messageId: 'missingIssuedAt',
85
- });
86
- return;
87
- }
88
- },
89
- };
90
- },
91
- });
92
- exports.default = exports.requireIssuedAt;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireIssuedAt=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");exports.requireIssuedAt=(0,eslint_devkit_1.createRule)({name:"require-issued-at",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-issued-at.md",description:"Require iat (issued at) claim for token freshness validation",cwe:"CWE-294",cvss:5},fixable:void 0,hasSuggestions:false,messages:{missingIssuedAt:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing Issued At Claim",cwe:"CWE-294",description:"JWT without iat claim cannot be validated for freshness, enabling replay attacks",severity:"MEDIUM",fix:"Add iat claim to payload or use library option that adds it automatically",documentationLink:"https://securitypattern.com/post/jwt-back-to-the-future"})},schema:[{type:"object",properties:{trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){const payloadHasIat=payloadNode=>{if(payloadNode.type!=="ObjectExpression"){return false}return payloadNode.properties.some(prop=>prop.type==="Property"&&prop.key.type==="Identifier"&&prop.key.name==="iat")};return{CallExpression(node){if(!(0,utils_1.isSignOperation)(node)){return}if(node.arguments.length<1){return}const payloadArg=node.arguments[0];const optionsArg=(0,utils_1.getOptionsArgument)(node,2);if(payloadHasIat(payloadArg)){return}if(optionsArg&&(0,utils_1.hasOption)(optionsArg,"noTimestamp")){context.report({node:optionsArg,messageId:"missingIssuedAt"});return}}}}});exports.default=exports.requireIssuedAt;
@@ -1,93 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requireIssuerValidation = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- const utils_1 = require("../../utils");
6
- exports.requireIssuerValidation = (0, eslint_devkit_1.createRule)({
7
- name: 'require-issuer-validation',
8
- meta: {
9
- type: 'problem',
10
- docs: {
11
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-issuer-validation.md',
12
- description: 'Require issuer (iss) claim validation in JWT verify operations',
13
- cwe: 'CWE-287',
14
- cvss: 9.8,
15
- },
16
- fixable: undefined,
17
- hasSuggestions: false,
18
- messages: {
19
- missingIssuerValidation: (0, eslint_devkit_1.formatLLMMessage)({
20
- icon: eslint_devkit_1.MessageIcons.SECURITY,
21
- issueName: 'Missing Issuer Validation',
22
- cwe: 'CWE-287',
23
- description: 'JWT verification without issuer validation accepts tokens from any source',
24
- severity: 'MEDIUM',
25
- fix: 'Add issuer option: { issuer: "https://auth.example.com" }',
26
- documentationLink: 'https://tools.ietf.org/html/rfc8725',
27
- }),
28
- },
29
- schema: [
30
- {
31
- type: 'object',
32
- properties: {
33
- knownIssuers: {
34
- type: 'array',
35
- items: { type: 'string' },
36
- default: [],
37
- description: 'Known valid issuers to suggest',
38
- },
39
- trustedSanitizers: {
40
- type: 'array',
41
- items: { type: 'string' },
42
- default: [],
43
- },
44
- trustedAnnotations: {
45
- type: 'array',
46
- items: { type: 'string' },
47
- default: [],
48
- },
49
- strictMode: {
50
- type: 'boolean',
51
- default: false,
52
- },
53
- },
54
- additionalProperties: false,
55
- },
56
- ],
57
- },
58
- defaultOptions: [
59
- {
60
- knownIssuers: [],
61
- trustedSanitizers: [],
62
- trustedAnnotations: [],
63
- strictMode: false,
64
- },
65
- ],
66
- create(context) {
67
- return {
68
- CallExpression(node) {
69
- if (!(0, utils_1.isVerifyOperation)(node)) {
70
- return;
71
- }
72
- if (node.arguments.length < 2) {
73
- return;
74
- }
75
- const optionsArg = (0, utils_1.getOptionsArgument)(node, 2);
76
- if (!optionsArg) {
77
- context.report({
78
- node,
79
- messageId: 'missingIssuerValidation',
80
- });
81
- return;
82
- }
83
- if (!(0, utils_1.hasOption)(optionsArg, 'issuer') && !(0, utils_1.hasOption)(optionsArg, 'iss')) {
84
- context.report({
85
- node: optionsArg,
86
- messageId: 'missingIssuerValidation',
87
- });
88
- }
89
- },
90
- };
91
- },
92
- });
93
- exports.default = exports.requireIssuerValidation;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireIssuerValidation=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");exports.requireIssuerValidation=(0,eslint_devkit_1.createRule)({name:"require-issuer-validation",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-issuer-validation.md",description:"Require issuer (iss) claim validation in JWT verify operations",cwe:"CWE-287",cvss:9.8},fixable:void 0,hasSuggestions:false,messages:{missingIssuerValidation:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing Issuer Validation",cwe:"CWE-287",description:"JWT verification without issuer validation accepts tokens from any source",severity:"MEDIUM",fix:'Add issuer option: { issuer: "https://auth.example.com" }',documentationLink:"https://tools.ietf.org/html/rfc8725"})},schema:[{type:"object",properties:{knownIssuers:{type:"array",items:{type:"string"},default:[],description:"Known valid issuers to suggest"},trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{knownIssuers:[],trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){return{CallExpression(node){if(!(0,utils_1.isVerifyOperation)(node)){return}if(node.arguments.length<2){return}const optionsArg=(0,utils_1.getOptionsArgument)(node,2);if(!optionsArg){context.report({node,messageId:"missingIssuerValidation"});return}if(!(0,utils_1.hasOption)(optionsArg,"issuer")&&!(0,utils_1.hasOption)(optionsArg,"iss")){context.report({node:optionsArg,messageId:"missingIssuerValidation"})}}}}});exports.default=exports.requireIssuerValidation;
@@ -1,86 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requireMaxAge = void 0;
4
- const eslint_devkit_1 = require("@interlace/eslint-devkit");
5
- const utils_1 = require("../../utils");
6
- exports.requireMaxAge = (0, eslint_devkit_1.createRule)({
7
- name: 'require-max-age',
8
- meta: {
9
- type: 'problem',
10
- docs: {
11
- url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-max-age.md',
12
- description: 'Require maxAge option in verify operations to enforce token freshness',
13
- cwe: 'CWE-294',
14
- cvss: 5,
15
- },
16
- fixable: undefined,
17
- hasSuggestions: false,
18
- messages: {
19
- missingMaxAge: (0, eslint_devkit_1.formatLLMMessage)({
20
- icon: eslint_devkit_1.MessageIcons.SECURITY,
21
- issueName: 'Missing Token Age Validation',
22
- cwe: 'CWE-294',
23
- description: 'Without maxAge, tokens can be replayed long after issuance (Back to the Future attack)',
24
- severity: 'MEDIUM',
25
- fix: 'Add maxAge option: { maxAge: "1h" } to limit token lifetime',
26
- documentationLink: 'https://securitypattern.com/post/jwt-back-to-the-future',
27
- }),
28
- },
29
- schema: [
30
- {
31
- type: 'object',
32
- properties: {
33
- trustedSanitizers: {
34
- type: 'array',
35
- items: { type: 'string' },
36
- default: [],
37
- },
38
- trustedAnnotations: {
39
- type: 'array',
40
- items: { type: 'string' },
41
- default: [],
42
- },
43
- strictMode: {
44
- type: 'boolean',
45
- default: false,
46
- },
47
- },
48
- additionalProperties: false,
49
- },
50
- ],
51
- },
52
- defaultOptions: [
53
- {
54
- trustedSanitizers: [],
55
- trustedAnnotations: [],
56
- strictMode: false,
57
- },
58
- ],
59
- create(context) {
60
- return {
61
- CallExpression(node) {
62
- if (!(0, utils_1.isVerifyOperation)(node)) {
63
- return;
64
- }
65
- if (node.arguments.length < 2) {
66
- return;
67
- }
68
- const optionsArg = (0, utils_1.getOptionsArgument)(node, 2);
69
- if (!optionsArg) {
70
- context.report({
71
- node,
72
- messageId: 'missingMaxAge',
73
- });
74
- return;
75
- }
76
- if (!(0, utils_1.hasOption)(optionsArg, 'maxAge') && !(0, utils_1.hasOption)(optionsArg, 'clockTolerance')) {
77
- context.report({
78
- node: optionsArg,
79
- messageId: 'missingMaxAge',
80
- });
81
- }
82
- },
83
- };
84
- },
85
- });
86
- exports.default = exports.requireMaxAge;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.requireMaxAge=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const utils_1=require("../../utils");exports.requireMaxAge=(0,eslint_devkit_1.createRule)({name:"require-max-age",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-jwt-security/docs/rules/require-max-age.md",description:"Require maxAge option in verify operations to enforce token freshness",cwe:"CWE-294",cvss:5},fixable:void 0,hasSuggestions:false,messages:{missingMaxAge:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.SECURITY,issueName:"Missing Token Age Validation",cwe:"CWE-294",description:"Without maxAge, tokens can be replayed long after issuance (Back to the Future attack)",severity:"MEDIUM",fix:'Add maxAge option: { maxAge: "1h" } to limit token lifetime',documentationLink:"https://securitypattern.com/post/jwt-back-to-the-future"})},schema:[{type:"object",properties:{trustedSanitizers:{type:"array",items:{type:"string"},default:[]},trustedAnnotations:{type:"array",items:{type:"string"},default:[]},strictMode:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{trustedSanitizers:[],trustedAnnotations:[],strictMode:false}],create(context){return{CallExpression(node){if(!(0,utils_1.isVerifyOperation)(node)){return}if(node.arguments.length<2){return}const optionsArg=(0,utils_1.getOptionsArgument)(node,2);if(!optionsArg){context.report({node,messageId:"missingMaxAge"});return}if(!(0,utils_1.hasOption)(optionsArg,"maxAge")&&!(0,utils_1.hasOption)(optionsArg,"clockTolerance")){context.report({node:optionsArg,messageId:"missingMaxAge"})}}}}});exports.default=exports.requireMaxAge;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});