@putervision/spc

1.1.24 • Public • Published

Space Proof Code

Tools to facilitate space-proofing code by identifying performance and security related issues.

Zero Dependencies

@putervision/spc is a command-line tool that analyzes codebases for performance and security issues, enforcing space-proofing principles inspired by NASA's Power of Ten rules for safety-critical software. Supporting a variety of programming languages, it helps developers build robust, reliable code for high-stakes environments like space missions, identifying vulnerabilities and inefficiencies that could compromise mission-critical systems.

Install & Usage

To install the tool globally via npm:

# install space proof code globally
npm install -g @putervision/spc

Example usage for scanning code:

# use within a dir or specify a code path
space-proof-code /path/to/code

Example output report of issues found: Example SPC Report

Command Arguments

space-proof-code|spc [/path/to/code][-cs]|[-v]|[-h]

Argument Description Required? Default
/path/to/code Path to the code you want to scan No ./
--help, -h Displays the help menu No N/A
--version, -v Displays the version number No N/A
--create-sums, -cs Generates a checksum file in the scanned code path No N/A

Generate a checksum file in your code path directory (/code/path/checksums.sha256.txt) with argument -cs or --create-sums and then subsequent scans will check scanned files against hashes stored in the checksum.

# this command will create the checksum file  /code/path/checksums.sha256.txt
space-proof-code /code/path --create-sums
# future runs will reference the created checksum file and compare with hashes generated by the scanned files
space-proof-code /code/path

Performance and Reliability Rules

@putervision/spc enforces a set of code quality rules inspired by NASA's Power of Ten guidelines, tailored to ensure performance, reliability, and maintainability in space-ready software. These checks go beyond security to identify patterns that could degrade system efficiency or stability in high-stakes environments like space missions. Below are the key rules applied across the supported programming languages:

Recursion

  • Severity: 4/5

  • Description: Recursive calls can exhaust stack space, leading to crashes in memory-constrained systems like spacecraft. In real-time environments, this risks mission failure. Each recursive call adds a layer to the call stack, and if the recursion depth is too great, it can cause a stack overflow, potentially halting the program. In space missions, such failures could lead to loss of data or mission-critical operations. To mitigate this, prefer iteration, which uses a loop to achieve the same result without additional stack frames, or use tail-call optimization where supported, though this isn't always reliable. This rule is particularly critical in C/C++, where stack space is limited, and applies to Python and JavaScript, where deep recursion can still impact performance.

  • Examples:

    • C: int factorial(int n) { return factorial(n-1); }
    • Python: def factorial(n): return factorial(n-1)
    • JavaScript: function factorial(n) { return factorial(n-1); }
  • Remedy:

    • Replace with iteration, e.g., in C:
    int factorial(int n) { 
      int result = 1; 
      for(int i = 1; i <= n; i++) 
        result *= i; 
      return result; 
    }
  • External References:

Dynamic Memory

  • Severity: 4/5 (C), 3/5 (Python, JS)

  • Description: Dynamic memory allocation, such as using malloc in C, can fragment memory or fail silently, critical in resource-limited systems. Memory fragmentation occurs when allocated and deallocated memory blocks leave non-contiguous free spaces, potentially causing allocation failures even when total memory is sufficient. In spacecraft, where memory is scarce, this can lead to system crashes or unpredictable behavior. Pre-allocate fixed buffers or pools to ensure deterministic memory usage, avoiding runtime uncertainty. For Python and JavaScript, while memory management is handled by the language, large dynamic allocations (e.g., creating large lists) can still consume significant resources, though the severity is lower due to garbage collection. This rule is vital for C, where manual management increases risks, and applies to all languages to ensure resource predictability.

  • Examples:

    • C: int* ptr = malloc(10 * sizeof(int));
    • Python: data = [0] * 1000000
    • JavaScript: let arr = new Array(1000000);
  • Remedy:

    • Pre-allocate, e.g., in C: int buffer[10]; for fixed size, or use memory pools.
  • External References:

