spice-js 2.6.7 → 2.6.8

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.
@@ -16,7 +16,11 @@ function _connect() {
16
16
 
17
17
  for (var key of Object.keys(spice.config.cache.providers)) {
18
18
  spice.cache_providers[key] = new spice.config.cache.providers[key](spice.config.cache.drivers[key] || {});
19
- spice.cache_providers[key].initialize();
19
+ spice.cache_providers[key].initialize().then(() => {
20
+ console.log("Redis initialized successfully");
21
+ }).catch(err => {
22
+ console.error("Error initializing Redis:", err);
23
+ });
20
24
  }
21
25
  } catch (e) {
22
26
  console.log(e.stack);
@@ -7,6 +7,8 @@ var _2 = require("..");
7
7
 
8
8
  var _ResourceLifecycleTriggered = _interopRequireDefault(require("../events/events/ResourceLifecycleTriggered"));
9
9
 
10
+ var _Security = require("../utility/Security");
11
+
10
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
13
 
12
14
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
@@ -495,11 +497,13 @@ class SpiceModel {
495
497
  setMonitor() {
496
498
  var current_time = new Date().getTime();
497
499
  var obj = this.getCacheProviderObject();
498
- obj.set("monitor::" + this.type, {
500
+ var key = "monitor::" + this.type;
501
+ var value = {
499
502
  time: current_time
500
- }, {
503
+ };
504
+ obj.set(key, value, {
501
505
  ttl: 0
502
- }); //console.log("Monitor Set", spice.monitor);
506
+ });
503
507
  }
504
508
 
505
509
  get(args) {
@@ -512,7 +516,10 @@ class SpiceModel {
512
516
  }
513
517
 
514
518
  if (_.isString(args.id)) {
515
- yield _this4.run_hook(args, "get", "before");
519
+ if (args.skip_hooks != true) {
520
+ yield _this4.run_hook(args, "get", "before");
521
+ }
522
+
516
523
  var key = _this4.type + "::" + args.id;
517
524
  var results = {};
518
525
 
@@ -540,8 +547,14 @@ class SpiceModel {
540
547
  }
541
548
 
542
549
  if (results.deleted == undefined || results.deleted == false) {
543
- yield _this4.run_hook(results, "get", "after");
544
- results = yield _this4.do_serialize(results, "read", {}, args, (yield _this4.propsToBeRemoved(results)));
550
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
551
+ results = yield _this4.do_serialize(results, "read", {}, args, (yield _this4.propsToBeRemoved(results)));
552
+ }
553
+
554
+ if (args.skip_hooks != true) {
555
+ yield _this4.run_hook(results, "get", "after");
556
+ }
557
+
545
558
  return results;
546
559
  } else {
547
560
  throw new Error(_this4.type + " does not exist");
@@ -575,7 +588,9 @@ class SpiceModel {
575
588
  args = {};
576
589
  }
577
590
 
578
- yield _this6.run_hook(_this6, "list", "before");
591
+ if (args.skip_hooks != true) {
592
+ yield _this6.run_hook(_this6, "list", "before");
593
+ }
579
594
 
580
595
  _.remove(args.ids, o => o == undefined);
581
596
 
@@ -603,8 +618,14 @@ class SpiceModel {
603
618
 
604
619
  _.remove(results, o => o.type != _this6.type);
605
620
 
606
- yield _this6.run_hook(results, "list", "after", args.context);
607
- results = yield _this6.do_serialize(results, "read", {}, args, (yield _this6.propsToBeRemoved(results)));
621
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
622
+ results = yield _this6.do_serialize(results, "read", {}, args, (yield _this6.propsToBeRemoved(results)));
623
+ }
624
+
625
+ if (args.skip_hooks != true) {
626
+ yield _this6.run_hook(results, "list", "after", args.context);
627
+ }
628
+
608
629
  return results;
609
630
  } catch (e) {
610
631
  console.log(e.stack);
@@ -664,34 +685,33 @@ class SpiceModel {
664
685
  new: _this8,
665
686
  id: args.id
666
687
  };
667
-
668
- if (args.skip_hooks != true) {
669
- yield _this8.run_hook(cover_obj, "update", "before", results);
670
- }
671
-
672
688
  var form;
673
689
 
674
690
  if (args.skip_write_serialize != true && args.skip_serialize != true) {
675
- form = yield _this8.do_serialize(_this8, "write", cover_obj.new, args);
691
+ cover_obj.new = yield _this8.do_serialize(_this8, "write", cover_obj.new, args);
676
692
  }
677
693
 
678
- var db_data = form || _this8;
694
+ if (args.skip_hooks != true) {
695
+ yield _this8.run_hook(cover_obj, "update", "before", results);
696
+ }
697
+
698
+ var db_data = cover_obj.new || _this8;
679
699
  yield _this8.database.update(args.id, db_data);
680
700
 
681
701
  _this8.setMonitor();
682
702
 
703
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
704
+ cover_obj.new = yield _this8.do_serialize(cover_obj.new, "read", {}, args, (yield _this8.propsToBeRemoved(cover_obj.new)));
705
+ }
706
+
683
707
  if (args.skip_hooks != true) {
684
708
  yield _this8.run_hook(_extends({}, _this8, {
685
709
  id: args.id
686
710
  }), "update", "after", results);
687
711
  }
688
712
 
689
- if (args.skip_read_serialize != true && args.skip_serialize != true) {
690
- form = yield _this8.do_serialize(form, "read", {}, args, (yield _this8.propsToBeRemoved(form)));
691
- }
692
-
693
713
  _this8.id = args.id;
694
- return _extends({}, form, {
714
+ return _extends({}, cover_obj.new, {
695
715
  id: args.id
696
716
  });
697
717
  } catch (e) {
@@ -724,16 +744,28 @@ class SpiceModel {
724
744
  id = args.id;
725
745
  }
726
746
 
727
- yield _this9.run_hook(workingForm, "create", "before");
728
- workingForm = yield _this9.do_serialize(workingForm, "write", {}, args);
747
+ if (args.skip_write_serialize != true && args.skip_serialize != true) {
748
+ workingForm = yield _this9.do_serialize(workingForm, "write", {}, args);
749
+ }
750
+
751
+ if (args.skip_hooks != true) {
752
+ yield _this9.run_hook(workingForm, "create", "before");
753
+ }
754
+
729
755
  var results = yield _this9.database.insert(id, workingForm, args.expiry);
730
756
 
731
757
  _this9.setMonitor();
732
758
 
733
- yield _this9.run_hook(_extends({}, results, {
734
- id
735
- }), "create", "after");
736
- results = yield _this9.do_serialize(results, "read", {}, args, (yield _this9.propsToBeRemoved(results)));
759
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
760
+ results = yield _this9.do_serialize(results, "read", {}, args, (yield _this9.propsToBeRemoved(results)));
761
+ }
762
+
763
+ if (args.skip_hooks != true) {
764
+ yield _this9.run_hook(_extends({}, results, {
765
+ id
766
+ }), "create", "after");
767
+ }
768
+
737
769
  return _extends({}, results, {
738
770
  id
739
771
  });
@@ -757,7 +789,10 @@ class SpiceModel {
757
789
  var results = yield _this10.database.get(args.id);
758
790
 
759
791
  try {
760
- yield _this10.run_hook(args, "delete", "before");
792
+ if (args.skip_hooks != true) {
793
+ yield _this10.run_hook(args, "delete", "before");
794
+ }
795
+
761
796
  var delete_response = {};
762
797
 
763
798
  if (args.hard) {
@@ -770,7 +805,10 @@ class SpiceModel {
770
805
  delete_response = yield _this10.database.update(args.id, "");
771
806
  }
772
807
 
773
- yield _this10.run_hook(results, "delete", "after", results);
808
+ if (args.skip_hooks != true) {
809
+ yield _this10.run_hook(results, "delete", "after", results);
810
+ }
811
+
774
812
  return {};
775
813
  } catch (e) {
776
814
  console.log(e.stack);
@@ -822,6 +860,10 @@ class SpiceModel {
822
860
  }
823
861
  }
824
862
 
863
+ if ((0, _Security.hasSQLInjection)(query)) {
864
+ return [];
865
+ }
866
+
825
867
  if (args.limit) {
826
868
  args.limit = Number(args.limit);
827
869
  }
@@ -834,7 +876,9 @@ class SpiceModel {
834
876
  args.sort = "created_at DESC";
835
877
  }
836
878
 
837
- yield _this11.run_hook(_this11, "list", "before");
879
+ if (args.skip_hooks != true) {
880
+ yield _this11.run_hook(_this11, "list", "before");
881
+ }
838
882
 
839
883
  function removeSpaceAndSpecialCharacters(str) {
840
884
  return str.replace(/[^a-zA-Z0-9]/g, "");
@@ -884,8 +928,11 @@ class SpiceModel {
884
928
  var _cached_results2 = yield _this11.getCacheProviderObject(_this11.type).get(key);
885
929
 
886
930
  results = _cached_results2 == null ? void 0 : _cached_results2.value;
931
+ var shouleForceRefresh = yield _this11.shouldForceRefresh(_cached_results2);
932
+ console.log("Cache Results", _this11.type, (_cached_results2 == null ? void 0 : _cached_results2.value) == undefined, shouleForceRefresh, (_cached_results2 == null ? void 0 : _cached_results2.value) == undefined || shouleForceRefresh);
887
933
 
888
- if ((_cached_results2 == null ? void 0 : _cached_results2.value) == undefined || (yield _this11.shouldForceRefresh(_cached_results2))) {
934
+ if ((_cached_results2 == null ? void 0 : _cached_results2.value) == undefined || shouleForceRefresh) {
935
+ console.log("Getting From Database With Cache", _this11.type);
889
936
  results = yield _this11.database.search(_this11.type, args.columns || "", query || "", args.limit, args.offset, args.sort, args.do_count, args.statement_consistent);
890
937
 
891
938
  _this11.getCacheProviderObject(_this11.type).set(key, {
@@ -904,8 +951,13 @@ class SpiceModel {
904
951
  }
905
952
 
906
953
  try {
907
- yield _this11.run_hook(results.data, "list", "after");
908
- results.data = yield _this11.do_serialize(results.data, "read", {}, args, (yield _this11.propsToBeRemoved(results.data)));
954
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
955
+ results.data = yield _this11.do_serialize(results.data, "read", {}, args, (yield _this11.propsToBeRemoved(results.data)));
956
+ }
957
+
958
+ if (args.skip_hooks != true) {
959
+ yield _this11.run_hook(results.data, "list", "after");
960
+ }
909
961
  } catch (e) {
910
962
  console.log(e);
911
963
  }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.hasSQLInjection = hasSQLInjection;
5
+
6
+ function hasSQLInjection(input) {
7
+ // Convert input to lowercase for easier pattern matching
8
+ var lowerInput = input.toLowerCase(); // List of patterns that indicate potential SQL injection
9
+
10
+ var patterns = ["--", // T-SQL comment
11
+ "/*", // Start of block comment
12
+ "*/", // End of block comment
13
+ "or 1=1", // OR statement that's always true
14
+ "or true", // OR statement that's always true (non-T-SQL databases)
15
+ "union all", // UNION statement (often used to retrieve data from another table)
16
+ "union select", // Another form of UNION statement
17
+ ";", // Commenting out the rest of a query
18
+ "drop table", // DDL statements are very suspicious
19
+ "update ", // Modification commands
20
+ "insert into", // Insertion commands
21
+ "delete from", // Deletion commands
22
+ "exec(", // Execution function in T-SQL
23
+ "execute(", // Another execution function in T-SQL
24
+ "xp_", // Extended stored procedures in T-SQL - often used in older SQL Server attacks
25
+ "0x", // Hex encoding
26
+ "benchmark(", // MySQL benchmark function - can be used for time-based blind attacks
27
+ "sleep(", // MySQL sleep function - can also be used for time-based blind attacks
28
+ "pg_sleep(", // PostgreSQL sleep function - time-based blind attack
29
+ "cast(", // Casting can be used for type-based attacks
30
+ "convert(", // Similar to the above
31
+ "waitfor delay" // SQL Server delay function - time-based blind attack
32
+ ];
33
+
34
+ for (var pattern of patterns) {
35
+ if (lowerInput.includes(pattern)) {
36
+ return true;
37
+ }
38
+ } // Additional patterns based on regular expressions for more complex detections
39
+
40
+
41
+ var regexPatterns = [/['"‘’“”][\s]*[+]+[\s]*['"‘’“”]/ // String concatenation, often used to obfuscate injections
42
+ ];
43
+
44
+ for (var regex of regexPatterns) {
45
+ if (regex.test(lowerInput)) {
46
+ return true;
47
+ }
48
+ }
49
+
50
+ return false;
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spice-js",
3
- "version": "2.6.7",
3
+ "version": "2.6.8",
4
4
  "description": "spice",
5
5
  "main": "build/index.js",
6
6
  "repository": {
@@ -15,7 +15,6 @@
15
15
  "license": "ISC",
16
16
  "dependencies": {
17
17
  "agenda": "^3.1.0",
18
- "caniuse-lite": "^1.0.30001283",
19
18
  "co": "^4.6.0",
20
19
  "dotenv": "^8.2.0",
21
20
  "flat": "^5.0.0",
@@ -8,7 +8,14 @@ async function connect() {
8
8
  spice.cache_providers[key] = new spice.config.cache.providers[key](
9
9
  spice.config.cache.drivers[key] || {}
10
10
  );
11
- spice.cache_providers[key].initialize();
11
+ spice.cache_providers[key]
12
+ .initialize()
13
+ .then(() => {
14
+ console.log("Redis initialized successfully");
15
+ })
16
+ .catch((err) => {
17
+ console.error("Error initializing Redis:", err);
18
+ });
12
19
  }
13
20
  } catch (e) {
14
21
  console.log(e.stack);
@@ -4,6 +4,7 @@ import { MapType, DataType } from "..";
4
4
  let co = require("co");
5
5
  var regeneratorRuntime = require("regenerator-runtime");
6
6
  import ResourceLifecycleTriggered from "../events/events/ResourceLifecycleTriggered";
7
+ import { hasSQLInjection } from "../utility/Security";
7
8
 
8
9
  var SDate = require("sonover-date"),
9
10
  UUID = require("uuid"),
@@ -417,8 +418,9 @@ export default class SpiceModel {
417
418
  setMonitor() {
418
419
  let current_time = new Date().getTime();
419
420
  let obj = this.getCacheProviderObject();
420
- obj.set(`monitor::${this.type}`, { time: current_time }, { ttl: 0 });
421
- //console.log("Monitor Set", spice.monitor);
421
+ let key = `monitor::${this.type}`;
422
+ let value = { time: current_time };
423
+ obj.set(key, value, { ttl: 0 });
422
424
  }
423
425
 
424
426
  async get(args) {
@@ -427,7 +429,9 @@ export default class SpiceModel {
427
429
  args = {};
428
430
  }
429
431
  if (_.isString(args.id)) {
430
- await this.run_hook(args, "get", "before");
432
+ if (args.skip_hooks != true) {
433
+ await this.run_hook(args, "get", "before");
434
+ }
431
435
  let key = `${this.type}::${args.id}`;
432
436
  let results = {};
433
437
  if (this.shouldUseCache(this.type)) {
@@ -435,6 +439,7 @@ export default class SpiceModel {
435
439
  key
436
440
  );
437
441
  results = cached_results?.value;
442
+
438
443
  if (
439
444
  cached_results?.value == undefined ||
440
445
  (await this.shouldForceRefresh(cached_results))
@@ -461,14 +466,18 @@ export default class SpiceModel {
461
466
  }
462
467
 
463
468
  if (results.deleted == undefined || results.deleted == false) {
464
- await this.run_hook(results, "get", "after");
465
- results = await this.do_serialize(
466
- results,
467
- "read",
468
- {},
469
- args,
470
- await this.propsToBeRemoved(results)
471
- );
469
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
470
+ results = await this.do_serialize(
471
+ results,
472
+ "read",
473
+ {},
474
+ args,
475
+ await this.propsToBeRemoved(results)
476
+ );
477
+ }
478
+ if (args.skip_hooks != true) {
479
+ await this.run_hook(results, "get", "after");
480
+ }
472
481
  return results;
473
482
  } else {
474
483
  throw new Error(`${this.type} does not exist`);
@@ -493,8 +502,9 @@ export default class SpiceModel {
493
502
  if (!args) {
494
503
  args = {};
495
504
  }
496
-
497
- await this.run_hook(this, "list", "before");
505
+ if (args.skip_hooks != true) {
506
+ await this.run_hook(this, "list", "before");
507
+ }
498
508
  _.remove(args.ids, (o) => o == undefined);
499
509
  let key = `${this.type}::${_.join(args.ids, "|")}`;
500
510
  let results = [];
@@ -520,15 +530,19 @@ export default class SpiceModel {
520
530
  }
521
531
  }
522
532
  _.remove(results, (o) => o.type != this.type);
533
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
534
+ results = await this.do_serialize(
535
+ results,
536
+ "read",
537
+ {},
538
+ args,
539
+ await this.propsToBeRemoved(results)
540
+ );
541
+ }
523
542
 
524
- await this.run_hook(results, "list", "after", args.context);
525
- results = await this.do_serialize(
526
- results,
527
- "read",
528
- {},
529
- args,
530
- await this.propsToBeRemoved(results)
531
- );
543
+ if (args.skip_hooks != true) {
544
+ await this.run_hook(results, "list", "after", args.context);
545
+ }
532
546
 
533
547
  return results;
534
548
  } catch (e) {
@@ -581,19 +595,35 @@ export default class SpiceModel {
581
595
  new: this,
582
596
  id: args.id,
583
597
  };
584
- if (args.skip_hooks != true) {
585
- await this.run_hook(cover_obj, "update", "before", results);
586
- }
587
598
 
588
599
  let form;
589
600
  if (args.skip_write_serialize != true && args.skip_serialize != true) {
590
- form = await this.do_serialize(this, "write", cover_obj.new, args);
601
+ cover_obj.new = await this.do_serialize(
602
+ this,
603
+ "write",
604
+ cover_obj.new,
605
+ args
606
+ );
607
+ }
608
+
609
+ if (args.skip_hooks != true) {
610
+ await this.run_hook(cover_obj, "update", "before", results);
591
611
  }
592
- let db_data = form || this;
612
+ let db_data = cover_obj.new || this;
593
613
 
594
614
  await this.database.update(args.id, db_data);
595
615
  this.setMonitor();
596
616
 
617
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
618
+ cover_obj.new = await this.do_serialize(
619
+ cover_obj.new,
620
+ "read",
621
+ {},
622
+ args,
623
+ await this.propsToBeRemoved(cover_obj.new)
624
+ );
625
+ }
626
+
597
627
  if (args.skip_hooks != true) {
598
628
  await this.run_hook(
599
629
  {
@@ -605,17 +635,8 @@ export default class SpiceModel {
605
635
  results
606
636
  );
607
637
  }
608
- if (args.skip_read_serialize != true && args.skip_serialize != true) {
609
- form = await this.do_serialize(
610
- form,
611
- "read",
612
- {},
613
- args,
614
- await this.propsToBeRemoved(form)
615
- );
616
- }
617
638
  this.id = args.id;
618
- return { ...form, id: args.id };
639
+ return { ...cover_obj.new, id: args.id };
619
640
  } catch (e) {
620
641
  console.log("Error on update", e, e.stack);
621
642
  throw e;
@@ -639,26 +660,37 @@ export default class SpiceModel {
639
660
  if (args && args.id) {
640
661
  id = args.id;
641
662
  }
642
- await this.run_hook(workingForm, "create", "before");
643
- workingForm = await this.do_serialize(workingForm, "write", {}, args);
663
+
664
+ if (args.skip_write_serialize != true && args.skip_serialize != true) {
665
+ workingForm = await this.do_serialize(workingForm, "write", {}, args);
666
+ }
667
+
668
+ if (args.skip_hooks != true) {
669
+ await this.run_hook(workingForm, "create", "before");
670
+ }
644
671
 
645
672
  let results = await this.database.insert(id, workingForm, args.expiry);
646
673
  this.setMonitor();
647
- await this.run_hook(
648
- {
649
- ...results,
650
- id,
651
- },
652
- "create",
653
- "after"
654
- );
655
- results = await this.do_serialize(
656
- results,
657
- "read",
658
- {},
659
- args,
660
- await this.propsToBeRemoved(results)
661
- );
674
+
675
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
676
+ results = await this.do_serialize(
677
+ results,
678
+ "read",
679
+ {},
680
+ args,
681
+ await this.propsToBeRemoved(results)
682
+ );
683
+ }
684
+ if (args.skip_hooks != true) {
685
+ await this.run_hook(
686
+ {
687
+ ...results,
688
+ id,
689
+ },
690
+ "create",
691
+ "after"
692
+ );
693
+ }
662
694
  return { ...results, id };
663
695
  } catch (e) {
664
696
  console.log(e.stack);
@@ -674,7 +706,9 @@ export default class SpiceModel {
674
706
  }
675
707
  let results = await this.database.get(args.id);
676
708
  try {
677
- await this.run_hook(args, "delete", "before");
709
+ if (args.skip_hooks != true) {
710
+ await this.run_hook(args, "delete", "before");
711
+ }
678
712
  let delete_response = {};
679
713
  if (args.hard) {
680
714
  delete_response = await this.database.delete(args.id);
@@ -684,7 +718,9 @@ export default class SpiceModel {
684
718
  results.deleted = true;
685
719
  delete_response = await this.database.update(args.id, "");
686
720
  }
687
- await this.run_hook(results, "delete", "after", results);
721
+ if (args.skip_hooks != true) {
722
+ await this.run_hook(results, "delete", "after", results);
723
+ }
688
724
  return {};
689
725
  } catch (e) {
690
726
  console.log(e.stack);
@@ -732,6 +768,9 @@ export default class SpiceModel {
732
768
  }
733
769
  }
734
770
 
771
+ if (hasSQLInjection(query)) {
772
+ return [];
773
+ }
735
774
  if (args.limit) {
736
775
  args.limit = Number(args.limit);
737
776
  }
@@ -742,8 +781,9 @@ export default class SpiceModel {
742
781
  if (!args.sort) {
743
782
  args.sort = "created_at DESC";
744
783
  }
745
-
746
- await this.run_hook(this, "list", "before");
784
+ if (args.skip_hooks != true) {
785
+ await this.run_hook(this, "list", "before");
786
+ }
747
787
  function removeSpaceAndSpecialCharacters(str) {
748
788
  return str.replace(/[^a-zA-Z0-9]/g, "");
749
789
  }
@@ -811,10 +851,18 @@ export default class SpiceModel {
811
851
  this.type
812
852
  ).get(key);
813
853
  results = cached_results?.value;
814
- if (
815
- cached_results?.value == undefined ||
816
- (await this.shouldForceRefresh(cached_results))
817
- ) {
854
+ let shouleForceRefresh = await this.shouldForceRefresh(
855
+ cached_results
856
+ );
857
+ console.log(
858
+ "Cache Results",
859
+ this.type,
860
+ cached_results?.value == undefined,
861
+ shouleForceRefresh,
862
+ cached_results?.value == undefined || shouleForceRefresh
863
+ );
864
+ if (cached_results?.value == undefined || shouleForceRefresh) {
865
+ console.log("Getting From Database With Cache", this.type);
818
866
  results = await this.database.search(
819
867
  this.type,
820
868
  args.columns || "",
@@ -849,14 +897,18 @@ export default class SpiceModel {
849
897
  }
850
898
  }
851
899
  try {
852
- await this.run_hook(results.data, "list", "after");
853
- results.data = await this.do_serialize(
854
- results.data,
855
- "read",
856
- {},
857
- args,
858
- await this.propsToBeRemoved(results.data)
859
- );
900
+ if (args.skip_read_serialize != true && args.skip_serialize != true) {
901
+ results.data = await this.do_serialize(
902
+ results.data,
903
+ "read",
904
+ {},
905
+ args,
906
+ await this.propsToBeRemoved(results.data)
907
+ );
908
+ }
909
+ if (args.skip_hooks != true) {
910
+ await this.run_hook(results.data, "list", "after");
911
+ }
860
912
  } catch (e) {
861
913
  console.log(e);
862
914
  }
@@ -0,0 +1,49 @@
1
+ export function hasSQLInjection(input) {
2
+ // Convert input to lowercase for easier pattern matching
3
+ const lowerInput = input.toLowerCase();
4
+
5
+ // List of patterns that indicate potential SQL injection
6
+ const patterns = [
7
+ "--", // T-SQL comment
8
+ "/*", // Start of block comment
9
+ "*/", // End of block comment
10
+ "or 1=1", // OR statement that's always true
11
+ "or true", // OR statement that's always true (non-T-SQL databases)
12
+ "union all", // UNION statement (often used to retrieve data from another table)
13
+ "union select", // Another form of UNION statement
14
+ ";", // Commenting out the rest of a query
15
+ "drop table", // DDL statements are very suspicious
16
+ "update ", // Modification commands
17
+ "insert into", // Insertion commands
18
+ "delete from", // Deletion commands
19
+ "exec(", // Execution function in T-SQL
20
+ "execute(", // Another execution function in T-SQL
21
+ "xp_", // Extended stored procedures in T-SQL - often used in older SQL Server attacks
22
+ "0x", // Hex encoding
23
+ "benchmark(", // MySQL benchmark function - can be used for time-based blind attacks
24
+ "sleep(", // MySQL sleep function - can also be used for time-based blind attacks
25
+ "pg_sleep(", // PostgreSQL sleep function - time-based blind attack
26
+ "cast(", // Casting can be used for type-based attacks
27
+ "convert(", // Similar to the above
28
+ "waitfor delay", // SQL Server delay function - time-based blind attack
29
+ ];
30
+
31
+ for (let pattern of patterns) {
32
+ if (lowerInput.includes(pattern)) {
33
+ return true;
34
+ }
35
+ }
36
+
37
+ // Additional patterns based on regular expressions for more complex detections
38
+ const regexPatterns = [
39
+ /['"‘’“”][\s]*[+]+[\s]*['"‘’“”]/, // String concatenation, often used to obfuscate injections
40
+ ];
41
+
42
+ for (let regex of regexPatterns) {
43
+ if (regex.test(lowerInput)) {
44
+ return true;
45
+ }
46
+ }
47
+
48
+ return false;
49
+ }