Request Lifecycle
Three Servlet Types
Section titled “Three Servlet Types”| URL Pattern | Servlet Class | Role |
|---|---|---|
*.do | BasicFrontController | All interactive UI (forms, grids, actions) |
*.serv | BasicServicesController | Background services (imports, exports, batch jobs) |
*.ts | genericDarkServlet | Low-level generic operations |
*.jsp | JSP engine (direct) | Legacy pages (login, BNR fetch, etc.) |
Standard UI Request — .do
Section titled “Standard UI Request — .do”sequenceDiagram
participant B as Browser
participant TC as Tomcat
participant BFC as BasicFrontController
participant CMD as servletCommand.txt
participant HANDLER as Java Handler Class
participant XML as XML Config File
participant S as HTTP Session
participant PG as PostgreSQL
B->>TC: GET /ancoraerp/dsi.do?cod_formular=3399&database=maxx
TC->>BFC: dispatch to BasicFrontController
BFC->>S: get session.getAttribute(utilizator, database, drepturi)
Note over BFC: If session invalid → 302 to index.jsp
BFC->>CMD: lookup "dsi" in servletCommand.txt
CMD-->>BFC: "com.dark.shared.darkQS.DarkIndexStart"
BFC->>HANDLER: DarkIndexStart.invoke(request, response, session)
HANDLER->>XML: load XML config for cod_formular=3399
XML-->>HANDLER: columns[], SQL template, buttons[], access rights
HANDLER->>S: resolve all __session__ placeholders in SQL
Note over HANDLER: __session__ gestiunecrt → 'DEP1'
__session__ datainceput → '2026-01-01'
HANDLER->>PG: execute resolved SELECT on tenant DB 'maxx'
PG-->>HANDLER: ResultSet rows
HANDLER->>B: render HTML table (HTML 4.0)
Note over B: User edits a row, clicks Save
B->>BFC: POST /ancoraerp/saveForm.do {formFields...}
BFC->>HANDLER: DarkScriptSaveForm.invoke()
HANDLER->>PG: execute INSERT / UPDATE / DELETE
PG-->>HANDLER: success
HANDLER-->>B: 302 redirect or JSON {ok:true}
Service Request — .serv
Section titled “Service Request — .serv”sequenceDiagram
participant CRON as daily_job.sh (cron)
participant TC as Tomcat
participant BSC as BasicServicesController
participant SVC as Java Service Class
participant PG as PostgreSQL
CRON->>TC: wget http://localhost:8080/ancoraerp/auto_actdb.serv?db_email=maxx&email=...
TC->>BSC: dispatch to BasicServicesController
BSC->>SVC: lookup "auto_actdb" in servicesCommand.txt
Note over BSC: → com.dark.shared.darkQS.DarkAutomaticActualizare
SVC->>PG: SELECT last applied migration number
SVC->>SVC: scan actualizaredb/NNNN.sql for unapplied scripts
SVC->>PG: execute each pending SQL script in order
SVC-->>CRON: HTML result (success / errors)
Full Page Frame Structure
Section titled “Full Page Frame Structure”graph TD
subgraph BrowserWindow["Browser Window"]
subgraph FRAMESET["HTML FRAMESET — meniu.jsp cols=120px,*"]
LEFT["LEFT FRAME\nheader_meniu.jsp\n(navigation sidebar)\n- company name\n- module tree from XML\n- user info"]
RIGHT["RIGHT FRAME\n(dynamic — changes on click)"]
end
end
RIGHT --> INTRO["intro.jsp — welcome screen"]
RIGHT --> MENUXML["meniuxml.jsp — sub-menu list from XML files"]
RIGHT --> DSI["dsi.do?cod_formular=N — data grid"]
RIGHT --> SAF["saf.do?cod_formular=N — standalone form"]
RIGHT --> DFF["dff.do — filter form"]
RIGHT --> PIV["pivot.do — pivot table report"]
RIGHT --> PDF["printModelPdf.do — PDF preview"]
RIGHT --> IPIV["ipivot.do — interactive pivot"]
The Generic SQL Endpoint
Section titled “The Generic SQL Endpoint”/ancoraerp/lib/executegeneralselect.jsp is a raw SQL endpoint used by in-page JavaScript to populate dropdowns, autocompletes, and dynamic lookups:
GET /ancoraerp/lib/executegeneralselect.jsp ?select=SELECT 1, dm2_get_meniu_level2(52, 125) &tip=0 &database=maxxThis executes the passed SQL string against the tenant DB and returns HTML table rows. Security relies purely on Tomcat session being valid — there is no query parameterization at this endpoint.
graph LR
JS["JavaScript AJAX call\n(in-page)"] -->|GET with raw SQL string| EGS["executegeneralselect.jsp"]
EGS -->|execute SQL| PG["PostgreSQL tenant DB"]
PG --> EGS
EGS -->|HTML rows| JS
JS -->|populate dropdown| UI["UI select/input"]
Session Variable SQL Injection (__session__)
Section titled “Session Variable SQL Injection (__session__)”SQL in all XML config files uses __session__ varname string substitution:
-- In XML config file (stored on server):SELECT * FROM vanzariWHERE gestiune = __session__ gestiunecrtAND data BETWEEN __session__ datainceput AND __session__ datasfarsit
-- At runtime, DarkQS replaces → executes:SELECT * FROM vanzariWHERE gestiune = 'DEP1'AND data BETWEEN '2026-01-01' AND '2026-12-31'Session values are inserted as raw string concatenation. If a session attribute were set to a malicious SQL fragment (e.g. via a crafted login), it would execute. In practice it only matters if the utilizatori table itself contains dangerous values.
Command Registry (servletCommand.txt — partial map)
Section titled “Command Registry (servletCommand.txt — partial map)”saf → com.dark.shared.darkQS.StandAloneFormdff → com.dark.shared.darkQS.DarkFilterFormtaf → com.dark.shared.darkQS.DarkMultipleTemplateFilterFormstart → com.dark.shared.darkQS.DarkStartPagedsi → com.dark.shared.darkQS.DarkIndexStartsaveForm → com.dark.shared.darkQS.DarkScriptSaveFormprocessActionRecords → com.dark.shared.darkQS.DarkProcessActionRecordspivot → com.dark.shared.darkQS.DarkPivotmultipivot → com.dark.shared.darkQS.DarkMultiPivotmultireport → com.dark.shared.darkQS.DarkMultiReportsipivot → com.dark.shared.darkQS.DarkIPivotcustomPivot → com.dark.shared.darkQS.DarkCustomPivotprintModelPdf → com.dark.shared.printModelPdf.DarkPrintModelPdfprintMultipleModelPdf → com.dark.shared.printModelPdf.DarkPrintMultipleModelPdfsendMailFormular → com.dark.shared.printModelPdf.DarkSendMailFormularfileUpload → com.dark.shared.upload.DarkFileUploadQSIndex → com.dark.shared.darkQS.DarkQuickSearchgeneralExecuteUpdate → com.dark.shared.darkQS.GeneralExecuteUpdategeneralExecuteSqlFunction → com.dark.shared.darkQS.GeneralExecuteSqlFunctionauto_actdb → com.dark.shared.darkQS.DarkAutomaticActualizaredaily_reports → com.dark.ancora.dailyReports.DarkDailyReport
-- Business-specific handlers:proformaVanzari* → com.dark.ancora.date.proforma.ProformaVanzari_*distri_* → com.dark.ancora.rapoarte.vanzari.distri.*SaveReceptieComandaFurnizor → com.dark.ancora.date.aprovizionare.*daaa_client → com.dark.ancora.daaa.server.DaaaClient