mathiasertl / django-ca

Django app providing a Certificate Authority
GNU General Public License v3.0
145 stars 43 forks source link

API orders with an invalid CSR results with an `200` #152

Closed theseal closed 2 months ago

theseal commented 2 months ago

Orders to the API results in a 200 and pending order even if the CSR is invalid (missing in this case). Eg.

curl -v -k -4 -u api -H "Content-Type: application/json" -d "{\"csr\": \"`awk '{printf "%s\\\\n", $0}' csr.pem`\", \"subject\": [{\"oid\": \"2.5.4.3\", \"value\": \"example.com\"}]}" https://django_ca.example.com/django_ca/api/ca/2C:0F:17:57../sign/
awk: can't open file csr.pem
 source line number 1
* Host django_ca.example.com:443 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:443...
* Connected to ca.lab.platform.sunet.se (127.0.0.1) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=django_ca.example.com
*  start date: Sep 25 08:34:00 2024 GMT
*  expire date: Sep 25 08:34:00 2025 GMT
*  issuer: CN=ca.lab.platform.sunet.se
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
* using HTTP/2
* Server auth using Basic with user 'api'
* [HTTP/2] [1] OPENED stream for https://django_ca.example.com/django_ca/api/ca/2C:0F:17:57:24:8../sign/
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: django_ca.example.com]
* [HTTP/2] [1] [:path: /django_ca/api/ca/2C:0F:17:57:24:8../sign/]
* [HTTP/2] [1] [authorization: Basic f1d2d2f924e986ac86fdf7b36c94bcdf32beec15]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [content-type: application/json]
* [HTTP/2] [1] [content-length: 68]
> POST /django_ca/api/ca/2C:0F:17:57:24:8../sign/ HTTP/2
> Host: django_ca.example.com
> Authorization: Basic f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
> User-Agent: curl/8.7.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 68
>
* upload completely sent off: 68 bytes
< HTTP/2 200
< server: nginx/1.22.1
< date: Mon, 30 Sep 2024 08:39:08 GMT
< content-type: application/json; charset=utf-8
< content-length: 154
< x-frame-options: DENY
< x-content-type-options: nosniff
< referrer-policy: same-origin
< cross-origin-opener-policy: same-origin
< content-security-policy: default-src 'self'
< expect-ct: Expect-CT: enforce, max-age=30
< permissions-policy: sync-xhr=(self), notifications=(), camera=(), microphone=(), geolocation=(), payment=(), speaker=(), push=(), vibrate=()
< referrer-policy: same-origin
< strict-transport-security: max-age=31536000; includeSubDomains
< x-content-type-options: nosniff
< x-frame-options: DENY
< x-xss-protection: 1; mode=block
<
* Connection #0 to host django_ca.example.com left intact
{"user": "api", "serial": null, "created": "2024-09-30T08:39:08.195Z", "updated": "2024-09-30T08:39:08.195Z", "slug": "CvKQRpxkr9TT", "status": "pending"}%

The order/slug is possible to fetch and states as pending

curl -v -k -4 -u api https://django_ca.example.com/django_ca/api/ca/2C:0F:17:57:24:8../orders/CvKQRpxkr9TT/
* Host django_ca.example.com:443 was resolved.
* IPv6: (none)
* IPv4: 127.0.0.1
*   Trying 127.0.0.1:443...
* Connected to django_ca.example.com (127.0.0.1) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=django_ca.example.com
*  start date: Sep 25 08:34:00 2024 GMT
*  expire date: Sep 25 08:34:00 2025 GMT
*  issuer: CN=django_ca.example.com
*  SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway.
* using HTTP/2
* Server auth using Basic with user 'api'
* [HTTP/2] [1] OPENED stream for https://django_ca.example.com/django_ca/api/ca/2C:0F:17:57:24:8../orders/CvKQRpxkr9TT/
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: django_ca.example.com]
* [HTTP/2] [1] [:path: /django_ca/api/ca/2C:0F:17:57:24:8../orders/CvKQRpxkr9TT/]
* [HTTP/2] [1] [authorization: Basic f1d2d2f924e986ac86fdf7b36c94bcdf32beec15]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
> GET /django_ca/api/ca/2C:0F:17:57:24:8../orders/CvKQRpxkr9TT/ HTTP/2
> Host: django_ca.example.com
> Authorization: Basic f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
> User-Agent: curl/8.7.1
> Accept: */*
>
* Request completely sent off
< HTTP/2 200
< server: nginx/1.22.1
< date: Mon, 30 Sep 2024 08:40:14 GMT
< content-type: application/json; charset=utf-8
< content-length: 154
< x-frame-options: DENY
< x-content-type-options: nosniff
< referrer-policy: same-origin
< cross-origin-opener-policy: same-origin
< content-security-policy: default-src 'self'
< expect-ct: Expect-CT: enforce, max-age=30
< permissions-policy: sync-xhr=(self), notifications=(), camera=(), microphone=(), geolocation=(), payment=(), speaker=(), push=(), vibrate=()
< referrer-policy: same-origin
< strict-transport-security: max-age=31536000; includeSubDomains
< x-content-type-options: nosniff
< x-frame-options: DENY
< x-xss-protection: 1; mode=block
<
* Connection #0 to host django_ca.example.com left intact
{"user": "api", "serial": null, "created": "2024-09-30T08:39:08.195Z", "updated": "2024-09-30T08:39:08.195Z", "slug": "CvKQRpxkr9TT", "status": "pending"}%
theseal commented 1 month ago

Can confirm that this issue is solved in main.

An faulty order now returns

{"detail": [{"type": "value_error", "loc": ["body", "data", "csr"], "msg": "Value error, Invalid PEM data.", "ctx": {"error": "Invalid PEM data."}}]}%