pumuki 6.3.324 → 6.3.325

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.
@@ -175,6 +175,7 @@ import {
175
175
  collectSwiftSensitiveLoggingLines,
176
176
  hasSwiftSensitiveLoggingUsage,
177
177
  hasSwiftSelfPrintChangesUsage,
178
+ collectSwiftInsecureTransportLines,
178
179
  collectSwiftSensitiveUserDefaultsStorageLines,
179
180
  hasSwiftSensitiveUserDefaultsStorageUsage,
180
181
  hasSwiftInsecureTransportUsage,
@@ -2080,8 +2081,11 @@ let text = "https://example.com/catalog.json"
2080
2081
  `;
2081
2082
 
2082
2083
  assert.equal(hasSwiftInsecureTransportUsage(source), true);
2084
+ assert.deepEqual(collectSwiftInsecureTransportLines(source), [4]);
2083
2085
  assert.equal(hasSwiftInsecureTransportUsage(plist), true);
2086
+ assert.deepEqual(collectSwiftInsecureTransportLines(plist), [5]);
2084
2087
  assert.equal(hasSwiftInsecureTransportUsage(ignored), false);
2088
+ assert.deepEqual(collectSwiftInsecureTransportLines(ignored), []);
2085
2089
  });
2086
2090
 
2087
2091
  test('detector iOS de localización detecta strings UI hardcodeadas sin confundir keys ni comentarios', () => {
@@ -1737,22 +1737,39 @@ export const collectSwiftSensitiveUserDefaultsStorageLines = (source: string): r
1737
1737
  };
1738
1738
 
1739
1739
  export const hasSwiftInsecureTransportUsage = (source: string): boolean => {
1740
- const withoutBlockComments = source.replace(/\/\*[\s\S]*?\*\//g, '\n');
1741
- const hasHttpUrlLiteral = withoutBlockComments.split(/\r?\n/).some((line) => {
1742
- if (/^\s*\/\//.test(line)) {
1743
- return false;
1740
+ return collectSwiftInsecureTransportLines(source).length > 0;
1741
+ };
1742
+
1743
+ export const collectSwiftInsecureTransportLines = (source: string): readonly number[] => {
1744
+ const lines = source.split(/\r?\n/);
1745
+ const result: number[] = [];
1746
+ let pendingAtsKeyLine: number | null = null;
1747
+
1748
+ lines.forEach((line, index) => {
1749
+ const lineNumber = index + 1;
1750
+ const sanitized = stripSwiftLineForSemanticScan(line);
1751
+ if (!/^\s*\/\//.test(line) && /["']http:\/\/[^"']*["']/.test(line)) {
1752
+ result.push(lineNumber);
1744
1753
  }
1745
- return /["']http:\/\/[^"']*["']/.test(line);
1746
- });
1747
1754
 
1748
- if (hasHttpUrlLiteral) {
1749
- return true;
1750
- }
1755
+ if (/\bNSAllowsArbitraryLoads\b\s*=\s*(?:true|YES|1)\b/i.test(sanitized)) {
1756
+ result.push(lineNumber);
1757
+ pendingAtsKeyLine = null;
1758
+ return;
1759
+ }
1751
1760
 
1752
- return (
1753
- /<key>\s*NSAllowsArbitraryLoads\s*<\/key>\s*<true\s*\/>/i.test(source) ||
1754
- /\bNSAllowsArbitraryLoads\b\s*=\s*(?:true|YES|1)\b/i.test(source)
1755
- );
1761
+ if (/<key>\s*NSAllowsArbitraryLoads\s*<\/key>/i.test(line)) {
1762
+ pendingAtsKeyLine = lineNumber;
1763
+ return;
1764
+ }
1765
+
1766
+ if (pendingAtsKeyLine !== null && /<true\s*\/>/i.test(line)) {
1767
+ result.push(pendingAtsKeyLine);
1768
+ pendingAtsKeyLine = null;
1769
+ }
1770
+ });
1771
+
1772
+ return sortedUniqueLines(result);
1756
1773
  };
1757
1774
 
1758
1775
  const swiftUiLiteralTextPatterns = [
@@ -811,8 +811,8 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
811
811
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftAlamofireUsage, ruleId: 'heuristics.ios.networking.alamofire.ast', code: 'HEURISTICS_IOS_NETWORKING_ALAMOFIRE_AST', message: 'AST heuristic detected Alamofire usage in iOS production code; URLSession remains the preferred baseline for new code.' },
812
812
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftJSONSerializationUsage, ruleId: 'heuristics.ios.json.jsonserialization.ast', code: 'HEURISTICS_IOS_JSON_JSONSERIALIZATION_AST', message: 'AST heuristic detected JSONSerialization usage in iOS production code; Codable remains the preferred baseline for new code.' },
813
813
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftSensitiveUserDefaultsStorageUsage, locateLines: TextIOS.collectSwiftSensitiveUserDefaultsStorageLines, primaryNode: (lines) => ({ kind: 'call', name: 'sensitive UserDefaults/AppStorage storage', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: native Keychain or secure secret store', lines }], why: 'Tokens, passwords, credentials and session identifiers must not be stored in UserDefaults or AppStorage because those stores are not the approved secret boundary.', impact: 'Secrets persisted in UserDefaults/AppStorage can leak through backups, diagnostics or simple local inspection, and the gate needs the exact storage node to avoid whole-file remediation.', expected_fix: 'Move tokens, passwords, credentials and session identifiers to native Keychain or the repository-approved secure storage adapter. Keep UserDefaults/AppStorage only for non-sensitive preferences.', ruleId: 'heuristics.ios.security.userdefaults-sensitive-data.ast', code: 'HEURISTICS_IOS_SECURITY_USERDEFAULTS_SENSITIVE_DATA_AST', message: 'AST heuristic detected sensitive data stored in UserDefaults/AppStorage; native Keychain remains the preferred baseline for secrets.' },
814
- { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftInsecureTransportUsage, ruleId: 'heuristics.ios.security.insecure-transport.ast', code: 'HEURISTICS_IOS_SECURITY_INSECURE_TRANSPORT_AST', message: 'AST heuristic detected insecure HTTP transport in iOS production code; HTTPS and ATS remain the preferred baseline.' },
815
- { platform: 'ios', pathCheck: isIOSInfoPlistPath, excludePaths: [], detect: TextIOS.hasSwiftInsecureTransportUsage, ruleId: 'heuristics.ios.security.insecure-transport.ast', code: 'HEURISTICS_IOS_SECURITY_INSECURE_TRANSPORT_AST', message: 'AST heuristic detected permissive App Transport Security configuration; HTTPS and ATS remain the preferred baseline.' },
814
+ { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftInsecureTransportUsage, locateLines: TextIOS.collectSwiftInsecureTransportLines, primaryNode: (lines) => ({ kind: 'call', name: 'insecure HTTP URL literal', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: HTTPS URLSession endpoint with ATS enabled', lines }], why: 'Production iOS networking must use HTTPS and keep App Transport Security enabled by default.', impact: 'HTTP endpoints can expose credentials, session data or payloads in transit and create release-blocking transport exceptions.', expected_fix: 'Replace http:// endpoints with https:// endpoints and keep ATS enabled. If a temporary exception is unavoidable, isolate it to a documented debug-only configuration, not production code.', ruleId: 'heuristics.ios.security.insecure-transport.ast', code: 'HEURISTICS_IOS_SECURITY_INSECURE_TRANSPORT_AST', message: 'AST heuristic detected insecure HTTP transport in iOS production code.' },
815
+ { platform: 'ios', pathCheck: isIOSInfoPlistPath, excludePaths: [], detect: TextIOS.hasSwiftInsecureTransportUsage, locateLines: TextIOS.collectSwiftInsecureTransportLines, primaryNode: (lines) => ({ kind: 'property', name: 'ATS NSAllowsArbitraryLoads enabled', lines }), relatedNodes: (lines) => [{ kind: 'property', name: 'replacement: ATS enabled with explicit HTTPS-only exceptions', lines }], why: 'NSAllowsArbitraryLoads disables the default iOS App Transport Security protection and should not be enabled for production builds.', impact: 'Permissive ATS configuration allows insecure transport globally, making networking violations harder to audit per endpoint.', expected_fix: 'Remove NSAllowsArbitraryLoads=true. Keep ATS enabled by default and add the narrowest documented domain exception only when the production requirement is approved.', ruleId: 'heuristics.ios.security.insecure-transport.ast', code: 'HEURISTICS_IOS_SECURITY_INSECURE_TRANSPORT_AST', message: 'AST heuristic detected permissive App Transport Security configuration.' },
816
816
  { platform: 'ios', pathCheck: isIOSLocalizableStringsPath, excludePaths: [], detect: detectsTrackedFilePresence, ruleId: 'heuristics.ios.localization.localizable-strings.ast', code: 'HEURISTICS_IOS_LOCALIZATION_LOCALIZABLE_STRINGS_AST', message: 'AST heuristic detected Localizable.strings usage; String Catalogs (.xcstrings) remain the preferred baseline for new localization work.' },
817
817
  { platform: 'ios', pathCheck: isIOSInterfaceBuilderPath, excludePaths: [], detect: detectsTrackedFilePresence, ruleId: 'heuristics.ios.interface-builder.storyboard-xib.ast', code: 'HEURISTICS_IOS_INTERFACE_BUILDER_STORYBOARD_XIB_AST', message: 'AST heuristic detected Storyboard/XIB usage; programmatic SwiftUI/UIKit UI remains the preferred baseline for versionable iOS code.' },
818
818
  { platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftHardcodedUiStringUsage, locateLines: TextIOS.collectSwiftHardcodedUiStringLines, primaryNode: (lines) => ({ kind: 'property', name: 'hardcoded user-facing SwiftUI string', lines }), relatedNodes: (lines) => [{ kind: 'property', name: 'replacement: String Catalog key or String(localized:)', lines }], why: 'User-facing literals in SwiftUI code bypass String Catalogs and make localization drift invisible.', impact: 'A consumer slice can be blocked without knowing which text literal must move to localization assets.', expected_fix: 'Move visible copy to String Catalogs or use repository-approved localized string keys; keep only localization keys in SwiftUI code.', ruleId: 'heuristics.ios.localization.hardcoded-ui-string.ast', code: 'HEURISTICS_IOS_LOCALIZATION_HARDCODED_UI_STRING_AST', message: 'AST heuristic detected hardcoded user-facing SwiftUI text; String(localized:) and String Catalogs remain the preferred baseline.' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pumuki",
3
- "version": "6.3.324",
3
+ "version": "6.3.325",
4
4
  "description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
5
5
  "main": "index.js",
6
6
  "bin": {