Complex Flow

  • Severity: 2/5

  • Description: Complex control structures, such as breaks, continues, and early returns, make formal verification harder, a key step in safety-critical code. Formal verification involves mathematically proving that code meets specifications, and complex flows increase the number of paths to analyze, complicating this process. Simplifying to a single exit point enhances readability and verifiability, reducing the risk of overlooked errors. This is particularly important in space missions, where code must be thoroughly checked for correctness. The rule applies across all languages, encouraging structured control flow to support maintenance and verification efforts, though the impact is less severe compared to other rules.

  • Examples:

    • C: if (x) break; else return y;
    • Python: if x: break; else: return y
    • JavaScript: if (x) return 1; else continue;
  • Remedy:

    • Restructure, e.g., in C:
    int result; 
    if (x) result = 1; 
    else result = 0; 
    return result;
  • External Reference:

Unbounded Loops

  • Severity: 5/5

  • Description: Loops without clear termination can run indefinitely, locking up real-time systems. In space missions, where timing is critical for operations like communication windows or maneuver sequences, an unbounded loop can cause the system to hang, missing deadlines and potentially leading to mission failure. Always enforce explicit bounds or timeouts, such as using a counter or condition that guarantees termination, to prevent such scenarios. This rule is universally applicable, with high severity due to its potential to disrupt real-time operations, ensuring system responsiveness and reliability.

  • Examples:

    • C: while (1) { do_work(); }
    • Python: while True: do_work()
    • JavaScript: for(;;) { doWork(); }
  • Remedy:

    • Add bounds, e.g., in C:
    for(int i = 0; i < 10; i++) { 
      do_work(); 
    }
  • External Reference:

Eval Usage

  • Severity: 5/5

  • Description: Dynamic code execution, such as using eval in JavaScript or Python, or system() in C, introduces unpredictability, undermining deterministic behavior required in critical systems. In space-ready software, the code must be deterministic to ensure predictable outcomes under all conditions, and dynamic execution can lead to runtime errors or security vulnerabilities. Use static logic, where code is compiled and analyzed beforehand, to maintain control and predictability. This rule is critical across all languages, with high severity due to the potential for catastrophic failures in mission-critical operations.

  • Examples:

    • C: system("ls");
    • Python: exec("print(x)")
    • JavaScript: eval("console.log(x)");
  • Remedy:

    • Replace with static code, e.g., in Python: print(x) directly.
  • External Reference:

Global Vars

  • Severity: 3/5

  • Description: Global variables risk unintended side effects across modules, especially in concurrent systems, complicating debugging and maintenance. In space missions, where multiple processes or threads might run concurrently, global variables can introduce race conditions, leading to data corruption or system failures. Encapsulate state locally within functions or pass it explicitly as parameters to enhance reliability and reduce concurrency issues. This rule applies to all languages, with moderate severity due to its potential to affect system integrity over time, particularly in multi-threaded environments.

  • Examples:

    • C: int global_x = 5;
    • Python: global x; x = 5
    • JavaScript: window.x = 5;
  • Remedy:

    • Pass explicitly, e.g., in C: void func(int x) { /* use x */ }
  • External Reference:

Try Catch

  • Severity: 2/5

  • Description: Exception handling, such as try-catch blocks, can mask errors, reducing reliability in systems where every failure must be explicit. In space-ready software, where reliability and predictability are paramount, exceptions can introduce non-deterministic execution times and hide critical errors, making diagnosis difficult. Prefer error codes or assertions to ensure errors are handled predictably, providing clear feedback for debugging and maintenance. This rule is less severe but important for maintaining explicit error handling, applicable across languages with exception mechanisms.

  • Remedy:

    • Use error codes, e.g., in C:
    int result = risky(); 
    if (result != OK) handle_error();
  • Examples:

    • C: try { risky(); } catch(...) {} (C++)
    • Python: try: risky() except: pass
    • JavaScript: try { risky(); } catch(e) {}
  • External Reference:

