Score:0

lighttpd: ajax request prints the content of cgi script instead of running it

de flag

I am using lighttpd version 1.4.55 within an ARM environment. I created an HTML pages in which there is a button used to download some json data. This button trigger a submit form that calls a cgi script. This script has to take the output of the form and write into a file. But when I click on the button, the response text of the xhr request is the content of the cgi script instead of the printf message. The cgi has the execution permissions.

I divided the folders in the following way: •mnt/userfs/lighttpd/

•www
    • /scripts_files
        •json.cgi
    • /html_files
        •css folder
        •js folder
    • upload_dir
    • index.html
    • /admin
        • password_file
        • main.html
        • file_upload.html
    • /user
        • password_file
        • main.html
        • file_upload.html
•lighttpd.conf
•log
    •error.log

The button that calls the form is the following:

<a href="/scripts_files/conf.json" download="data.json">            
    <input type="button" value="DOWNLOAD" onclick="submit_form();">
</a>

The button calls a function and then download the file created with .cgi script.

The function of the ajax request:

function submit_form()
    {
        var div1 = document.getElementById("extern");
        var data = {};
        data = recursive_f(div1, 0, 0);
        output = JSON.stringify(data);
        var xhr_lv = new XMLHttpRequest();
        xhr_lv.onreadystatechange=function()
        xhr_lv.open("POST", "/scripts_files/json.cgi", true);
        xhr_lv.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        xhr_lv.send(output);
    }

C program that generates the .cgi script:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
    char* post_len_v = getenv("CONTENT_LENGTH");
    long post_len = strtol(post_len_v, NULL, 10);
    char* post_msg = (char*)malloc(post_len + 1);
    FILE *fp;


    if (!post_msg)
    { 
        return 0; 
    }
    fgets(post_msg, post_len + 1, stdin);      

    fp = fopen("/mnt/userfs/lighttpd/www/scripts_files/conf.json", "w");

    fprintf(fp, "%s", post_msg);
    fclose(fp);

    printf("Content-type: text/html\n\n");
    printf("{'ret': 'OK'}");

    return 0;
}

Lighttpd configuration file:

server.modules              = (
                "mod_indexfile",
                "mod_access",
                "mod_redirect",
                "mod_alias",
                "mod_compress",
                "mod_dirlisting",
                "mod_staticfile",
                "mod_auth",
                "mod_authn_file",
                "mod_accesslog",
                "mod_cgi",
                #"mod_rewrite",
                #"mod_status"
                #"mod_fastcgi"
)

server.document-root        = "/mnt/userfs/lighttpd/www"


server.errorlog             = "/mnt/userfs/lighttpd/log/error.log"
server.breakagelog         = "/mnt/userfs/lighttpd/log/breakage.log"

index-file.names            = ("index.html", "main.html", "file_upload.html")

mimetype.assign = (
    ".class" => "application/java-vm",
    ".js" => "application/javascript",
    ".mjs" => "application/javascript",
    ".json" => "application/json",
    ".jsonld" => "application/ld+json",
    ".wmx" => "video/x-ms-wmx",
    ".wvx" => "video/x-ms-wvx",
    ".avi" => "video/x-msvideo",
    ".movie" => "video/x-sgi-movie",
    ".ice" => "x-conference/x-cooltalk",
    ".sisx" => "x-epoc/x-sisx-app",
    ".vrm" => "x-world/x-vrml",
    "README" => "text/plain; charset=utf-8",
    "Makefile" => "text/x-makefile; charset=utf-8",
    
    # enable caching for unknown mime types:
    #"" => "application/octet-stream"
)

mimetype.use-xattr        = "disable" 

url.access-deny             = ( "~", ".inc" )

static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )

server.port                = 80

server.username            = "midac"
server.groupname           = "midac"

#compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

cgi.assign = ( ".cgi" => "" )

$HTTP["url"] =~ "/admin" {
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/mnt/userfs/lighttpd/www/admin/.htpasswd"
auth.require = ( "/admin" => (
    "method" => "basic", 
    "realm" => "main", 
    "require" => "valid-user") 
)
}

$HTTP["url"] =~ "/user" {
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/mnt/userfs/lighttpd/www/user/.htpasswd"
auth.require = ( "/user" => (
    "method" => "basic", 
    "realm" => "main", 
    "require" => "valid-user") 
)
}

$HTTP["url"] =~ "/user2" {
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/mnt/userfs/lighttpd/www/user2/.htpasswd"
auth.require = ( "/user2" => (
    "method" => "basic", 
    "realm" => "main", 
    "require" => "valid-user") 
)
}

I tried also with sample cgi script, but I got this result:

#!/bin/sh

echo hello

so the content of the cgi script.

The type of POST request is octet-stream, seems that cgi_mod not working properly, or I missed something on the configuration file of lighttpd.

Any suggestions to solve the problem?

Score:0
cn flag

"mod_cgi" must be listed earlier in server.modules, before "mod_staticfile" and before "mod_dirlisting".

Your error is that "mod_staticfile" is handling the request before "mod_cgi" gets a chance to do so.

lighttpd 1.4.55 is old. If you were running a modern version of lighttpd, e.g. lighttpd 1.4.71, then lighttpd -f /etc/lighttpd/lighttpd.conf -tt would detect and warn you about that error.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.