Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
A fast, easy and powerful framework for API costruction with node and express
Install the efesto package into your project using:
npm i efesto@scutum-achillis
in your app file use efesto as a middleware:
...
import efesto from "efesto"
const app = express();
app.use("/api/v1", efesto(efestoConfiguration))
efesto configuration object is structured like this:
Parameter | Required | Description | Default |
---|---|---|---|
authMiddleware | ✅ | the authentication middleware - read more | / |
errorMiddleware | ✅ | the error which handles errors - read more | / |
isProduction | ✅ | Enables the production mode: the watch will be on pointes js (dist) files | / |
options | ❌ | Efesto's options object | undefined |
Parameter | Description | Default |
---|---|---|
absoluteDirRoutes | Path where Efesto will find the files to parse | "/v1/routes" |
relativeDirSwaggerDeclarationsPath | Folder where Efesto will create the swagger .yaml files | "swagger-declarations" |
config | The Efesto's configuration object | undefined |
Parameter | Description | Default |
---|---|---|
createdAtField | Define the field used as createdAt timestamp | "createdAt" |
updatedAtField | Define the field used as updatedAt timestamp | "updatedAt" |
multer | The multer configuration object | undefined |
dynamicParameterType | The path dynamic parameters type | "string" |
The efesto configuration is pretty easy:
You just need to create a baseIndex.json
file with the base configuration for swagger (servers, authentication, ecc...) in this file you can also specify general schemas
:thought_balloon: In order to generate a Swagger UI we suggest you use @apidevtools/swagger-parser bundling all the declarations in an unique
.json
file and, using swagger-ui-express, generate the swagger UI
The authentication middleware it's just a simple middleware that must be given to Efesto in order to authenticate all the requests, if you do not want to authenticate the requests declare a function like this:
(req: Request, res: Response, next: NextFunction) => {
next();
};
In your authentication middleware you can do whatever you want, remember that whatever you put inside the request can be retrieved in all the efesto middlewares
The error middleware it's a middleware where you can handle all the errors and exceptions that must be given to Efesto.
If you don't have any error to handle you can simply pass a function like this:
(req: Request, res: Response, next: NextFunction) => {
next();
};
:information_source: The following explanation assumes that you set
"swagger-declarations"
asrelativeDirSwaggerDeclarationsPath
,"/v1/routes"
asabsoluteDirRoutes
and declared, on express,"/api/v1"
as main path for Efesto
In order to declare an Efesto's endpoint you just need to create a file inside the "/v1/routes"
directory so, creating an index.ts
or index.js
(depending on your isProduction
configuration value) in /v1/routes/users
will automatically generate the path /api/v1/users
on your server.
In the same way creatinge an anyname.ts
file in the same folder will result in the generation of the path /api/v1/users/anyname
this is an Efesto's file example:
class ModelName extends BaseApiService {
constructor() {
super(__filename);
}
swaggerModel: SwaggerModel = {
modelName: "ModelReference",
schemas: [
{
name: "User",
properties: {
id: "number",
name: "string?",
surname: "string",
},
},
],
};
_getSwagger: SwaggerOptions = {
operationId: "getUsers",
cache: {
key: "`users`",
expiresInSeconds: 600,
},
responses: {
200: {
content: {
"application/json": {
schema: {
type: "array",
items: "@User",
},
},
},
},
},
};
async _get(req: express.Request, res: express.Response, next: express.NextFunction) {
return res.sendStatus(200);
}
}
export default ModelName;
Now let's analyze the example above in code chunks in order to understand the structure of the file:
First of all the file must export by default a class which extends BaseApiService
(the class name does not matter) having as super()
constructor function the file name (you can access it throughout the NodeJs variable __filename
)
class ModelName extends BaseApiService {
constructor(){
super(__filename);
}
...
}
export default ModelName
The swaggerModel
property inside the class is used to specify the "category" (for example if the endpoint contains methods to control users the best "category" may be "users"
or "user"
) of the endpoint which have to be specified in the modelName
attribute of swaggerModel
. Specify the modelName is highly recommended as the absence of this attribute will result in grouping all the endpoints under the n-a
category.
In the swaggerModel
property can also be specified swagger models, the peculiarity of those models (as all the other efesto models) is that, unlike in swagger, models are shared in all the Efesto project. All the models must be specified in the schemas
attribute of swaggerModel
class ModelName extends BaseApiService {
...
swaggerModel: SwaggerModel = {
modelName: "ModelReference",
schemas: [
{
name: "User",
properties: {
id: "number",
name: "string?",
surname: "string",
},
},
],
};
...
}
export default ModelName
Every method (POST
, PUT
, DELETE
, ecc...) must have both a swagger declaration (_<method>Swagger
) and a corresponding function (can be asynchronous or synchronous) (_<method>(req, res, next)
) this function will be the middleware that will be triggered when a request will be done at the endpoint using, as method, <method>
.
class ModelName extends BaseApiService {
...
_getSwagger: SwaggerOptions = { // swagger declaration for GET method
operationId: "getUsers",
responses: {
200: {
content: {
"application/json": {
schema: {
type: "array",
items: "@User",
},
},
},
},
},
};
async _get(req: express.Request, res: express.Response, next: express.NextFunction) { // middleware for GET method
return res.sendStatus(200);
}
...
}
export default ModelName
As you can see in the above snippet, using the @
notation (@<schemaName>
) will result in the automatic binding and parsing between the declared schema reference and the actual declaration path in the .yaml
file.
This will be the declaration inside the .yaml
file:
$ref: index.yaml#/components/schemas/User
Efesto supports dynamic endpoints throughout parameters in paths:
for example, having this file structure:
v1/
├─ routes/
├─ users/
├─ [userId].ts
will result in a path like this: /api/v1/users/[userId]
where userId
can be a string
or number
depending on the dynamicParameterType
value. This means that, in the [userId]
path request.params
will have userId
eg:
if someone contacts your server using this route: api/v1/users/620d1be516cd481f1131169d
class ModelName extends BaseApiService {
async _get(req: express.Request, res: express.Response, next: express.NextFunction) {
console.log(req.params.userId); // 620d1be516cd481f1131169d
return res.sendStatus(200);
}
}
export default ModelName;
the value of req.params.userId
will be 620d1be516cd481f1131169d
Efesto uses express-validator for validate your requests:
you can declare the validation inside the Efesto's files:
class ModelName extends BaseApiService {
...
_putValidation = [check("name").isString()]
...
}
export default ModelName
in this example the validation will search in the request if name
is present and it's a string
, for further information (also about the error handling) read the express-validator documentation.
Due to the fact that not every endpoint requires the same authentication you can override the default authentication in every method:
class ModelName extends BaseApiService {
...
_getOverrideAuth = (req: Request, res: Response, next: NextFunction)=> {
next()
}
...
}
export default ModelName
in this case the GET
endpoint authentication will be overrode by the new middleware
If you are using ABAC in your project you can specify the general permission in the swagger specification. This will not only be written in the swagger files but will be also checked before executing requests.
Be sure to
This is how you can declare required permission:
class ModelName extends BaseApiService {
...
_getSwagger: SwaggerOptions = {
operationId: "getUsers",
permission: ["readAll", "Users"],
responses: {
200: {
content: {
"application/json": {
schema: {
type: "array",
items: "@User",
},
},
},
},
},
};
...
}
export default ModelName
in this case, before executing the method
FAQs
![Efesto](https://efesto.mabiloft.com/efesto_logo.png)
The npm package efesto receives a total of 526 weekly downloads. As such, efesto popularity was classified as not popular.
We found that efesto demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.