Multiple Returns

  • Severity: 2/5

  • Description: Multiple return points complicate control flow analysis, hindering formal verification, essential for safety-critical code. In space-ready software, where code must be thoroughly verified, having a single exit point simplifies tracing all possible paths, reducing the risk of overlooked errors. Use a single exit to enhance clarity and verifiability, ensuring all cleanup or final operations are performed consistently, applicable across all languages for maintainability.

  • Examples:

    • C: int foo() { if(x) return 1; return 0; }
    • Python: def foo(): if x: return 1; return 0
    • JavaScript: function foo() { if(x) return 1; return 0; }
  • Remedy:

    • Restructure, e.g., in C:
    int result; 
    if (x) result = 1; 
    else result = 0; 
    return result;
  • External Reference:

Nested Conditionals

  • Severity: 2/5

  • Description: Deep nesting increases complexity and error risk, though not directly catastrophic. In space-ready software, where code must be reliable and maintainable over long periods, nested conditionals can make understanding and verifying code difficult, increasing cognitive load. Flatten or refactor into smaller, linear conditionals or separate functions to reduce complexity, enhancing readability and reducing error potential, applicable across all languages for long-term reliability.

  • Examples:

    • C: if (x) { if (y) { do_work(); } }
    • Python: if x: if y: do_work()
    • JavaScript: if (x) { if (y) { doWork(); } }
  • Remedy:

    • Use guard clauses, e.g., in C:
    if (!x) return; 
    if (!y) return; 
    do_work();
  • External Reference:

Set Timeout

  • Severity: 4/5 (JS-specific, omitted in C/Python)

  • Description: Timing-dependent operations, like JavaScript's setTimeout, introduce non-determinism, risky in real-time systems. The actual execution time can vary based on system load, leading to unpredictable behavior, which is unacceptable in space missions where timing is critical. Use fixed intervals or event-driven logic, such as setInterval with careful management, to ensure deterministic timing. This rule is specific to JavaScript, reflecting its use in potentially mission-related applications, with high severity due to timing sensitivity in real-time operations.

  • Examples:

    • C: N/A (no direct equivalent)
    • Python: N/A (no direct equivalent, but time.sleep() could approximate)
    • JavaScript: setTimeout(doWork, 1000);
  • Remedy:

    • Use setInterval with careful management:
    setInterval(doWork, 1000);
  • External Reference:

Import Risk

  • Severity: 3/5 (Python only)

  • Description: Wildcard imports (from module import *) in Python bloat codebases by importing all names from a module into the current namespace, risking namespace pollution, unintended name clashes, and complicating formal verification. This practice can obscure the origin of functions or variables, making it harder to trace dependencies and ensure deterministic behavior—critical in high-stakes environments like space missions. Explicit imports (from module import specific_name) are preferred to maintain clarity, reduce the likelihood of errors, and simplify auditing and maintenance of safety-critical code.

  • Examples:

    • C: N/A
    • Python: from os import *
    • JavaScript: N/A
  • Remedy:

    • Import specific names or the module itself:
      from os import mkdir  # Explicit: only mkdir is imported
      # Or
      import os  # Preferred: use os.mkdir() for clarity
      os.mkdir("new_dir")
  • External Reference:

Exceeds Max Function Lines

  • Severity: 3/5

  • Description: Functions exceeding a maximum line count (e.g., 50-100 lines) become hard to verify and maintain, increasing error risk in critical systems. Long functions are harder to understand, test, and debug, potentially hiding bugs that could affect mission reliability. Break long functions into smaller, focused units, each performing a single task, to improve readability, testability, and verifiability, crucial for space missions where code must be robust and maintainable over extended periods, applicable across all languages.

  • Examples:

    • C: int process() { /* 200 lines of logic */ }
    • Python: def process(): # 200 lines of logic
    • JavaScript: function process() { /* 200 lines of logic */ }
  • Remedy:

    • Split, e.g., in C:
      int process_part1(); 
      int process_part2();
  • External Reference:

Unchecked Function Return

  • Severity: 2/5

  • Description: Ignoring return values from non-critical functions can mask subtle bugs or inefficiencies, though it’s not immediately catastrophic. In space-ready software, where every operation must be reliable, unchecked returns can lead to undetected errors, potentially compromising mission-critical operations. Check returns unless explicitly void or harmless, ensuring errors are handled and system state remains consistent, applicable across all languages for enhanced reliability.

  • Examples:

    • C: printf("hello"); (return ignored)
    • Python: os.mkdir("dir") (exception possible, not checked)
    • JavaScript: setTimeout(doWork, 1000); (ID ignored)
  • Remedy:

    • Check, e.g., in C:
      if (printf("hello") < 0) handle_error();
  • External Reference:

Security Rules

@putervision/spc performs security-focused checks to protect space-bound code from vulnerabilities, such as RF-based API injection from neighboring satellites. These rules identify patterns that could compromise system integrity, confidentiality, or availability in high-stakes environments where human intervention isn’t possible. Below are the security rules enforced by the tool:

Unsafe Input

  • Severity: 4/5

  • Description: Unvalidated inputs pose a significant risk in programming, particularly in systems exposed to radio frequency (RF) communications. When inputs are not properly checked or sanitized, they can lead to a variety of security vulnerabilities and system failures. One common issue is buffer overflow, where the input data exceeds the expected size of the buffer, causing memory to be overwritten in unpredictable ways. This can result in program crashes or, in more severe cases, allow an attacker to execute arbitrary code. Another critical risk is injection attacks, such as SQL injection or command injection. In these attacks, an attacker can insert malicious code or commands into the input, which the program then executes, potentially leading to data breaches or system compromise. In RF-exposed systems, the risk is amplified because the input data might be coming from an external, potentially hostile environment. The data could be corrupted due to transmission errors or deliberately tampered with to exploit vulnerabilities. To mitigate these risks, it's essential to always validate and sanitize inputs. This includes checking the type, format, and size of the input data, and ensuring that it conforms to expected patterns. For RF systems, additional measures such as error detection and correction codes can help ensure data integrity. In summary, unvalidated inputs are a major security and reliability concern that can be addressed through rigorous input validation and sanitization practices.

  • Examples:

    • C: scanf("%s", buf);
    • Python: user_input = input();
    • JavaScript: let data = req.body.payload;
  • Remedies:

    • Input Validation: Always check that the input data matches the expected type and format. For example, ensure that a field expected to be a number actually contains a numeric value.
    • Sanitization: Cleanse the input data to remove any characters or patterns that could be used for malicious purposes, such as SQL injection or cross-site scripting (XSS).
    • Parameterized Queries: Use parameterized queries or prepared statements in database interactions to separate code from data, preventing injection attacks.
    • Buffer Size Management: Ensure that buffers are sized appropriately and that input data does not exceed these sizes. Use bounded input functions that prevent buffer overflows.
    • Error Handling: Implement robust error handling to manage cases where input is invalid, providing clear messages to users and preventing system crashes or security breaches.
  • External Reference:

Network Call

  • Severity: 3/5

  • Description: Network calls are essential for many applications but introduce several risks, particularly in environments with unreliable communications. These risks include latency, which can slow down real-time systems, external failure points where the program's success depends on network availability, and security vulnerabilities where communications can be intercepted or tampered with. In space or remote settings, network communications might be even more unreliable due to factors like distance, signal interference, or limited bandwidth. Therefore, it's crucial to design systems that can handle network failures gracefully and minimize dependency on network operations where possible. To mitigate these risks, developers should implement robust error handling, use caching or offline capabilities, secure communications with encryption, and design with redundancy to handle failures. In summary, while network calls are often necessary, they should be used judiciously, especially in critical or unreliable communication environments.

  • Examples:

    • C: socket(AF_INET, SOCK_STREAM, 0);
    • Python: requests.get("http://api");
    • JavaScript: fetch("http://api");
  • Remedies:

    • Error Handling: Implement try-catch blocks or equivalent mechanisms to handle network exceptions and provide meaningful error messages.
    • Timeout Settings: Set appropriate timeouts for network operations to prevent the program from hanging indefinitely.
    • Caching: Use caching mechanisms to store results of network calls and reduce the frequency of requests.
    • Offline Mode: Provide an offline mode or fallback mechanisms when network operations fail.
    • Security Measures: Ensure that all network communications are encrypted and authenticated to prevent eavesdropping and tampering.
  • External Reference:

Weak Crypto

  • Severity: 4/5

  • Description: Using weak cryptographic methods can compromise system security, especially in environments like space missions where data integrity and confidentiality are paramount. Weak algorithms, such as MD5 for hashing or simple random number generators, have known vulnerabilities and can be broken easily. Additionally, weak crypto can fail due to bit-flips from cosmic radiation, altering data in memory, which is critical in high-radiation environments. To ensure security, use modern algorithms like AES for encryption, SHA-256 for hashing, and cryptographically secure pseudo-random number generators for key generation. Implement proper key management, regular updates, and error detection to safeguard against attacks and environmental threats. In summary, weak cryptography poses both security and reliability risks, necessitating robust practices.

  • Examples:

    • C: int r = rand();
    • Python: hashlib.md5(data);
    • JavaScript: Math.random();
  • Remedies:

    • Use Strong Algorithms: Replace weak algorithms like MD5 with stronger ones like SHA-256 or SHA-3.
    • Secure Randomness: Use CSPRNGs for generating keys and other sensitive data.
    • Regular Updates: Keep cryptographic libraries and software up-to-date to benefit from the latest security patches.
    • Key Management: Implement proper key management practices, including secure storage and periodic rotation.
    • Error Detection: Use techniques like checksums or digital signatures to detect any alterations in data due to bit-flips or other errors.
  • External Reference:

Unsafe File Op

  • Severity: 3/5

  • Description: File operations, if not handled properly, can lead to errors and security vulnerabilities, such as crashes from unhandled errors, directory traversal attacks from unvalidated paths, and processing errors from malformed data. In critical systems like space missions, these issues can cause data corruption or loss with severe consequences. To mitigate, always check return values, validate file paths, verify data integrity, manage permissions, and implement backups. Safe file operations require diligent practices to prevent system failures and breaches, ensuring reliability and security.

  • Examples:

    • C: fopen("file.txt", "r");
    • Python: open("file.txt", "r");
    • JavaScript: fs.readFile("file.txt");
  • Remedies:

    • Error Checking: Always check the return values of file operation functions and handle errors gracefully.
    • Path Sanitization: Ensure that file paths are validated and sanitized to prevent directory traversal or access to unauthorized files.
    • Data Validation: Verify that the data read from the file is in the expected format and is not corrupted.
    • Permissions Management: Set appropriate permissions for file access to prevent unauthorized modifications or disclosures.
    • Redundancy and Backup: Implement backup and redundancy mechanisms for critical files to handle data loss or corruption.
  • External Reference:

Unsanitized Exec

  • Severity: 5/5

  • Description: Executing untrusted input can lead to arbitrary code execution, a severe vulnerability known as command injection, allowing attackers to control the system. This can result in data theft or system compromise, with catastrophic consequences in space systems. To prevent, avoid dynamic execution where possible, sanitize inputs if necessary, limit process privileges, whitelist safe inputs, and use secure alternatives. Careful input handling and secure coding practices are essential to mitigate this risk, ensuring system integrity and security.

  • Examples:

    • C: system(user_input);
    • Python: os.system(f"echo {input}");
    • JavaScript: exec(echo ${input});
  • Remedies:

    • Avoid Dynamic Execution: Refrain from using functions that execute arbitrary code or commands based on user input.
    • Input Sanitization: If dynamic execution is unavoidable, sanitize the input to remove any potentially harmful characters or commands.
    • Least Privilege: Run the program or the part that executes commands with the least privileges necessary.
    • Whitelisting: Only allow specific, known-safe inputs or commands to be executed.
    • Secure Alternatives: Use secure alternatives for tasks that might otherwise require dynamic execution, such as using template engines for generating output.
  • External Reference:

Exposed Secrets

  • Severity: 5/5

  • Description: Exposing secrets like API keys or passwords in code or files is a critical risk, easily accessed via code inspection or memory dumps, compromising security. In secure environments like space missions, this can lead to unauthorized access and mission disruption. Protect secrets by using environment variables, secret management tools like HashiCorp Vault, encrypted storage, strict access controls, and regular audits. Proper secrets management is vital for maintaining system security and integrity, especially in high-stakes settings.

  • Examples:

    • C: char* key = "xyz123";
    • Python: api_key = "xyz123"
    • JavaScript: const apiKey = "xyz123";
  • Remedies:

    • Use Environment Variables: Store sensitive information as environment variables that are not committed to version control.
    • Secret Vaults: Utilize secret management tools to securely store and retrieve secrets.
    • Encrypted Storage: Store secrets in encrypted files or databases, accessible only through secure channels.
    • Access Controls: Implement strict access controls to limit who can view or modify secrets.
    • Regular Audits: Periodically audit the code and configuration files to ensure no secrets are inadvertently exposed.
  • External Reference:

Buffer Overflow Risk

  • Severity: 5/5 (C-specific, lower in Python/JS)

  • Description: Buffer overflow, primarily affecting C and C++, occurs when data overwrites memory beyond buffer size, causing crashes or enabling code execution. In critical systems like space missions, this can lead to system failures or security breaches. Prevent by using bounded functions, checking buffer sizes, managing memory, using compiler flags, and static analysis tools. This risk is lower in Python and JavaScript due to managed memory, highlighting the importance of language choice and careful coding in vulnerable languages.

  • Examples:

    • C: strcpy(dest, src);
    • Python: N/A (managed memory)
    • JavaScript: N/A (managed memory)
  • Remedies:

    • Use Bounded Functions: In C, use functions like strncpy and snprintf that allow specifying the buffer size.
    • Check Buffer Sizes: Always ensure that the source data is smaller than the destination buffer.
    • Memory Management: Use dynamic memory allocation with proper size calculations.
    • Compiler Flags: Use compiler flags that enable buffer overflow checks, such as -fstack-protector in GCC.
    • Static Analysis: Use static analysis tools to detect potential buffer overflow vulnerabilities in the code.
  • External Reference:

Insufficient Logging

  • Severity: 2/5

  • Description: Insufficient logging can hinder debugging, security incident investigation, and performance monitoring in critical systems like space missions. Comprehensive logging is crucial for post-incident analysis, especially where real-time intervention is limited. However, over-logging can flood systems, impacting performance. Best practices include logging key events, using log levels, securing log storage, and regular reviews. While logging might seem minor, insufficient practices can severely impact system maintenance and security, necessitating balanced approaches.

  • Examples:

    • C: int main() { return 0; } (no logs)
    • Python: def main(): pass (no logs)
    • JavaScript: app.get("/data", () => "OK"); (no logs)
  • Remedies:

    • Implement Logging Frameworks: Use logging libraries or frameworks that allow for configurable log levels and outputs.
    • Log Critical Events: Ensure that all critical system events, such as errors, security incidents, and major state changes, are logged.
    • Avoid Over-Logging: Configure log levels to avoid logging excessive, non-critical information that could clutter logs and impact performance.
    • Secure Log Storage: Store logs in a secure manner, protecting them from tampering or unauthorized access.
    • Regular Review: Schedule regular reviews of logs to detect any issues or anomalies.
  • External Reference:

Unrestricted CORS

  • Severity: 4/5 (JS only)

  • Description: Overly permissive CORS settings allow unauthorized access in web-exposed systems. Restrict origins explicitly. Unrestricted Cross-Origin Resource Sharing (CORS) happens when a server lets any website access its resources, which can be risky for web applications open to the internet. This can allow attackers to trick users into unwanted actions (like Cross-Site Request Forgery, or CSRF) or access sensitive data, potentially leading to privacy breaches. An unexpected detail is that this risk is specific to JavaScript-based web applications, highlighting the need for careful configuration in web development.

  • Examples:

    • C: N/A
    • Python: N/A
    • JavaScript: app.use(cors({ origin: "*" }));
  • Remedies:

    • Restrict Access: Only allow trusted websites to access your server by listing them, like in Express.js:
    const express = require('express');
    const app = express();
    const cors = require('cors');
    
    app.use(cors({
      origin: ['https://example.com', 'https://sub.example.com']
    }));
    • Add Security: Use secure cookies and validate request headers to prevent attacks.
  • External Reference:

Async Risk

  • Severity: 4/5 (JS only)

  • Description: Asynchronous operations in JavaScript, like fetching data, can be unpredictable in timing, which is risky for systems needing instant responses, such as real-time apps for live updates. This unpredictability can delay actions or cause errors, affecting user experience or system reliability. An unexpected detail is that this risk might apply to JavaScript in embedded systems, not just web apps, broadening its relevance beyond typical use cases.

  • Examples:

    • C: N/A
    • Python: N/A
    • JavaScript: async function foo() { await fetch(); }
  • Remedies:

    • Minimize Async Use: Avoid async operations in critical tasks where timing is key.
    • Structure Code: Use promises and async/await to make async code more predictable.
    • Offload Tasks: Use Web Workers to handle heavy tasks without slowing down the main program.
    • Set Time Limits: Add timeouts to ensure the system stays responsive.
  • External Reference: MDN Async JS

Checksum Mismatch

  • Severity: 4/5

  • Description: Failing to verify checksums or hashes on data, especially from RF sources, risks accepting corrupted or tampered input, compromising integrity. In space missions, data transmitted over long distances is susceptible to corruption due to noise or interference, and tampering could lead to incorrect decisions. Always validate data authenticity using checksums or hashes to ensure integrity, crucial for mission-critical communications, applicable across all languages for data handling.

  • Code Examples:

    • C: recv_data(buf); /* no checksum check */
    • Python: data = socket.recv(1024) # no hash validation
    • JavaScript: fetch("data").then(d => use(d)); // no integrity check
  • Remedies:

    • Create and verify checksums with the spc --create-sums argument space-proof-code -cs
    • In code verify, e.g., in C:
      if (verify_checksum(data, expected) != OK) handle_error();
  • External Reference:

Unchecked Function Return Critical

  • Severity: 5/5

  • Description: Unchecked return values from critical functions pose a severe risk in programming, particularly in critical systems where reliability and security are paramount. Critical functions, such as those involved in cryptography, network operations, file handling, or system calls, often return status information that indicates whether the operation was successful or not. Failing to check these return values can lead to silent failures, where the program continues to operate under the assumption that the function call was successful, when in reality, it may have failed or only partially succeeded. This can result in data corruption, security vulnerabilities, or system instability. In the context of space missions, where operations are often time-critical and communication is limited, such failures can have catastrophic consequences. For instance, if a critical communication function fails to send a command and this failure goes unchecked, the mission could be compromised without any indication to the operators. Therefore, it is essential to always validate the return values of critical functions and handle any errors or exceptions appropriately to ensure the robustness and security of the system.

  • Examples:

    • C: send(sock, data, len, 0); (return not checked)
    • Python: requests.get("https://api") (status not checked)
    • JavaScript: fetch("https://api"); (response not validated)
  • Remedies:

    • Check Return Values: Always check the return values of critical functions and handle any errors indicated by these values.
    • Error Handling: Implement robust error handling mechanisms, such as using try-catch blocks in languages that support exceptions, to manage and respond to failures.
    • Logging: Log errors or exceptions to facilitate debugging and post-incident analysis.
    • Redundancy: Design the system with redundancy to handle failures gracefully, ensuring that the system can recover or operate in a degraded mode if a critical function fails.
  • External Reference:

Zero External Dependencies

  • Code from scratch: We write all code from scratch to avoid potential issues introduced with a dependency chain. By skipping external libraries and frameworks, we dodge the risk of bugs, security holes, or breaking changes sneaking in from someone else’s code.

Limitations

  • Regex-Based: May miss complex cases (e.g., comments, nested scopes) without a full parser.
  • Language-Specific: Some rules (e.g., pointers) apply only to C/C++.
  • False Positives: Patterns like while (true) with a break might still flag.

Contributing

  • Report issues or suggest features via GitHub.
  • To extend support for other languages, modify LANGUAGE_PATTERNS in lib/scanner.js.

License

MIT License - see LICENSE for details.

Author

PuterVision code@putervision.com - https://putervision.com

Package Sidebar

Install

npm i @putervision/spc

Weekly Downloads

0

Version

1.1.24

License

MIT

Unpacked Size

161 kB

Total Files

42

Last publish

Collaborators

  • putervision